mirror of
https://github.com/Telecominfraproject/wlan-cloud-ucentralgw.git
synced 2025-10-29 18:02:27 +00:00
Adding SQLite
This commit is contained in:
52
src/DeviceStatusServer.cpp
Normal file
52
src/DeviceStatusServer.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-03-01.
|
||||
//
|
||||
|
||||
#include "DeviceStatusServer.h"
|
||||
|
||||
DeviceStatusServer * DeviceStatusServer::instance_ = nullptr;
|
||||
|
||||
DeviceStatusServer::DeviceStatusServer() noexcept:
|
||||
SubSystemServer("DeviceStatus","DevStatus","devicestatus")
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int DeviceStatusServer::start() {
|
||||
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
|
||||
SubSystemServer::logger().information("Starting ");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DeviceStatusServer::stop() {
|
||||
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
|
||||
SubSystemServer::logger().information("Stopping ");
|
||||
|
||||
}
|
||||
|
||||
void DeviceStatusServer::Connect(const std::string &SerialNumber, const std::string & address)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
|
||||
}
|
||||
|
||||
void DeviceStatusServer::Disconnect(const std::string &SerialNumber) {
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
|
||||
}
|
||||
|
||||
const std::string DeviceStatusServer::LastStats(const std::string &SerialNumber) {
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
void DeviceStatusServer::SetStats(const std::string &SerialNumber,const std::string &stats) {
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
|
||||
}
|
||||
39
src/DeviceStatusServer.h
Normal file
39
src/DeviceStatusServer.h
Normal file
@@ -0,0 +1,39 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-03-01.
|
||||
//
|
||||
|
||||
#ifndef UCENTRAL_DEVICESTATUSSERVER_H
|
||||
#define UCENTRAL_DEVICESTATUSSERVER_H
|
||||
|
||||
#include "SubSystemServer.h"
|
||||
|
||||
class DeviceStatusServer : public SubSystemServer{
|
||||
public:
|
||||
DeviceStatusServer() noexcept;
|
||||
|
||||
int start();
|
||||
void stop();
|
||||
|
||||
static DeviceStatusServer *instance() {
|
||||
if(instance_== nullptr) {
|
||||
instance_ = new DeviceStatusServer;
|
||||
}
|
||||
return instance_;
|
||||
}
|
||||
|
||||
std::string process_message(const char *msg);
|
||||
|
||||
void Connect(const std::string &SerialNumber, const std::string & address);
|
||||
void Disconnect(const std::string &SerialNumber);
|
||||
const std::string LastStats(const std::string &SerialNumber);
|
||||
void SetStats(const std::string &SerialNumber,const std::string &stats);
|
||||
|
||||
Logger & logger() { return SubSystemServer::logger(); };
|
||||
|
||||
private:
|
||||
static DeviceStatusServer * instance_;
|
||||
std::mutex mutex_;
|
||||
};
|
||||
|
||||
|
||||
#endif //UCENTRAL_DEVICESTATUSSERVER_H
|
||||
44
src/PropertiesFileServerList.cpp
Normal file
44
src/PropertiesFileServerList.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-02-12.
|
||||
//
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include "uCentral.h"
|
||||
#include "PropertiesFileServerList.h"
|
||||
|
||||
void PropertiesFileServerList::initialize() {
|
||||
|
||||
auto i=0;
|
||||
bool good=true;
|
||||
|
||||
while(good) {
|
||||
std::string root{prefix_ + ".host." + std::to_string(i) + "."};
|
||||
|
||||
std::string address{root + "address"};
|
||||
if(uCentral::instance().config().getString(address,"") == "") {
|
||||
good = false;
|
||||
}
|
||||
else {
|
||||
std::string port{root + "port"};
|
||||
std::string key{root + "key"};
|
||||
std::string key_password{root + "key.password"};
|
||||
std::string cert{root + "cert"};
|
||||
|
||||
PropertiesFileServerEntry entry( uCentral::instance().config().getString(address,""),
|
||||
uCentral::instance().config().getInt(port,0),
|
||||
uCentral::instance().config().getString(key,""),
|
||||
uCentral::instance().config().getString(cert,""),
|
||||
uCentral::instance().config().getString(key_password,""));
|
||||
list_.push_back(entry);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
// uCentral::instance().config().
|
||||
}
|
||||
|
||||
const PropertiesFileServerEntry & PropertiesFileServerList::operator[](int index)
|
||||
{
|
||||
return list_[index];
|
||||
}
|
||||
|
||||
58
src/PropertiesFileServerList.h
Normal file
58
src/PropertiesFileServerList.h
Normal file
@@ -0,0 +1,58 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-02-12.
|
||||
//
|
||||
|
||||
#ifndef UCENTRAL_PROPERTIESFILESERVERLIST_H
|
||||
#define UCENTRAL_PROPERTIESFILESERVERLIST_H
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <iterator>
|
||||
|
||||
class PropertiesFileServerEntry {
|
||||
public:
|
||||
PropertiesFileServerEntry(const std::string &address,
|
||||
const uint32_t port,
|
||||
const std::string &key_file,
|
||||
const std::string &cert_file,
|
||||
const std::string &key_file_password = "" ) :
|
||||
address_(address),
|
||||
port_(port),
|
||||
key_file_(key_file),
|
||||
cert_file_(cert_file),
|
||||
key_file_password_(key_file_password) {};
|
||||
|
||||
const std::string & address() const { return address_; };
|
||||
const uint32_t port() const { return port_; };
|
||||
const std::string & key_file() const { return key_file_; };
|
||||
const std::string & cert_file() const { return cert_file_; };
|
||||
const std::string & key_file_password() const { return key_file_password_; };
|
||||
|
||||
private:
|
||||
std::string address_;
|
||||
std::string cert_file_;
|
||||
std::string key_file_;
|
||||
std::string key_file_password_;
|
||||
uint32_t port_;
|
||||
};
|
||||
|
||||
class PropertiesFileServerList {
|
||||
public:
|
||||
PropertiesFileServerList(const std::string &prefix):prefix_(prefix) {};
|
||||
|
||||
void initialize();
|
||||
|
||||
const PropertiesFileServerEntry & operator[](int);
|
||||
inline std::vector<PropertiesFileServerEntry>::iterator begin() noexcept { return list_.begin(); };
|
||||
inline std::vector<PropertiesFileServerEntry>::iterator end() noexcept { return list_.end(); };
|
||||
inline std::vector<PropertiesFileServerEntry>::const_iterator cbegin() const noexcept { return list_.cbegin(); };
|
||||
inline std::vector<PropertiesFileServerEntry>::const_iterator cend() const noexcept { return list_.cend(); };
|
||||
const uint32_t size() const { return list_.size(); };
|
||||
|
||||
private:
|
||||
std::string prefix_;
|
||||
std::vector<PropertiesFileServerEntry> list_;
|
||||
};
|
||||
|
||||
#endif //UCENTRAL_PROPERTIESFILESERVERLIST_H
|
||||
33
src/SubSystemServer.cpp
Normal file
33
src/SubSystemServer.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-03-01.
|
||||
//
|
||||
|
||||
#include "SubSystemServer.h"
|
||||
|
||||
SubSystemServer::SubSystemServer( const std::string &Name,
|
||||
const std::string & LoggingPrefix,
|
||||
const std::string & SubSystemConfigPrefix )
|
||||
: name_(Name),
|
||||
logger_(Logger::get(LoggingPrefix)),
|
||||
servers_(SubSystemConfigPrefix)
|
||||
{}
|
||||
|
||||
void SubSystemServer::initialize(Application & self)
|
||||
{
|
||||
logger_.information("Initializing...");
|
||||
servers_.initialize();
|
||||
}
|
||||
|
||||
void SubSystemServer::uninitialize()
|
||||
{
|
||||
// add your own uninitialization code here
|
||||
}
|
||||
|
||||
void SubSystemServer::reinitialize(Application & self)
|
||||
{
|
||||
// add your own reinitialization code here
|
||||
}
|
||||
|
||||
void SubSystemServer::defineOptions(OptionSet& options)
|
||||
{
|
||||
}
|
||||
50
src/SubSystemServer.h
Normal file
50
src/SubSystemServer.h
Normal file
@@ -0,0 +1,50 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-03-01.
|
||||
//
|
||||
|
||||
#ifndef UCENTRAL_SUBSYSTEMSERVER_H
|
||||
#define UCENTRAL_SUBSYSTEMSERVER_H
|
||||
|
||||
#include "Poco/Util/Application.h"
|
||||
#include "Poco/Util/ServerApplication.h"
|
||||
#include "Poco/Util/Option.h"
|
||||
#include "Poco/Util/OptionSet.h"
|
||||
#include "Poco/Util/HelpFormatter.h"
|
||||
#include "Poco/Util/AbstractConfiguration.h"
|
||||
#include "Poco/Util/IntValidator.h"
|
||||
#include "Poco/AutoPtr.h"
|
||||
#include "Poco/Logger.h"
|
||||
|
||||
using Poco::Util::Application;
|
||||
using Poco::Util::ServerApplication;
|
||||
using Poco::Util::Option;
|
||||
using Poco::Util::OptionSet;
|
||||
using Poco::Util::HelpFormatter;
|
||||
using Poco::Util::AbstractConfiguration;
|
||||
using Poco::Util::OptionCallback;
|
||||
using Poco::Util::IntValidator;
|
||||
using Poco::AutoPtr;
|
||||
using Poco::Logger;
|
||||
|
||||
#include "PropertiesFileServerList.h"
|
||||
|
||||
class SubSystemServer : public Poco::Util::Application::Subsystem {
|
||||
public:
|
||||
SubSystemServer(const std::string &name, const std::string & LoggingName, const std::string & SubSystemPrefix );
|
||||
virtual int start() = 0;
|
||||
virtual void stop() = 0;
|
||||
void initialize(Application &self);
|
||||
void uninitialize();
|
||||
void reinitialize(Application & self);
|
||||
void defineOptions(OptionSet &options);
|
||||
const char *name() const { return name_.c_str(); };
|
||||
const PropertiesFileServerEntry & host(int index) { return servers_[index]; };
|
||||
Logger & logger() { return logger_;};
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
Logger & logger_;
|
||||
PropertiesFileServerList servers_;
|
||||
};
|
||||
|
||||
#endif //UCENTRAL_SUBSYSTEMSERVER_H
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "Api.h"
|
||||
#include "../app.h"
|
||||
#include "../uCentral.h"
|
||||
|
||||
#include "Poco//Net/DNS.h"
|
||||
|
||||
@@ -14,12 +14,12 @@ namespace TIP::API {
|
||||
TIP::API::API *TIP::API::API::instance_ = 0;
|
||||
|
||||
void API::Init() {
|
||||
username_ = App::instance().config().getString("tip.api.login.username");
|
||||
password_ = App::instance().config().getString("tip.api.login.password");
|
||||
api_host_ = App::instance().config().getString("tip.api.host");
|
||||
api_port_ = App::instance().config().getInt("tip.api.port");
|
||||
ssc_host_ = App::instance().config().getString("tip.ssc.host");
|
||||
ssc_port_ = App::instance().config().getInt("tip.ssc.port");
|
||||
username_ = uCentral::instance().config().getString("tip.api.login.username");
|
||||
password_ = uCentral::instance().config().getString("tip.api.login.password");
|
||||
api_host_ = uCentral::instance().config().getString("tip.api.host");
|
||||
api_port_ = uCentral::instance().config().getInt("tip.api.port");
|
||||
ssc_host_ = uCentral::instance().config().getString("tip.gateway.host.0.address");
|
||||
ssc_port_ = uCentral::instance().config().getInt("tip.gateway.host.0.port");
|
||||
}
|
||||
|
||||
void API::Logout() {
|
||||
@@ -58,8 +58,16 @@ namespace TIP::API {
|
||||
TIP::API::API::instance()->Logout();
|
||||
}
|
||||
|
||||
const std::string & SSC_Host() { return TIP::API::API::instance()->ssc_host(); }
|
||||
uint64_t SSC_Port() { return TIP::API::API::instance()->ssc_port(); }
|
||||
const std::string & AccessToken() {
|
||||
return TIP::API::API::instance()->access_token();
|
||||
};
|
||||
|
||||
const std::string & SSC_Host() {
|
||||
return TIP::API::API::instance()->ssc_host();
|
||||
}
|
||||
|
||||
uint64_t SSC_Port() {
|
||||
return TIP::API::API::instance()->ssc_port();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -71,13 +71,27 @@ namespace TIP::API {
|
||||
|
||||
bool Login();
|
||||
void Logout();
|
||||
void Init();
|
||||
const std::string & ssc_host() const { return ssc_host_; }
|
||||
uint64_t ssc_port() const { return ssc_port_; }
|
||||
|
||||
const std::string &access_token() const { return token_.access_token(); };
|
||||
[[nodiscard]] const std::string & ssc_host() const { return ssc_host_; }
|
||||
[[nodiscard]] uint64_t ssc_port() const { return ssc_port_; }
|
||||
[[nodiscard]] const std::string &access_token() const { return token_.access_token(); };
|
||||
|
||||
[[nodiscard]] const std::string &refresh_token() const { return token_.refresh_token(); };
|
||||
[[nodiscard]] const std::string &id_token() const { return token_.id_token(); };
|
||||
[[nodiscard]] const std::string &token_type() const { return token_.token_type(); };
|
||||
[[nodiscard]] unsigned int expires_in() const { return token_.expires_in(); };
|
||||
[[nodiscard]] unsigned int idle_timeout() const { return token_.idle_timeout(); };
|
||||
|
||||
[[nodiscard]] bool read_access() const { return token_.read_access(); };
|
||||
[[nodiscard]] bool readWrite_access() const { return token_.readWrite_access(); };
|
||||
[[nodiscard]] bool readWriteCreate_access() const { return token_.readWriteCreate_access(); };
|
||||
[[nodiscard]] bool delete_access() const { return token_.delete_access(); };
|
||||
[[nodiscard]] bool portalLogin_access() const { return token_.portalLogin_access(); };
|
||||
|
||||
|
||||
private:
|
||||
void Init();
|
||||
|
||||
static API *instance_;
|
||||
std::string api_host_; // TIP portal server name: default to wlan-ui.wlan.local
|
||||
unsigned int api_port_;
|
||||
@@ -91,6 +105,7 @@ namespace TIP::API {
|
||||
|
||||
bool Login();
|
||||
void Logout();
|
||||
const std::string & AccessToken();
|
||||
const std::string & SSC_Host();
|
||||
uint64_t SSC_Port();
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// Created by stephane bourque on 2021-02-17.
|
||||
//
|
||||
|
||||
#include "EquipmentGatewayRecord.h"
|
||||
#include "Routing.h"
|
||||
#include "Poco/JSON/Parser.h"
|
||||
|
||||
namespace TIP::Routing {
|
||||
@@ -39,9 +39,9 @@ namespace TIP::Routing {
|
||||
|
||||
bool CreateRoutingGateway(const TIP::Routing::EquipmentGatewayRecord & R) {
|
||||
Poco::Net::HTTPSClientSession session(TIP::API::SSC_Host(),TIP::API::SSC_Port());
|
||||
Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST,
|
||||
Poco::Net::HTTPRequest request( Poco::Net::HTTPRequest::HTTP_POST,
|
||||
std::string("/api/routing/gateway"),
|
||||
Poco::Net::HTTPMessage::HTTP_1_1);
|
||||
Poco::Net::HTTPMessage::HTTP_1_1);
|
||||
|
||||
Poco::JSON::Object obj;
|
||||
R.to_JSON(obj);
|
||||
@@ -66,9 +66,10 @@ namespace TIP::Routing {
|
||||
TIP::Routing::EquipmentGatewayRecord R;
|
||||
|
||||
Poco::Net::HTTPSClientSession session(TIP::API::SSC_Host(),TIP::API::SSC_Port());
|
||||
Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_DELETE,
|
||||
std::string("/api/routing/gateway?gatewayId=") + std::to_string(Id),
|
||||
Poco::Net::HTTPMessage::HTTP_1_1);
|
||||
Poco::Net::HTTPRequest request( Poco::Net::HTTPRequest::HTTP_DELETE,
|
||||
std::string("/api/routing/gateway?gatewayId=")
|
||||
+ std::to_string(Id),
|
||||
Poco::Net::HTTPMessage::HTTP_1_1);
|
||||
request.setContentType("application/json");
|
||||
session.sendRequest(request);
|
||||
|
||||
@@ -84,9 +85,10 @@ namespace TIP::Routing {
|
||||
EquipmentGatewayRecord R;
|
||||
|
||||
Poco::Net::HTTPSClientSession session(TIP::API::SSC_Host(),TIP::API::SSC_Port());
|
||||
Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET,
|
||||
std::string("/api/routing/gateway?gatewayId=") + std::to_string(Id),
|
||||
Poco::Net::HTTPMessage::HTTP_1_1);
|
||||
Poco::Net::HTTPRequest request( Poco::Net::HTTPRequest::HTTP_GET,
|
||||
std::string("/api/routing/gateway?gatewayId=")
|
||||
+ std::to_string(Id),
|
||||
Poco::Net::HTTPMessage::HTTP_1_1);
|
||||
request.setContentType("application/json");
|
||||
session.sendRequest(request);
|
||||
|
||||
@@ -102,9 +104,10 @@ namespace TIP::Routing {
|
||||
std::vector<TIP::Routing::EquipmentGatewayRecord> R;
|
||||
|
||||
Poco::Net::HTTPSClientSession session(TIP::API::SSC_Host(),TIP::API::SSC_Port());
|
||||
Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET,
|
||||
std::string("/api/routing/gateway/byType?gatewayType=") + Type,
|
||||
Poco::Net::HTTPMessage::HTTP_1_1);
|
||||
Poco::Net::HTTPRequest request( Poco::Net::HTTPRequest::HTTP_GET,
|
||||
std::string("/api/routing/gateway/byType?gatewayType=")
|
||||
+ Type,
|
||||
Poco::Net::HTTPMessage::HTTP_1_1);
|
||||
request.setContentType("application/json");
|
||||
session.sendRequest(request);
|
||||
|
||||
@@ -120,9 +123,10 @@ namespace TIP::Routing {
|
||||
std::vector<TIP::Routing::EquipmentGatewayRecord> R;
|
||||
|
||||
Poco::Net::HTTPSClientSession session(TIP::API::SSC_Host(),TIP::API::SSC_Port());
|
||||
Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET,
|
||||
std::string("/api/routing/gateway/byHostname?hostname=") + host,
|
||||
Poco::Net::HTTPMessage::HTTP_1_1);
|
||||
Poco::Net::HTTPRequest request( Poco::Net::HTTPRequest::HTTP_GET,
|
||||
std::string("/api/routing/gateway/byHostname?hostname=")
|
||||
+ host,
|
||||
Poco::Net::HTTPMessage::HTTP_1_1);
|
||||
request.setContentType("application/json");
|
||||
session.sendRequest(request);
|
||||
|
||||
@@ -134,5 +138,52 @@ namespace TIP::Routing {
|
||||
return R;
|
||||
}
|
||||
|
||||
bool EquipmentRoutingRecord::to_JSON(Poco::JSON::Object &obj) const
|
||||
{
|
||||
obj.set("id", id_);
|
||||
obj.set("equipmentId", equipmentId_);
|
||||
obj.set("customerId", customerId_);
|
||||
obj.set("gatewayId", gatewayId_);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EquipmentRoutingRecord::from_stream(std::istream &response) {
|
||||
Poco::JSON::Parser parser;
|
||||
Poco::JSON::Object::Ptr Obj = parser.parse(response).extract<Poco::JSON::Object::Ptr>();
|
||||
|
||||
return EquipmentRoutingRecord::from_object(Obj);
|
||||
}
|
||||
|
||||
bool EquipmentRoutingRecord::from_object(Poco::JSON::Object::Ptr Obj) {
|
||||
Poco::DynamicStruct ds = *Obj;
|
||||
|
||||
id_ = ds["id"];
|
||||
equipmentId_ = ds["equipmentId"];
|
||||
customerId_ = ds["customerId"];
|
||||
gatewayId_ = ds["gatewayId"];
|
||||
createdTimestamp_ = ds["createdTimestamp"];
|
||||
lastModifiedTimestamp_ = ds["lastModifiedTimestamp"];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateEquipmentRoutingRecord(const EquipmentRoutingRecord &R) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DeleteEquipmentRoutingRecord(uint64_t id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool UpdateEquipmentRoutingRecord(const EquipmentRoutingRecord &R) {
|
||||
return false;
|
||||
}
|
||||
|
||||
EquipmentRoutingRecord GetEquipmentRoutingById(uint64_t Id) {
|
||||
EquipmentRoutingRecord E;
|
||||
|
||||
return E;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// Created by stephane bourque on 2021-02-17.
|
||||
//
|
||||
|
||||
#ifndef UCENTRAL_EQUIPMENTGATEWAYRECORD_H
|
||||
#define UCENTRAL_EQUIPMENTGATEWAYRECORD_H
|
||||
#ifndef UCENTRAL_ROUTING_H
|
||||
#define UCENTRAL_ROUTING_H
|
||||
|
||||
#include "Poco/JSON/Parser.h"
|
||||
#include "Poco/Net/HTTPSClientSession.h"
|
||||
@@ -30,7 +30,6 @@ namespace TIP::Routing {
|
||||
}
|
||||
|
||||
bool to_JSON(Poco::JSON::Object &obj) const;
|
||||
|
||||
bool from_stream(std::istream &response);
|
||||
bool from_object(Poco::JSON::Object::Ptr Obj);
|
||||
|
||||
@@ -66,6 +65,38 @@ namespace TIP::Routing {
|
||||
std::vector<TIP::Routing::EquipmentGatewayRecord> GetRoutingGatewaysByHost(const std::string &host);
|
||||
std::vector<TIP::Routing::EquipmentGatewayRecord> GetRoutingGatewaysByType(const std::string & Type = "CEGW");
|
||||
|
||||
class EquipmentRoutingRecord {
|
||||
public:
|
||||
[[nodiscard]] uint64_t id() const { return id_; };
|
||||
[[nodiscard]] uint64_t equipmentId() const { return equipmentId_; };
|
||||
[[nodiscard]] uint32_t customerId() const { return customerId_; };
|
||||
[[nodiscard]] uint64_t gatewayId() const { return gatewayId_; };
|
||||
[[nodiscard]] uint64_t createdTimestamp() const { return createdTimestamp_; };
|
||||
[[nodiscard]] uint64_t lastModifiedTimestamp() const { return lastModifiedTimestamp_; };
|
||||
|
||||
void id(uint64_t v) { id_ = v ; };
|
||||
void equipmentId(uint64_t v) { equipmentId_ = v ; };
|
||||
void customerId(uint32_t v) { customerId_ = v; };
|
||||
void gatewayId(uint64_t v) { gatewayId_ = v; };
|
||||
|
||||
bool to_JSON(Poco::JSON::Object &obj) const;
|
||||
bool from_stream(std::istream &response);
|
||||
bool from_object(Poco::JSON::Object::Ptr Obj);
|
||||
|
||||
private:
|
||||
uint64_t id_;
|
||||
uint64_t equipmentId_;
|
||||
uint32_t customerId_;
|
||||
uint64_t gatewayId_;
|
||||
uint64_t createdTimestamp_;
|
||||
uint64_t lastModifiedTimestamp_;
|
||||
};
|
||||
|
||||
bool CreateEquipmentRoutingRecord(const EquipmentRoutingRecord &R);
|
||||
bool UpdateEquipmentRoutingRecord(const EquipmentRoutingRecord &R);
|
||||
bool DeleteEquipmentRoutingRecord(uint64_t id);
|
||||
EquipmentRoutingRecord GetEquipmentRoutingRecordById(uint64_t id);
|
||||
|
||||
}
|
||||
|
||||
#endif //UCENTRAL_EQUIPMENTGATEWAYRECORD_H
|
||||
#endif //UCENTRAL_ROUTING_H
|
||||
@@ -30,7 +30,18 @@ namespace TIP::WebToken {
|
||||
|
||||
public:
|
||||
bool from_JSON(std::istream &response);
|
||||
const std::string &access_token() const { return access_token_; };
|
||||
[[nodiscard]] const std::string &access_token() const { return access_token_; };
|
||||
[[nodiscard]] const std::string &refresh_token() const { return refresh_token_; };
|
||||
[[nodiscard]] const std::string &id_token() const { return id_token_; };
|
||||
[[nodiscard]] const std::string &token_type() const { return token_type_; };
|
||||
[[nodiscard]] unsigned int expires_in() const { return expires_in_; };
|
||||
[[nodiscard]] unsigned int idle_timeout() const { return idle_timeout_; };
|
||||
|
||||
[[nodiscard]] bool read_access() const { return acl_template_.Read_; };
|
||||
[[nodiscard]] bool readWrite_access() const { return acl_template_.ReadWrite_; };
|
||||
[[nodiscard]] bool readWriteCreate_access() const { return acl_template_.ReadWriteCreate_; };
|
||||
[[nodiscard]] bool delete_access() const { return acl_template_.Delete_; };
|
||||
[[nodiscard]] bool portalLogin_access() const { return acl_template_.PortalLogin_; };
|
||||
|
||||
private:
|
||||
std::string access_token_;
|
||||
|
||||
20
src/TIPGWServer.cpp
Normal file
20
src/TIPGWServer.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-02-12.
|
||||
//
|
||||
#include "TIPGWServer.h"
|
||||
|
||||
TIPGWServer * TIPGWServer::instance_= nullptr;
|
||||
|
||||
TIPGWServer::TIPGWServer() noexcept:
|
||||
SubSystemServer("TIPGWServer","TIPGWServer","tip.gateway")
|
||||
{
|
||||
}
|
||||
|
||||
int TIPGWServer::start() {
|
||||
SubSystemServer::logger().information("Starting.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TIPGWServer::stop() {
|
||||
SubSystemServer::logger().information("Stopping.");
|
||||
}
|
||||
@@ -2,8 +2,10 @@
|
||||
// Created by stephane bourque on 2021-02-12.
|
||||
//
|
||||
|
||||
#ifndef UCENTRAL_UCENTRALSERVER_H
|
||||
#define UCENTRAL_UCENTRALSERVER_H
|
||||
#ifndef UCENTRAL_TIPGWSERVER_H
|
||||
#define UCENTRAL_TIPGWSERVER_H
|
||||
|
||||
#include "PropertiesFileServerList.h"
|
||||
|
||||
#include "Poco/Util/Application.h"
|
||||
#include "Poco/Util/ServerApplication.h"
|
||||
@@ -13,9 +15,7 @@
|
||||
#include "Poco/Util/AbstractConfiguration.h"
|
||||
#include "Poco/Util/IntValidator.h"
|
||||
#include "Poco/AutoPtr.h"
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#include "Poco/Logger.h"
|
||||
|
||||
using Poco::Util::Application;
|
||||
using Poco::Util::ServerApplication;
|
||||
@@ -26,22 +26,30 @@ using Poco::Util::AbstractConfiguration;
|
||||
using Poco::Util::OptionCallback;
|
||||
using Poco::Util::IntValidator;
|
||||
using Poco::AutoPtr;
|
||||
using Poco::Logger;
|
||||
|
||||
#include "SubSystemServer.h"
|
||||
|
||||
class UCentralGW: public Poco::Util::Subsystem
|
||||
class TIPGWServer: public SubSystemServer
|
||||
{
|
||||
public:
|
||||
UCentralGW();
|
||||
TIPGWServer() noexcept;
|
||||
|
||||
int start();
|
||||
void stop();
|
||||
|
||||
Logger & logger() { return SubSystemServer::logger(); };
|
||||
|
||||
static TIPGWServer *instance() {
|
||||
if(instance_== nullptr) {
|
||||
instance_ = new TIPGWServer;
|
||||
}
|
||||
return instance_;
|
||||
}
|
||||
|
||||
protected:
|
||||
const char *name() const { return "uCentralGW"; };
|
||||
void initialize(Application &self);
|
||||
void uninitialize();
|
||||
void reinitialize(Application& self);
|
||||
void defineOptions(OptionSet &options);
|
||||
|
||||
private:
|
||||
bool helpRequested_;
|
||||
static TIPGWServer *instance_;
|
||||
};
|
||||
|
||||
#endif //UCENTRAL_UCENTRALSERVER_H
|
||||
#endif //UCENTRAL_TIPGWSERVER_H
|
||||
231
src/app.cpp
231
src/app.cpp
@@ -1,231 +0,0 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-02-15.
|
||||
//
|
||||
|
||||
#include "app.h"
|
||||
|
||||
#include "Poco/Util/Application.h"
|
||||
#include "Poco/Util/Option.h"
|
||||
#include "Poco/Util/OptionSet.h"
|
||||
#include "Poco/Util/HelpFormatter.h"
|
||||
#include "Poco/Util/AbstractConfiguration.h"
|
||||
#include "Poco/Util/IntValidator.h"
|
||||
#include <iostream>
|
||||
|
||||
using Poco::Util::Application;
|
||||
using Poco::Util::Option;
|
||||
using Poco::Util::OptionSet;
|
||||
using Poco::Util::HelpFormatter;
|
||||
using Poco::Util::AbstractConfiguration;
|
||||
using Poco::Util::OptionCallback;
|
||||
using Poco::Util::IntValidator;
|
||||
using Poco::AutoPtr;
|
||||
|
||||
#include "common.h"
|
||||
#include "ucentralServer.h"
|
||||
#include "TIP/Api.h"
|
||||
#include "TIP/EquipmentGatewayRecord.h"
|
||||
|
||||
App::App():helpRequested_(false)
|
||||
{
|
||||
}
|
||||
|
||||
void App::initialize(Application& self)
|
||||
{
|
||||
// logging_channel_.assign(new FileChannel);
|
||||
addSubsystem(new UCentralGW);
|
||||
loadConfiguration(); // load default configuration files, if present
|
||||
Application::initialize(self);
|
||||
// add your own initialization code here
|
||||
}
|
||||
|
||||
void App::uninitialize()
|
||||
{
|
||||
// add your own uninitialization code here
|
||||
Application::uninitialize();
|
||||
}
|
||||
|
||||
void App::reinitialize(Application& self)
|
||||
{
|
||||
Application::reinitialize(self);
|
||||
// add your own reinitialization code here
|
||||
}
|
||||
|
||||
void App::defineOptions(OptionSet& options)
|
||||
{
|
||||
Application::defineOptions(options);
|
||||
|
||||
options.addOption(
|
||||
Option("help", "h", "display help information on command line arguments")
|
||||
.required(false)
|
||||
.repeatable(false)
|
||||
.callback(OptionCallback<App>(this, &App::handleHelp)));
|
||||
|
||||
options.addOption(
|
||||
Option("file", "f", "specify the configuration file")
|
||||
.required(false)
|
||||
.repeatable(true)
|
||||
.argument("file")
|
||||
.callback(OptionCallback<App>(this, &App::handleConfig)));
|
||||
|
||||
options.addOption(
|
||||
Option("debug", "d", "run in debug mode")
|
||||
.required(false)
|
||||
.repeatable(true)
|
||||
.callback(OptionCallback<App>(this, &App::handleDebug)));
|
||||
|
||||
options.addOption(
|
||||
Option("port", "p", "bind to port")
|
||||
.required(false)
|
||||
.repeatable(false)
|
||||
.argument("value")
|
||||
.validator(new IntValidator(0,9999))
|
||||
.callback(OptionCallback<App>(this, &App::handlePort)));
|
||||
}
|
||||
|
||||
void App::handleHelp(const std::string& name, const std::string& value)
|
||||
{
|
||||
helpRequested_ = true;
|
||||
displayHelp();
|
||||
stopOptionsProcessing();
|
||||
}
|
||||
|
||||
void App::handleDebug(const std::string& name, const std::string& value)
|
||||
{
|
||||
defineProperty(value);
|
||||
}
|
||||
|
||||
void App::handlePort(const std::string& name, const std::string& value)
|
||||
{
|
||||
defineProperty(value);
|
||||
}
|
||||
|
||||
void App::handleConfig(const std::string& name, const std::string& value)
|
||||
{
|
||||
std::cout << "Configuration file name: " << value << std::endl;
|
||||
loadConfiguration(value);
|
||||
}
|
||||
|
||||
void App::displayHelp()
|
||||
{
|
||||
HelpFormatter helpFormatter(options());
|
||||
helpFormatter.setCommand(commandName());
|
||||
helpFormatter.setUsage("OPTIONS");
|
||||
helpFormatter.setHeader("A uCentral gateway implementation for TIP.");
|
||||
helpFormatter.format(std::cout);
|
||||
}
|
||||
|
||||
void App::defineProperty(const std::string& def)
|
||||
{
|
||||
std::string name;
|
||||
std::string value;
|
||||
std::string::size_type pos = def.find('=');
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
name.assign(def, 0, pos);
|
||||
value.assign(def, pos + 1, def.length() - pos);
|
||||
}
|
||||
else name = def;
|
||||
config().setString(name, value);
|
||||
}
|
||||
|
||||
int App::main(const ArgVec& args)
|
||||
{
|
||||
if (!helpRequested_)
|
||||
{
|
||||
// logging_channel_-> setProperty("path",App::instance().config().getString("logging.path"));
|
||||
// logging_channel_-> setProperty("rotation",App::instance().config().getString("logging.rotation"));
|
||||
// logging_channel_-> setProperty("archive", "timestamp");
|
||||
|
||||
// AutoPtr<Formatter> Ftr(new AppLogFormatter);
|
||||
|
||||
// AutoPtr<FormattingChannel> FC( new FormattingChannel(Ftr,logging_channel_));
|
||||
|
||||
|
||||
// Logger::root().setChannel(FC);
|
||||
DBG
|
||||
Logger& logger = Logger::get("App");
|
||||
|
||||
logger.information("Command line:");
|
||||
std::ostringstream ostr;
|
||||
for(auto &it: args)
|
||||
{
|
||||
// ostr << it << ' ';
|
||||
}
|
||||
logger.information(ostr.str());
|
||||
logger.information("Arguments to main():");
|
||||
for(auto &it: args)
|
||||
{
|
||||
// logger().information(it);
|
||||
}
|
||||
logger.information("Application properties:");
|
||||
printProperties("");
|
||||
|
||||
std::cout << "1st login" << std::endl;
|
||||
TIP::API::Login();
|
||||
|
||||
std::vector<TIP::Routing::EquipmentGatewayRecord> gateways;
|
||||
|
||||
for(auto i: gateways)
|
||||
{
|
||||
std::cout << "Gateway: " << i.id() << std::endl;
|
||||
}
|
||||
|
||||
gateways = TIP::Routing::GetRoutingGatewaysByType();
|
||||
for(auto i: gateways)
|
||||
{
|
||||
std::cout << "ID: " << i.id() << "@" << i.hostname() << std::endl;
|
||||
}
|
||||
|
||||
std::cout << "ID: " << gateways[0].id() << std::endl;
|
||||
|
||||
TIP::Routing::EquipmentGatewayRecord E = TIP::Routing::GetRoutingGateway(1691801527873612933);
|
||||
std::cout << "Hostname: " << E.hostname() << std::endl;
|
||||
|
||||
gateways = TIP::Routing::GetRoutingGatewaysByHost("10.1.124.61");
|
||||
std::cout << "ID: " << gateways[0].id() << std::endl;
|
||||
|
||||
TIP::Routing::EquipmentGatewayRecord rr = gateways[0];
|
||||
|
||||
rr.hostname("10.3.111.3");
|
||||
rr.ipAddr("10.3.111.3");
|
||||
rr.port( 9911);
|
||||
TIP::Routing::CreateRoutingGateway(rr);
|
||||
|
||||
gateways = TIP::Routing::GetRoutingGatewaysByHost("10.3.111.3");
|
||||
|
||||
std::cout << "ID: " << gateways[0].id() << " Host: " << gateways[0].hostname() << std::endl;
|
||||
|
||||
TIP::Routing::DeleteRoutingGateway(gateways[0].id());
|
||||
|
||||
}
|
||||
|
||||
return Application::EXIT_OK;
|
||||
}
|
||||
|
||||
void App::printProperties(const std::string& base)
|
||||
{
|
||||
AbstractConfiguration::Keys keys;
|
||||
config().keys(base, keys);
|
||||
if (keys.empty())
|
||||
{
|
||||
if (config().hasProperty(base))
|
||||
{
|
||||
std::string msg;
|
||||
msg.append(base);
|
||||
msg.append(" = ");
|
||||
msg.append(config().getString(base));
|
||||
logger().information(msg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(auto &it: keys)
|
||||
{
|
||||
std::string fullKey = base;
|
||||
if (!fullKey.empty()) fullKey += '.';
|
||||
fullKey.append(it);
|
||||
printProperties(fullKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-02-12.
|
||||
//
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "yaml-cpp/yaml.h"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
uConfig::Config *uConfig::Config::instance_ = 0;
|
||||
|
||||
bool uConfig::Config::init(const char *filename) {
|
||||
|
||||
filename_ = filename;
|
||||
|
||||
cfg_ = std::make_shared<YAML::Node>(YAML::LoadFile(filename_));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool uConfig::init(const char *filename) {
|
||||
return uConfig::Config::instance()->init(filename);
|
||||
}
|
||||
45
src/config.h
45
src/config.h
@@ -1,45 +0,0 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-02-12.
|
||||
//
|
||||
|
||||
#ifndef UCENTRAL_CONFIG_H
|
||||
#define UCENTRAL_CONFIG_H
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
#include "yaml-cpp/yaml.h"
|
||||
|
||||
namespace uConfig {
|
||||
|
||||
bool init(const char * filename);
|
||||
|
||||
class Config {
|
||||
public:
|
||||
Config() {
|
||||
}
|
||||
|
||||
bool init(const char *filename);
|
||||
auto get(const char *node_name, const char *sub_node) { return (*cfg_)[node_name][sub_node]; }
|
||||
template<typename T> T get(const char *node_name, const char *sub_node) { return (*cfg_)[node_name][sub_node].as<T>(); }
|
||||
|
||||
static Config *instance() {
|
||||
if(!instance_)
|
||||
instance_ = new Config;
|
||||
return instance_;
|
||||
}
|
||||
|
||||
private:
|
||||
static Config *instance_;
|
||||
std::string filename_;
|
||||
std::shared_ptr<YAML::Node> cfg_;
|
||||
};
|
||||
|
||||
template<typename T> T get(const char *node_name, const char *sub_node)
|
||||
{
|
||||
return uConfig::Config::instance()->get<T>(node_name,sub_node);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif //UCENTRAL_CONFIG_H
|
||||
@@ -1,8 +0,0 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-02-12.
|
||||
//
|
||||
|
||||
// This is the implementation of the tipapi/gw/equipment-gateway-service-openapi.yaml
|
||||
|
||||
#include "gateway.h"
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-02-12.
|
||||
//
|
||||
|
||||
#ifndef UCENTRAL_GATEWAY_H
|
||||
#define UCENTRAL_GATEWAY_H
|
||||
|
||||
#endif //UCENTRAL_GATEWAY_H
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "app.h"
|
||||
#include "uCentral.h"
|
||||
|
||||
POCO_APP_MAIN(App)
|
||||
POCO_SERVER_MAIN(uCentral)
|
||||
9
src/openapi_local_defs.h
Normal file
9
src/openapi_local_defs.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef OPEN_API_LOCAL_DEFS_H
|
||||
#define OPEN_API_LOCAL_DEFS_H
|
||||
|
||||
typedef std::string FullDateRFC3339;
|
||||
typedef std::string BinaryString;
|
||||
typedef std::string Base64String;
|
||||
typedef std::string DateTimeRFC3339;
|
||||
|
||||
#endif
|
||||
1176
src/portal-services-openapi.cpp
Normal file
1176
src/portal-services-openapi.cpp
Normal file
File diff suppressed because it is too large
Load Diff
11375
src/portal-services-openapi.h
Normal file
11375
src/portal-services-openapi.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,58 +0,0 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-02-12.
|
||||
//
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "tipApi.h"
|
||||
#include "app.h"
|
||||
|
||||
void TIPAPI::init() {
|
||||
initialized_ = true ;
|
||||
key_filename_ = App::instance().config().getString("tip.key_filename") ;
|
||||
cert_filename_ = App::instance().config().getString("tip.cert_filename");
|
||||
cacert_filename_ = App::instance().config().getString("tip.cacert_filename");
|
||||
key_filename_password_ = App::instance().config().getString("tip.key_password");
|
||||
|
||||
Poco::Net::SSLManager::instance().initializeClient(new MyPassPhraseHandler, 0, 0);
|
||||
ctx_ptr_ = new Poco::Net::Context(Poco::Net::Context::TLS_CLIENT_USE,
|
||||
key_filename_,
|
||||
cert_filename_,
|
||||
cacert_filename_,
|
||||
Poco::Net::Context::VERIFY_NONE);
|
||||
Poco::Net::SSLManager::instance().initializeClient(new MyPassPhraseHandler, new MyInvalidCertificateHandler, ctx_ptr_);
|
||||
}
|
||||
|
||||
bool TIPAPI::login() {
|
||||
|
||||
if(!initialized_)
|
||||
init();
|
||||
|
||||
Poco::Net::HTTPSClientSession session( App::instance().config().getString("tipapi.host"),
|
||||
App::instance().config().getInt("tipapi.port"), ctx_ptr_);
|
||||
|
||||
Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, "/management/v1/oauth2/token", Poco::Net::HTTPMessage::HTTP_1_1);
|
||||
request.setContentType("application/json");
|
||||
|
||||
Poco::JSON::Object obj;
|
||||
obj.set("userId", App::instance().config().getString("tiplogin.username"));
|
||||
obj.set("password", App::instance().config().getString("tiplogin.password"));
|
||||
std::stringstream ss;
|
||||
obj.stringify(ss);
|
||||
request.setContentLength(ss.str().size());
|
||||
std::ostream& o = session.sendRequest(request);
|
||||
obj.stringify(o);
|
||||
|
||||
Poco::Net::HTTPResponse response;
|
||||
|
||||
std::istream& s = session.receiveResponse(response);
|
||||
|
||||
Poco::JSON::Parser parser;
|
||||
Poco::JSON::Object::Ptr ret = parser.parse(s).extract<Poco::JSON::Object::Ptr>();
|
||||
|
||||
access_token_ = ret->get("access_token").toString();
|
||||
|
||||
std::cout << "ACCESS_TOKEN: " << access_token_ << std::endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
87
src/tipApi.h
87
src/tipApi.h
@@ -1,87 +0,0 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-02-12.
|
||||
//
|
||||
|
||||
// This implements the various calls to the tipController
|
||||
|
||||
#ifndef UCENTRAL_TIPAPI_H
|
||||
#define UCENTRAL_TIPAPI_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "Poco/JSON/JSON.h"
|
||||
#include "Poco/JSON/Object.h"
|
||||
#include "Poco/URI.h"
|
||||
#include "Poco/JSON/Parser.h"
|
||||
#include "Poco/Net/HTTPSClientSession.h"
|
||||
#include "Poco/Net/HTTPClientSession.h"
|
||||
#include "Poco/Net/HTTPResponse.h"
|
||||
#include "Poco/Net/HTTPRequest.h"
|
||||
#include "Poco/Net/Context.h"
|
||||
#include "Poco/Net/SSLManager.h"
|
||||
#include "Poco/Net/NetSSL.h"
|
||||
#include "Poco/Net/PrivateKeyPassphraseHandler.h"
|
||||
#include "Poco/Net/KeyFileHandler.h"
|
||||
#include "Poco/Net/InvalidCertificateHandler.h"
|
||||
|
||||
#include "common.h"
|
||||
|
||||
class MyPassPhraseHandler : public Poco::Net::KeyFileHandler {
|
||||
public:
|
||||
MyPassPhraseHandler()
|
||||
:Poco::Net::KeyFileHandler(false){
|
||||
|
||||
};
|
||||
|
||||
~MyPassPhraseHandler() {};
|
||||
|
||||
void onPrivateKeyRequested( const void * pSender, std::string & privateKey ) {
|
||||
std::cout << "Private key: " << privateKey << std::endl;
|
||||
privateKey = "mypassword";
|
||||
}
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
class MyInvalidCertificateHandler : public Poco::Net::InvalidCertificateHandler
|
||||
{
|
||||
public:
|
||||
MyInvalidCertificateHandler() : Poco::Net::InvalidCertificateHandler(false) {};
|
||||
~MyInvalidCertificateHandler() {};
|
||||
void onInvalidCertificate(const void * pSender,Poco::Net::VerificationErrorArgs & errorCert)
|
||||
{
|
||||
std::cout << "CERT: ignoring cert." << std::endl;
|
||||
errorCert.setIgnoreError(true);
|
||||
}
|
||||
private:
|
||||
};
|
||||
|
||||
class TIPAPI {
|
||||
public:
|
||||
TIPAPI():initialized_(false) {
|
||||
}
|
||||
|
||||
~TIPAPI() {
|
||||
if(initialized_)
|
||||
Poco::Net::SSLManager::instance().shutdown();
|
||||
}
|
||||
|
||||
bool login();
|
||||
void init();
|
||||
|
||||
private:
|
||||
bool initialized_;
|
||||
std::string portal_host_; // TIP portal server name: default to wlan-ui.wlan.local
|
||||
std::string username_; // TIP user name: default to "support@example.com"
|
||||
std::string password_; // TIP user password: default to "support"
|
||||
unsigned int tip_port_; // TIP portal management port: default to 9051
|
||||
std::string access_token_; // Token obtained during login
|
||||
std::string key_filename_;
|
||||
std::string cert_filename_;
|
||||
std::string cacert_filename_;
|
||||
std::string key_filename_password_;
|
||||
bool use_ssl_;
|
||||
Poco::Net::Context * ctx_ptr_;
|
||||
};
|
||||
|
||||
#endif //UCENTRAL_TIPAPI_H
|
||||
164
src/uCentral.cpp
Normal file
164
src/uCentral.cpp
Normal file
@@ -0,0 +1,164 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-02-15.
|
||||
//
|
||||
|
||||
#include "uCentral.h"
|
||||
|
||||
#include "Poco/Util/Application.h"
|
||||
#include "Poco/Util/Option.h"
|
||||
#include "Poco/Util/OptionSet.h"
|
||||
#include "Poco/Util/HelpFormatter.h"
|
||||
#include "Poco/Util/AbstractConfiguration.h"
|
||||
#include "Poco/Util/IntValidator.h"
|
||||
#include <iostream>
|
||||
|
||||
using Poco::Util::Application;
|
||||
using Poco::Util::Option;
|
||||
using Poco::Util::OptionSet;
|
||||
using Poco::Util::HelpFormatter;
|
||||
using Poco::Util::AbstractConfiguration;
|
||||
using Poco::Util::OptionCallback;
|
||||
using Poco::Util::IntValidator;
|
||||
using Poco::AutoPtr;
|
||||
|
||||
#include "TIPGWServer.h"
|
||||
#include "uCentralRESTAPIServer.h"
|
||||
#include "uCentralWebSocketServer.h"
|
||||
#include "uStorageService.h"
|
||||
#include "DeviceStatusServer.h"
|
||||
|
||||
#include "TIP/Api.h"
|
||||
#include "TIP/Routing.h"
|
||||
|
||||
uCentral::uCentral():helpRequested_(false)
|
||||
{
|
||||
}
|
||||
|
||||
void uCentral::initialize(Application& self)
|
||||
{
|
||||
// logging_channel_.assign(new FileChannel);
|
||||
loadConfiguration(); // load default configuration files, if present
|
||||
|
||||
addSubsystem(TIPGWServer::instance());
|
||||
addSubsystem(uCentralRESTAPIServer::instance());
|
||||
addSubsystem(uCentralWebSocketServer::instance());
|
||||
addSubsystem(uStorageService::instance());
|
||||
|
||||
ServerApplication::initialize(self);
|
||||
logger().information("Starting...");
|
||||
// add your own initialization code here
|
||||
}
|
||||
|
||||
void uCentral::uninitialize()
|
||||
{
|
||||
// add your own uninitialization code here
|
||||
Application::uninitialize();
|
||||
}
|
||||
|
||||
void uCentral::reinitialize(Application& self)
|
||||
{
|
||||
Application::reinitialize(self);
|
||||
// add your own reinitialization code here
|
||||
}
|
||||
|
||||
void uCentral::defineOptions(OptionSet& options)
|
||||
{
|
||||
Application::defineOptions(options);
|
||||
|
||||
options.addOption(
|
||||
Option("help", "h", "display help information on command line arguments")
|
||||
.required(false)
|
||||
.repeatable(false)
|
||||
.callback(OptionCallback<uCentral>(this, &uCentral::handleHelp)));
|
||||
|
||||
options.addOption(
|
||||
Option("file", "f", "specify the configuration file")
|
||||
.required(false)
|
||||
.repeatable(true)
|
||||
.argument("file")
|
||||
.callback(OptionCallback<uCentral>(this, &uCentral::handleConfig)));
|
||||
|
||||
options.addOption(
|
||||
Option("debug", "d", "run in debug mode")
|
||||
.required(false)
|
||||
.repeatable(true)
|
||||
.callback(OptionCallback<uCentral>(this, &uCentral::handleDebug)));
|
||||
|
||||
options.addOption(
|
||||
Option("port", "p", "bind to port")
|
||||
.required(false)
|
||||
.repeatable(false)
|
||||
.argument("value")
|
||||
.validator(new IntValidator(0,9999))
|
||||
.callback(OptionCallback<uCentral>(this, &uCentral::handlePort)));
|
||||
}
|
||||
|
||||
void uCentral::handleHelp(const std::string& name, const std::string& value)
|
||||
{
|
||||
helpRequested_ = true;
|
||||
displayHelp();
|
||||
stopOptionsProcessing();
|
||||
}
|
||||
|
||||
void uCentral::handleDebug(const std::string& name, const std::string& value)
|
||||
{
|
||||
defineProperty(value);
|
||||
}
|
||||
|
||||
void uCentral::handlePort(const std::string& name, const std::string& value)
|
||||
{
|
||||
defineProperty(value);
|
||||
}
|
||||
|
||||
void uCentral::handleConfig(const std::string& name, const std::string& value)
|
||||
{
|
||||
std::cout << "Configuration file name: " << value << std::endl;
|
||||
loadConfiguration(value);
|
||||
}
|
||||
|
||||
void uCentral::displayHelp()
|
||||
{
|
||||
HelpFormatter helpFormatter(options());
|
||||
helpFormatter.setCommand(commandName());
|
||||
helpFormatter.setUsage("OPTIONS");
|
||||
helpFormatter.setHeader("A uCentral gateway implementation for TIP.");
|
||||
helpFormatter.format(std::cout);
|
||||
}
|
||||
|
||||
void uCentral::defineProperty(const std::string& def)
|
||||
{
|
||||
std::string name;
|
||||
std::string value;
|
||||
std::string::size_type pos = def.find('=');
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
name.assign(def, 0, pos);
|
||||
value.assign(def, pos + 1, def.length() - pos);
|
||||
}
|
||||
else name = def;
|
||||
config().setString(name, value);
|
||||
}
|
||||
|
||||
int uCentral::main(const ArgVec& args)
|
||||
{
|
||||
if (!helpRequested_)
|
||||
{
|
||||
Logger& logger = Logger::get("App");
|
||||
|
||||
uStorageService::instance()->start();
|
||||
DeviceStatusServer::instance()->start();
|
||||
TIPGWServer::instance()->start();
|
||||
uCentralRESTAPIServer::instance()->start();
|
||||
uCentralWebSocketServer::instance()->start();
|
||||
|
||||
waitForTerminationRequest();
|
||||
|
||||
TIPGWServer::instance()->stop();
|
||||
uCentralRESTAPIServer::instance()->stop();
|
||||
uCentralWebSocketServer::instance()->stop();
|
||||
DeviceStatusServer::instance()->stop();
|
||||
uStorageService::instance()->stop();
|
||||
}
|
||||
|
||||
return Application::EXIT_OK;
|
||||
}
|
||||
@@ -2,10 +2,10 @@
|
||||
// Created by stephane bourque on 2021-02-15.
|
||||
//
|
||||
|
||||
#ifndef UCENTRAL_APP_H
|
||||
#define UCENTRAL_APP_H
|
||||
#ifndef UCENTRAL_UCENTRAL_H
|
||||
#define UCENTRAL_UCENTRAL_H
|
||||
|
||||
#include "Poco/Util/Application.h"
|
||||
#include "Poco/Util/ServerApplication.h"
|
||||
#include "Poco/Util/Option.h"
|
||||
#include "Poco/Util/OptionSet.h"
|
||||
#include "Poco/Util/HelpFormatter.h"
|
||||
@@ -18,11 +18,12 @@
|
||||
#include "Poco/FormattingChannel.h"
|
||||
#include "Poco/Formatter.h"
|
||||
#include "Poco/Message.h"
|
||||
#include "Poco/Data/Session.h"
|
||||
#include "Poco/Data/SQLite/Connector.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
|
||||
using Poco::Util::Application;
|
||||
using Poco::Util::Option;
|
||||
using Poco::Util::OptionSet;
|
||||
@@ -38,6 +39,10 @@ using Poco::FileChannel;
|
||||
using Poco::AutoPtr;
|
||||
using Poco::Message;
|
||||
|
||||
#include "TIPGWServer.h"
|
||||
#include "uCentralWebSocketServer.h"
|
||||
#include "uCentralRESTAPIServer.h"
|
||||
|
||||
class AppLogFormatter : public Formatter {
|
||||
public:
|
||||
void format(const Message &msg, std::string & text )
|
||||
@@ -46,10 +51,11 @@ public:
|
||||
}
|
||||
private:
|
||||
};
|
||||
class App: public Application
|
||||
|
||||
class uCentral: public Poco::Util::ServerApplication
|
||||
{
|
||||
public:
|
||||
App();
|
||||
uCentral();
|
||||
|
||||
protected:
|
||||
void initialize(Application& self);
|
||||
@@ -71,4 +77,4 @@ private:
|
||||
};
|
||||
|
||||
|
||||
#endif //UCENTRAL_APP_H
|
||||
#endif //UCENTRAL_UCENTRAL_H
|
||||
24
src/uCentralRESTAPIServer.cpp
Normal file
24
src/uCentralRESTAPIServer.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-02-28.
|
||||
//
|
||||
|
||||
#include "uCentralRESTAPIServer.h"
|
||||
|
||||
uCentralRESTAPIServer * uCentralRESTAPIServer::instance_ = nullptr;
|
||||
|
||||
uCentralRESTAPIServer::uCentralRESTAPIServer() noexcept:
|
||||
SubSystemServer("RESTAPIServer","RESTAPIServer","ucentral.restapi")
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int uCentralRESTAPIServer::start() {
|
||||
SubSystemServer::logger().information("Starting ");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void uCentralRESTAPIServer::stop() {
|
||||
SubSystemServer::logger().information("Stopping ");
|
||||
|
||||
}
|
||||
32
src/uCentralRESTAPIServer.h
Normal file
32
src/uCentralRESTAPIServer.h
Normal file
@@ -0,0 +1,32 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-02-28.
|
||||
//
|
||||
|
||||
#ifndef UCENTRAL_UCENTRALRESTAPISERVER_H
|
||||
#define UCENTRAL_UCENTRALRESTAPISERVER_H
|
||||
|
||||
#include "SubSystemServer.h"
|
||||
|
||||
class uCentralRESTAPIServer : public SubSystemServer {
|
||||
|
||||
public:
|
||||
uCentralRESTAPIServer() noexcept;
|
||||
|
||||
int start();
|
||||
void stop();
|
||||
|
||||
Logger & logger() { return SubSystemServer::logger(); };
|
||||
|
||||
static uCentralRESTAPIServer *instance() {
|
||||
if(instance_== nullptr) {
|
||||
instance_ = new uCentralRESTAPIServer;
|
||||
}
|
||||
return instance_;
|
||||
}
|
||||
|
||||
private:
|
||||
static uCentralRESTAPIServer * instance_;
|
||||
|
||||
};
|
||||
|
||||
#endif //UCENTRAL_UCENTRALRESTAPISERVER_H
|
||||
229
src/uCentralWebSocketServer.cpp
Normal file
229
src/uCentralWebSocketServer.cpp
Normal file
@@ -0,0 +1,229 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-02-28.
|
||||
//
|
||||
|
||||
#include "uCentralWebSocketServer.h"
|
||||
#include "uStorageService.h"
|
||||
|
||||
uCentralWebSocketServer * uCentralWebSocketServer::instance_= nullptr;
|
||||
|
||||
uCentralWebSocketServer::uCentralWebSocketServer() noexcept:
|
||||
SubSystemServer("WebSocketServer","WebSocketServer","ucentral.websocket")
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int uCentralWebSocketServer::start() {
|
||||
// SubSystemServer::logger().information
|
||||
|
||||
std::string l{"Starting: " +
|
||||
SubSystemServer::host(0).address() + ":" + std::to_string(SubSystemServer::host(0).port()) +
|
||||
" key:" + SubSystemServer::host(0).key_file() + " cert:" + SubSystemServer::host(0).cert_file()};
|
||||
|
||||
std::cout << "LOGGING: " << l << std::endl;
|
||||
|
||||
SecureServerSocket sock( SubSystemServer::host(0).port(),
|
||||
64,
|
||||
new Context(Poco::Net::Context::TLS_SERVER_USE,
|
||||
SubSystemServer::host(0).key_file(),
|
||||
SubSystemServer::host(0).cert_file(),
|
||||
""));
|
||||
|
||||
server_ = new HTTPServer( new RequestHandlerFactory, sock, new HTTPServerParams);
|
||||
|
||||
server_->start();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void uCentralWebSocketServer::stop() {
|
||||
SubSystemServer::logger().information("Stopping ");
|
||||
|
||||
server_->stop();
|
||||
}
|
||||
|
||||
std::string default_config() {
|
||||
return std::string{"{\"cfg\": {\"uuid\":1613927736,\"steer\":{\"enabled\":1,\"network\":\"wan\",\"debug_level\":0},\"stats\":{\"interval\":60,\"neighbours\":1,\"traffic\":1,\"wifiiface\":1,\"wifistation\":1,\"pids\":1,\"serviceprobe\":1,\"lldp\":1,\"system\":1,\"poe\":1},\"phy\":[{\"band\":\"2\",\"cfg\":{\"disabled\":0,\"country\":\"DE\",\"channel\":6,\"txpower\":30,\"beacon_int\":100,\"htmode\":\"HE40\",\"hwmode\":\"11g\",\"chanbw\":20}},{\"band\":\"5\",\"cfg\":{\"mimo\":\"4x4\",\"disabled\":0,\"country\":\"DE\",\"channel\":0,\"htmode\":\"HE80\"}},{\"band\":\"5u\",\"cfg\":{\"disabled\":0,\"country\":\"DE\",\"channel\":100,\"htmode\":\"VHT80\"}},{\"band\":\"5l\",\"cfg\":{\"disabled\":0,\"country\":\"DE\",\"channel\":36,\"htmode\":\"VHT80\"}}],\"ssid\":[{\"band\":[\"2\"],\"cfg\":{\"ssid\":\"uCentral-Guest\",\"encryption\":\"psk2\",\"key\":\"OpenWifi\",\"mode\":\"ap\",\"isolate\":1,\"network\":\"guest\",\"ieee80211r\":1,\"ieee80211v\":1,\"ieee80211k\":1,\"ft_psk_generate_local\":1,\"ft_over_ds\":1,\"mobility_domain\":\"4f57\"}},{\"band\":[\"5l\",\"5\"],\"cfg\":{\"ssid\":\"uCentral-NAT.200\",\"encryption\":\"psk2\",\"key\":\"OpenWifi\",\"mode\":\"ap\",\"network\":\"nat200\",\"ieee80211r\":1,\"ieee80211v\":1,\"ieee80211k\":1,\"ft_psk_generate_local\":1,\"ft_over_ds\":1,\"mobility_domain\":\"4f51\"}},{\"band\":[\"5l\",\"5\"],\"cfg\":{\"ssid\":\"uCentral-EAP\",\"encryption\":\"wpa2\",\"server\":\"148.251.188.218\",\"port\":1812,\"auth_secret\":\"uSyncRad1u5\",\"mode\":\"ap\",\"network\":\"lan\",\"ieee80211r\":1,\"ieee80211v\":1,\"ieee80211k\":1,\"ft_psk_generate_local\":1,\"ft_over_ds\":1,\"mobility_domain\":\"4f51\"}},{\"band\":[\"5l\",\"5\"],\"cfg\":{\"ssid\":\"uCentral\",\"encryption\":\"psk2\",\"key\":\"OpenWifi\",\"mode\":\"ap\",\"network\":\"wan\",\"ieee80211r\":1,\"ieee80211v\":1,\"ieee80211k\":1,\"ft_psk_generate_local\":1,\"ft_over_ds\":1,\"mobility_domain\":\"4f51\"}}],\"network\":[{\"mode\":\"wan\",\"cfg\":{\"proto\":\"dhcp\"}},{\"mode\":\"gre\",\"cfg\":{\"vid\":\"50\",\"peeraddr\":\"50.210.104.108\"}},{\"mode\":\"nat\",\"vlan\":200,\"cfg\":{\"proto\":\"static\",\"ipaddr\":\"192.168.16.1\",\"netmask\":\"255.255.255.0\",\"mtu\":1500,\"ip6assign\":60,\"dhcp\":{\"start\":10,\"limit\":100,\"leasetime\":\"6h\"},\"leases\":[{\"ip\":\"192.168.100.2\",\"mac\":\"00:11:22:33:44:55\",\"hostname\":\"test\"},{\"ip\":\"192.168.100.3\",\"mac\":\"00:11:22:33:44:56\",\"hostname\":\"test2\"}]}},{\"mode\":\"guest\",\"cfg\":{\"proto\":\"static\",\"ipaddr\":\"192.168.12.11\",\"dhcp\":{\"start\":10,\"limit\":100,\"leasetime\":\"6h\"}}}],\"ntp\":{\"enabled\":1,\"enable_server\":1,\"server\":[\"0.openwrt.pool.ntp.org\",\"1.openwrt.pool.ntp.org\"]},\"ssh\":{\"enable\":1,\"Port\":22},\"system\":{\"timezone\":\"CET-1CEST,M3.5.0,M10.5.0/3\"},\"log\":{\"_log_proto\":\"udp\",\"_log_ip\":\"192.168.11.23\",\"_log_port\":12345,\"_log_hostname\":\"foo\",\"_log_size\":128},\"rtty\":{\"host\":\"websocket.usync.org\",\"token\":\"7049cb6b7949ba06c6b356d76f0f6275\",\"interface\":\"wan\"}}}"};
|
||||
}
|
||||
|
||||
std::string uCentralWebSocketServer::process_message(const std::string &m, ConnectionState &conn)
|
||||
{
|
||||
Parser parser;
|
||||
|
||||
Poco::Dynamic::Var result = parser.parse(m);
|
||||
Poco::JSON::Object::Ptr object = result.extract<Poco::JSON::Object::Ptr>();
|
||||
Poco::DynamicStruct ds = *object;
|
||||
|
||||
std::string SerialNumber = ds["serial"].toString();
|
||||
|
||||
std::cout << "SERIAL: " << SerialNumber << std::endl;
|
||||
|
||||
conn.SerialNumber = SerialNumber;
|
||||
|
||||
if(ds.contains("state") && ds.contains("serial"))
|
||||
{
|
||||
logger().information(SerialNumber + ": updating statistics.");
|
||||
std::cout << "STATE_MSG 1 " << std::endl ;
|
||||
std::string NewStatistics{ds["state"].toString()};
|
||||
uStorageService::instance()->AddStatisticsData(conn.SerialNumber,conn.CfgUUID,NewStatistics);
|
||||
std::cout << "STATE_MSG 2 " << std::endl ;
|
||||
}
|
||||
else if(ds.contains("capab") && ds.contains("serial"))
|
||||
{
|
||||
logger().information(SerialNumber + ": updating capabilities.");
|
||||
conn.SerialNumber = ds["serial"].toString();
|
||||
std::string NewCapabilities{ds["capab"].toString()};
|
||||
uStorageService::instance()->UpdateDeviceCapabilities(conn.SerialNumber,NewCapabilities);
|
||||
}
|
||||
else if(ds.contains("uuid") && ds.contains("serial") && ds.contains("active")) {
|
||||
conn.CfgUUID = ds["uuid"];
|
||||
std::cout << "UUID of config" << ds["uuid"].toString() << std::endl;
|
||||
return default_config();
|
||||
}
|
||||
else if(ds.contains("uuid") && ds.contains("serial")) {
|
||||
conn.CfgUUID = ds["uuid"];
|
||||
std::cout << "UUID of config" << ds["uuid"].toString() << std::endl;
|
||||
return default_config();
|
||||
}
|
||||
else if(ds.contains("log")) {
|
||||
std::string log = ds["log"].toString();
|
||||
logger().warning("DEVICE-LOG(" + SerialNumber + "):" + log);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "UNKNOWN_MESSAGE: " << m << std::endl;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
void PageRequestHandler::handleRequest(HTTPServerRequest& request, HTTPServerResponse& response)
|
||||
{
|
||||
response.setChunkedTransferEncoding(true);
|
||||
response.setContentType("text/html");
|
||||
std::ostream& ostr = response.send();
|
||||
ostr << "<html>";
|
||||
ostr << "<head>";
|
||||
ostr << "<title>WebSocketServer</title>";
|
||||
ostr << "<script type=\"text/javascript\">";
|
||||
ostr << "function WebSocketTest()";
|
||||
ostr << "{";
|
||||
ostr << " if (\"WebSocket\" in window)";
|
||||
ostr << " {";
|
||||
ostr << " var ws = new WebSocket(\"ws://" << request.serverAddress().toString() << "/ws\");";
|
||||
ostr << " ws.onopen = function()";
|
||||
ostr << " {";
|
||||
ostr << " ws.send(\"Hello, world!\");";
|
||||
ostr << " };";
|
||||
ostr << " ws.onmessage = function(evt)";
|
||||
ostr << " { ";
|
||||
ostr << " var msg = evt.data;";
|
||||
ostr << " alert(\"Message received: \" + msg);";
|
||||
ostr << " ws.close();";
|
||||
ostr << " };";
|
||||
ostr << " ws.onclose = function()";
|
||||
ostr << " { ";
|
||||
ostr << " alert(\"WebSocket closed.\");";
|
||||
ostr << " };";
|
||||
ostr << " }";
|
||||
ostr << " else";
|
||||
ostr << " {";
|
||||
ostr << " alert(\"This browser does not support WebSockets.\");";
|
||||
ostr << " }";
|
||||
ostr << "}";
|
||||
ostr << "</script>";
|
||||
ostr << "</head>";
|
||||
ostr << "<body>";
|
||||
ostr << " <h1>WebSocket Server</h1>";
|
||||
ostr << " <p><a href=\"javascript:WebSocketTest()\">Run WebSocket Script</a></p>";
|
||||
ostr << "</body>";
|
||||
ostr << "</html>";
|
||||
}
|
||||
|
||||
void WebSocketRequestHandler::handleRequest(HTTPServerRequest& request, HTTPServerResponse& response)
|
||||
{
|
||||
Application& app = Application::instance();
|
||||
try
|
||||
{
|
||||
|
||||
WebSocket ws(request, response);
|
||||
std::string Address{ws.peerAddress().toString()};
|
||||
|
||||
std::cout << "Connection from: " << Address << std::endl;
|
||||
|
||||
ConnectionState conn{ .SerialNumber{""},
|
||||
.Address{Address},
|
||||
.messages=0,
|
||||
.CfgUUID=0,
|
||||
.RX=0,
|
||||
.TX=0};
|
||||
|
||||
uCentralWebSocketServer::instance()->logger().information("WebSocket connection established from .");
|
||||
char buffer[32000];
|
||||
int flags;
|
||||
int n;
|
||||
do
|
||||
{
|
||||
|
||||
ws.peerAddress().toString();
|
||||
memset(buffer,0,sizeof(buffer));
|
||||
n = ws.receiveFrame(buffer, sizeof(buffer), flags);
|
||||
conn.messages++;
|
||||
|
||||
uCentralWebSocketServer::instance()->logger().information(Poco::format("Frame received (length=%d, flags=0x%x).", n, unsigned(flags)));
|
||||
|
||||
std::string m{buffer};
|
||||
conn.RX += m.size();
|
||||
|
||||
std::string return_document = uCentralWebSocketServer::instance()->process_message(m,conn);
|
||||
conn.TX += return_document.size();
|
||||
|
||||
if( !return_document.empty()) {
|
||||
// std::cout << "RETURN:" << return_document << std::endl;
|
||||
ws.sendFrame(return_document.c_str(), return_document.size(), flags);
|
||||
}
|
||||
}
|
||||
while (n > 0 && (flags & WebSocket::FRAME_OP_BITMASK) != WebSocket::FRAME_OP_CLOSE);
|
||||
std::cout << "ENDING CONNECTION..." << std::endl;
|
||||
uCentralWebSocketServer::instance()->logger().information("WebSocket connection closed.");
|
||||
}
|
||||
catch (WebSocketException& exc)
|
||||
{
|
||||
uCentralWebSocketServer::instance()->logger().log(exc);
|
||||
switch (exc.code())
|
||||
{
|
||||
case WebSocket::WS_ERR_HANDSHAKE_UNSUPPORTED_VERSION:
|
||||
response.set("Sec-WebSocket-Version", WebSocket::WEBSOCKET_VERSION);
|
||||
// fallthrough
|
||||
case WebSocket::WS_ERR_NO_HANDSHAKE:
|
||||
case WebSocket::WS_ERR_HANDSHAKE_NO_VERSION:
|
||||
case WebSocket::WS_ERR_HANDSHAKE_NO_KEY:
|
||||
response.setStatusAndReason(HTTPResponse::HTTP_BAD_REQUEST);
|
||||
response.setContentLength(0);
|
||||
response.send();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HTTPRequestHandler* RequestHandlerFactory::createRequestHandler(const HTTPServerRequest& request)
|
||||
{
|
||||
uCentralWebSocketServer::instance()->logger().information("Request from "
|
||||
+ request.clientAddress().toString()
|
||||
+ ": "
|
||||
+ request.getMethod()
|
||||
+ " "
|
||||
+ request.getURI()
|
||||
+ " "
|
||||
+ request.getVersion());
|
||||
|
||||
for (HTTPServerRequest::ConstIterator it = request.begin(); it != request.end(); ++it)
|
||||
{
|
||||
uCentralWebSocketServer::instance()->logger().information(it->first + ": " + it->second);
|
||||
}
|
||||
|
||||
if(request.find("Upgrade") != request.end() && Poco::icompare(request["Upgrade"], "websocket") == 0)
|
||||
return new WebSocketRequestHandler;
|
||||
else
|
||||
return new PageRequestHandler;
|
||||
}
|
||||
93
src/uCentralWebSocketServer.h
Normal file
93
src/uCentralWebSocketServer.h
Normal file
@@ -0,0 +1,93 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-02-28.
|
||||
//
|
||||
|
||||
#ifndef UCENTRAL_UCENTRALWEBSOCKETSERVER_H
|
||||
#define UCENTRAL_UCENTRALWEBSOCKETSERVER_H
|
||||
|
||||
#include "SubSystemServer.h"
|
||||
|
||||
#include "Poco/Net/HTTPServer.h"
|
||||
#include "Poco/Net/HTTPRequestHandler.h"
|
||||
#include "Poco/Net/HTTPRequestHandlerFactory.h"
|
||||
#include "Poco/Net/HTTPServerParams.h"
|
||||
#include "Poco/Net/HTTPServerRequest.h"
|
||||
#include "Poco/Net/HTTPServerResponse.h"
|
||||
#include "Poco/Net/HTTPServerParams.h"
|
||||
#include "Poco/Net/ServerSocket.h"
|
||||
#include "Poco/Net/SecureServerSocket.h"
|
||||
#include "Poco/Net/WebSocket.h"
|
||||
#include "Poco/Net/NetException.h"
|
||||
#include "Poco/Net/Context.h"
|
||||
#include "Poco/JSON/Parser.h"
|
||||
#include "Poco/DynamicAny.h"
|
||||
|
||||
|
||||
|
||||
using Poco::Net::ServerSocket;
|
||||
using Poco::Net::SecureServerSocket;
|
||||
using Poco::Net::WebSocket;
|
||||
using Poco::Net::Context;
|
||||
using Poco::Net::WebSocketException;
|
||||
using Poco::Net::HTTPRequestHandler;
|
||||
using Poco::Net::HTTPRequestHandlerFactory;
|
||||
using Poco::Net::HTTPServer;
|
||||
using Poco::Net::HTTPServerRequest;
|
||||
using Poco::Net::HTTPResponse;
|
||||
using Poco::Net::HTTPServerResponse;
|
||||
using Poco::Net::HTTPServerParams;
|
||||
using Poco::JSON::Parser;
|
||||
|
||||
struct ConnectionState {
|
||||
uint64_t messages;
|
||||
std::string SerialNumber;
|
||||
std::string Address;
|
||||
uint64_t CfgUUID;
|
||||
uint64_t TX, RX;
|
||||
};
|
||||
|
||||
class uCentralWebSocketServer : public SubSystemServer {
|
||||
public:
|
||||
uCentralWebSocketServer() noexcept;
|
||||
|
||||
int start();
|
||||
void stop();
|
||||
|
||||
static uCentralWebSocketServer *instance() {
|
||||
if(instance_== nullptr) {
|
||||
instance_ = new uCentralWebSocketServer;
|
||||
}
|
||||
return instance_;
|
||||
}
|
||||
|
||||
std::string process_message(const std::string &message, ConnectionState &conn);
|
||||
|
||||
Logger & logger() { return SubSystemServer::logger(); };
|
||||
|
||||
private:
|
||||
static uCentralWebSocketServer * instance_;
|
||||
HTTPServer * server_;
|
||||
};
|
||||
|
||||
class PageRequestHandler: public HTTPRequestHandler
|
||||
/// Return a HTML document with some JavaScript creating
|
||||
/// a WebSocket connection.
|
||||
{
|
||||
public:
|
||||
void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response);
|
||||
};
|
||||
|
||||
class WebSocketRequestHandler: public HTTPRequestHandler
|
||||
/// Handle a WebSocket connection.
|
||||
{
|
||||
public:
|
||||
void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response);
|
||||
};
|
||||
|
||||
class RequestHandlerFactory: public HTTPRequestHandlerFactory
|
||||
{
|
||||
public:
|
||||
HTTPRequestHandler* createRequestHandler(const HTTPServerRequest& request);
|
||||
};
|
||||
|
||||
#endif //UCENTRAL_UCENTRALWEBSOCKETSERVER_H
|
||||
192
src/uStorageService.cpp
Normal file
192
src/uStorageService.cpp
Normal file
@@ -0,0 +1,192 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-03-01.
|
||||
//
|
||||
|
||||
#include "uStorageService.h"
|
||||
#include "Poco/Data/SQLite/Connector.h"
|
||||
#include "Poco/Data/RecordSet.h"
|
||||
#include "Poco/DateTime.h"
|
||||
|
||||
#include "uCentral.h"
|
||||
|
||||
using namespace Poco::Data::Keywords;
|
||||
using Poco::Data::Session;
|
||||
using Poco::Data::Statement;
|
||||
using Poco::Data::RecordSet;
|
||||
|
||||
uStorageService * uStorageService::instance_= nullptr;
|
||||
|
||||
uStorageService::uStorageService() noexcept:
|
||||
SubSystemServer("Storage","storage","storage")
|
||||
{
|
||||
}
|
||||
|
||||
int uStorageService::start() {
|
||||
|
||||
SubSystemServer::logger().information("Starting.");
|
||||
Poco::Data::SQLite::Connector::registerConnector();
|
||||
|
||||
std::string TableLocation = uCentral::instance().config().getString("sqlite.location") + "/devices.db";
|
||||
|
||||
session_ = std::shared_ptr<Poco::Data::Session>(new Poco::Data::Session("SQLite",TableLocation));
|
||||
|
||||
*session_ << "CREATE TABLE IF NOT EXISTS Statistics (SerialNumber VARCHAR(30), CfgUUID INTEGER, Stats BLOB, Recorded DATETIME)", now;
|
||||
*session_ << "CREATE INDEX IF NOT EXISTS serial ON Statistics (SerialNumber ASC, Recorded ASC)", now;
|
||||
|
||||
*session_ << "CREATE TABLE IF NOT EXISTS Devices (SerialNumber VARCHAR(30) UNIQUE PRIMARY KEY, MAC VARCHAR(30), CfgUUID INTEGER, Configuration BLOB, Created DATETIME, Updated DATETIME, LastDownloaded DATETIME ) WITHOUT ROWID" , now ;
|
||||
|
||||
*session_ << "CREATE TABLE IF NOT EXISTS Capabilities (SerialNumber VARCHAR(30) PRIMARY KEY, Capabilities BLOB, Created DATETIME, Updated DATETIME) WITHOUT ROWID" , now ;
|
||||
|
||||
Poco::Data::SQLite::Connector::registerConnector();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void uStorageService::stop() {
|
||||
SubSystemServer::logger().information("Stopping.");
|
||||
}
|
||||
|
||||
bool uStorageService::AddStatisticsData(std::string &SerialNumber, uint64_t CfgUUID, std::string &NewStats)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
|
||||
Poco::DateTime Now;
|
||||
*session_ << "INSERT INTO Statistics VALUES(?, ?, ?, ?)",
|
||||
use(SerialNumber),
|
||||
use(CfgUUID),
|
||||
use(NewStats),
|
||||
use(Now), now;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool uStorageService::GetStatisticsData(std::string &SerialNumber, uint32_t From, uint32_t To, std::vector<uCentralStatistics> &Stats)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool uStorageService::UpdateDeviceConfiguration(std::string &SerialNumber, std::string &Configuration ){
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool uStorageService::CreateDevice(uCentralDevice & DeviceDetails){
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
|
||||
std::string SerialNumber;
|
||||
|
||||
*session_ << "SELECT SerialNumber FROM Devices WHERE SerialNumber=?" ,
|
||||
into(SerialNumber),
|
||||
use(DeviceDetails.SerialNumber), now;
|
||||
|
||||
if(SerialNumber.empty())
|
||||
{
|
||||
*session_ << "INSERT INTO Devices VALUES(?, ?, ?, ?, ?, ?, ?)",
|
||||
use(DeviceDetails.SerialNumber),
|
||||
use(DeviceDetails.MAC),
|
||||
use(DeviceDetails.UUID),
|
||||
use(DeviceDetails.Configuration),
|
||||
use(DeviceDetails.CreationTimestamp),
|
||||
use(DeviceDetails.ModifiedTimestamp),
|
||||
use(DeviceDetails.LastDownloadTimeStamp), now;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool uStorageService::DeleteDevice(std::string &SerialNumber){
|
||||
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
|
||||
*session_ << "DELETE FROM Devices WHERE SerialNumber=?",
|
||||
use(SerialNumber), now;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool uStorageService::GetDevice(std::string &SerialNUmber, uCentralDevice &DeviceDetails)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
|
||||
*session_ << "SELECT SerialNumber, MAC, CfgUUID, Configuration, Created, Updated, LastDownloaded FROM Devices WHERE SerialNumber=?" ,
|
||||
into(DeviceDetails.SerialNumber),
|
||||
into(DeviceDetails.MAC),
|
||||
into(DeviceDetails.UUID),
|
||||
into(DeviceDetails.Configuration),
|
||||
into(DeviceDetails.CreationTimestamp),
|
||||
into(DeviceDetails.ModifiedTimestamp),
|
||||
into(DeviceDetails.LastDownloadTimeStamp),
|
||||
use(SerialNUmber), now;
|
||||
|
||||
if(DeviceDetails.SerialNumber.empty())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool uStorageService::UpdateDeviceCapabilities(std::string &SerialNumber, std::string &Capabs)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
|
||||
std::string SS;
|
||||
|
||||
*session_ << "SELECT SerialNumber FROM Capabilities WHERE SerialNumber=?" , into(SS), use(SerialNumber),now ;
|
||||
|
||||
Poco::DateTime Now;
|
||||
|
||||
if(SS.empty()) {
|
||||
std::cout << "Adding capabilities for " << SerialNumber << std::endl;
|
||||
*session_ << "INSERT INTO Capabilities VALUES(?, ?, ?, ?)" ,
|
||||
use(SerialNumber),
|
||||
use(Capabs),
|
||||
use(Now),
|
||||
use(Now), now;
|
||||
std::cout << "Done adding capabilities for " << SerialNumber << std::endl;
|
||||
}
|
||||
else {
|
||||
std::cout << "Updating capabilities for " << SerialNumber << std::endl;
|
||||
*session_ << "UPDATE Capabilities SET Capabilities=?, Updated=? WHERE SerialNumber=?" ,
|
||||
use(Capabs),
|
||||
use(Now),
|
||||
use(SerialNumber), now;
|
||||
std::cout << "Done updating capabilities for " << SerialNumber << std::endl;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool uStorageService::GetDeviceCapabilities(std::string &SerialNUmber, uCentralCapabilities & Caps)
|
||||
{
|
||||
*session_ << "SELECT SerialNumber, Capabilities, Created, Updated FROM Capabilities WHERE SerialNumber=?" ,
|
||||
into(Caps.SerialNumber),
|
||||
into(Caps.Caps),
|
||||
into(Caps.CreationTimestamp),
|
||||
into(Caps.LastUpdatedTimestamp),
|
||||
use(SerialNUmber), now;
|
||||
|
||||
if(Caps.SerialNumber.empty())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool uStorageService::NewerConfiguration(std::string &SerialNumber, uint64_t CurrentConfig, std::string &NewConfig, uint64_t & UUID){
|
||||
|
||||
std::lock_guard<std::mutex> guard(mutex_);
|
||||
|
||||
std::string SS;
|
||||
|
||||
*session_ << "SELECT SerialNumber, CfgUUID, Configuration FROM Capabilities WHERE SerialNumber=?" ,
|
||||
into(SS),
|
||||
into(UUID),
|
||||
into(NewConfig),
|
||||
use(SerialNumber),now ;
|
||||
|
||||
if(SS.empty() || CurrentConfig >= UUID)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
74
src/uStorageService.h
Normal file
74
src/uStorageService.h
Normal file
@@ -0,0 +1,74 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-03-01.
|
||||
//
|
||||
|
||||
#ifndef UCENTRAL_USTORAGESERVICE_H
|
||||
#define UCENTRAL_USTORAGESERVICE_H
|
||||
|
||||
#include "SubSystemServer.h"
|
||||
|
||||
#include "Poco/Data/Session.h"
|
||||
#include "Poco/Data/SQLite/SQLite.h"
|
||||
|
||||
struct uCentralDevice {
|
||||
std::string SerialNumber;
|
||||
std::string MAC;
|
||||
uint64_t UUID;
|
||||
std::string Configuration;
|
||||
uint64_t CreationTimestamp;
|
||||
uint64_t ModifiedTimestamp;
|
||||
uint64_t LastDownloadTimeStamp;
|
||||
};
|
||||
|
||||
struct uCentralStatistics {
|
||||
std::string SerialNumber;
|
||||
uint64_t UUID;
|
||||
std::string StatsRecord;
|
||||
uint64_t CreationTimestamp;
|
||||
};
|
||||
|
||||
struct uCentralCapabilities {
|
||||
std::string SerialNumber;
|
||||
std::string Caps;
|
||||
uint64_t CreationTimestamp;
|
||||
uint64_t LastUpdatedTimestamp;
|
||||
};
|
||||
|
||||
class uStorageService : public SubSystemServer {
|
||||
|
||||
public:
|
||||
uStorageService() noexcept;
|
||||
|
||||
int start();
|
||||
void stop();
|
||||
|
||||
Logger & logger() { return SubSystemServer::logger(); };
|
||||
|
||||
bool AddStatisticsData(std::string &SerialNUmber, uint64_t CfgUUID, std::string &NewStats);
|
||||
bool GetStatisticsData(std::string &SerialNUmber, uint32_t From, uint32_t To, std::vector<uCentralStatistics> &Stats);
|
||||
|
||||
bool UpdateDeviceConfiguration(std::string &SerialNUmber, std::string &Configuration );
|
||||
bool CreateDevice(uCentralDevice &);
|
||||
bool GetDevice(std::string &SerialNUmber, uCentralDevice & );
|
||||
bool DeleteDevice(std::string &SerialNUmber);
|
||||
bool UpdateDevice(uCentralDevice &);
|
||||
bool NewerConfiguration(std::string &SerialNumber, uint64_t CurrentConfig, std::string &NewConfig, uint64_t &);
|
||||
|
||||
bool UpdateDeviceCapabilities(std::string &SerialNUmber, std::string &State );
|
||||
bool GetDeviceCapabilities(std::string &SerialNUmber, uCentralCapabilities & );
|
||||
|
||||
static uStorageService *instance() {
|
||||
if(instance_== nullptr) {
|
||||
instance_ = new uStorageService;
|
||||
}
|
||||
return instance_;
|
||||
}
|
||||
|
||||
private:
|
||||
static uStorageService *instance_;
|
||||
std::shared_ptr<Poco::Data::Session> session_;
|
||||
std::mutex mutex_;
|
||||
};
|
||||
|
||||
|
||||
#endif //UCENTRAL_USTORAGESERVICE_H
|
||||
@@ -1,28 +0,0 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-02-12.
|
||||
//
|
||||
#include "ucentralServer.h"
|
||||
#include "common.h"
|
||||
|
||||
UCentralGW::UCentralGW(): helpRequested_(false)
|
||||
{
|
||||
}
|
||||
|
||||
void UCentralGW::initialize(Application & self)
|
||||
{
|
||||
}
|
||||
|
||||
void UCentralGW::uninitialize()
|
||||
{
|
||||
// add your own uninitialization code here
|
||||
}
|
||||
|
||||
void UCentralGW::reinitialize(Application & self)
|
||||
{
|
||||
// add your own reinitialization code here
|
||||
}
|
||||
|
||||
void UCentralGW::defineOptions(OptionSet& options)
|
||||
{
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user