mirror of
https://github.com/Telecominfraproject/wlan-cloud-ucentralgw.git
synced 2025-11-02 03:37:57 +00:00
Compare commits
21 Commits
release_v3
...
bug-WIFI-1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f52e493525 | ||
|
|
be6c09886a | ||
|
|
242261de0a | ||
|
|
31a4edead5 | ||
|
|
f7b697f219 | ||
|
|
e020da75fc | ||
|
|
89702f56e0 | ||
|
|
0ac97442c0 | ||
|
|
e38b4c8a13 | ||
|
|
9c5bbee834 | ||
|
|
a5d1eebe6d | ||
|
|
ee14f064c8 | ||
|
|
dbf52c1f23 | ||
|
|
9dc6a6bf97 | ||
|
|
1c0556f8bf | ||
|
|
d298139525 | ||
|
|
a37c961f5b | ||
|
|
75bcbd748c | ||
|
|
b6eba2a96d | ||
|
|
17082803d4 | ||
|
|
26b9a96506 |
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@@ -21,7 +21,7 @@ defaults:
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
DOCKER_REGISTRY_URL: tip-tip-wlan-cloud-ucentral.jfrog.io
|
||||
DOCKER_REGISTRY_USERNAME: ucentral
|
||||
|
||||
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -11,7 +11,7 @@ defaults:
|
||||
|
||||
jobs:
|
||||
helm-package:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
HELM_REPO_URL: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/
|
||||
HELM_REPO_USERNAME: ucentral
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -29,4 +29,4 @@ helm/charts/*
|
||||
!helm/charts/.gitkeep
|
||||
/portal-test/
|
||||
/src/ow_version.h
|
||||
|
||||
.vscode/*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
project(owgw VERSION 3.2.1)
|
||||
project(owgw VERSION 4.1.0)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
|
||||
26
PROTOCOL.md
26
PROTOCOL.md
@@ -880,6 +880,32 @@ The device should answer:
|
||||
}
|
||||
```
|
||||
|
||||
#### Controller wants the device to perform re-enrollment
|
||||
Controller sends this command to trigger re-enrollment, i.e. update of operational certificate. Extreme care must be taken.
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"method" : "reenroll" ,
|
||||
"params" : {
|
||||
"serial" : <serial number>,
|
||||
"when" : Optional - <UTC time when to apply this config, 0 mean immediate, this is a suggestion>
|
||||
},
|
||||
"id" : <some number>
|
||||
}
|
||||
```
|
||||
|
||||
The device should answer:
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"result" : {
|
||||
"serial" : <serial number> ,
|
||||
"status" : {
|
||||
"error" : <0 or the value of $? from the shell running the command, 255 signifies a timeout>,
|
||||
"txt" : <text describing the error or success>
|
||||
},
|
||||
"id" : <same number as request>
|
||||
}
|
||||
```
|
||||
|
||||
#### Controller wants the device to switch to another controller
|
||||
Controller sends this when the device should change the controller it connects to without looking up a new redirector.
|
||||
|
||||
|
||||
@@ -1600,6 +1600,77 @@ components:
|
||||
maximum: 60000
|
||||
description: off time in milliseconds
|
||||
|
||||
PackageGetResponse:
|
||||
type: object
|
||||
properties:
|
||||
serial:
|
||||
type: string
|
||||
status:
|
||||
type: object
|
||||
properties:
|
||||
packages:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
version:
|
||||
type: string
|
||||
|
||||
|
||||
PackageInstallRequest:
|
||||
type: object
|
||||
properties:
|
||||
serialNumber:
|
||||
type: string
|
||||
packages:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
url:
|
||||
type: string
|
||||
|
||||
PackageInstallResponse:
|
||||
type: object
|
||||
properties:
|
||||
serial:
|
||||
type: string
|
||||
status:
|
||||
type: object
|
||||
properties:
|
||||
error:
|
||||
type: number
|
||||
packages:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
result:
|
||||
type: string
|
||||
text:
|
||||
type: string
|
||||
uuid:
|
||||
type: number
|
||||
|
||||
PackageRemoveRequest:
|
||||
type: object
|
||||
properties:
|
||||
serialNumber:
|
||||
type: string
|
||||
packages:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
|
||||
paths:
|
||||
/devices:
|
||||
get:
|
||||
@@ -3084,6 +3155,92 @@ paths:
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/device/{serialNumber}/package:
|
||||
get:
|
||||
tags:
|
||||
- Commands
|
||||
summary: Get package installed on the remote device.
|
||||
operationId: getDevicePackages
|
||||
parameters:
|
||||
- in: path
|
||||
name: serialNumber
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
responses:
|
||||
200:
|
||||
description: Successful command execution
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PackageGetResponse'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
post:
|
||||
tags:
|
||||
- Commands
|
||||
summary: Install IPK files to remote device.
|
||||
operationId: postDevicePackages
|
||||
parameters:
|
||||
- in: path
|
||||
name: serialNumber
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
requestBody:
|
||||
description: Packages to be installed
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PackageInstallRequest'
|
||||
responses:
|
||||
200:
|
||||
description: Successful command execution
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PackageInstallResponse'
|
||||
|
||||
400:
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
delete:
|
||||
tags:
|
||||
- Commands
|
||||
summary: Remove install packages from remote device.
|
||||
operationId: deleteDevicePackages
|
||||
parameters:
|
||||
- in: path
|
||||
name: serialNumber
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
requestBody:
|
||||
description: Packages to be removed
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PackageRemoveRequest'
|
||||
responses:
|
||||
200:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PackageInstallResponse'
|
||||
400:
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/ouis:
|
||||
get:
|
||||
tags:
|
||||
|
||||
@@ -213,6 +213,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
State_.certificateExpiryDate = PeerCert.expiresOn().timestamp().epochTime();
|
||||
State_.certificateIssuerName = PeerCert.issuerName();
|
||||
|
||||
poco_trace(Logger_,
|
||||
fmt::format("TLS-CONNECTION({}): Session={} CN={} Completed. (t={})", CId_,
|
||||
|
||||
@@ -105,7 +105,7 @@ namespace OpenWifi {
|
||||
Restrictions_.developer = Capabilities->getValue<bool>("developer");
|
||||
}
|
||||
|
||||
if(Capabilities->has("secure-rtty")) {
|
||||
if (Capabilities->has("secure-rtty")) {
|
||||
RTTYMustBeSecure_ = Capabilities->getValue<bool>("secure-rtty");
|
||||
}
|
||||
|
||||
|
||||
@@ -71,14 +71,18 @@ namespace OpenWifi {
|
||||
bool AP_WS_Server::ValidateCertificate(const std::string &ConnectionId,
|
||||
const Poco::Crypto::X509Certificate &Certificate) {
|
||||
if (IsCertOk()) {
|
||||
if (!Certificate.issuedBy(*IssuerCert_)) {
|
||||
poco_warning(
|
||||
Logger(),
|
||||
fmt::format("CERTIFICATE({}): issuer mismatch. Local='{}' Incoming='{}'",
|
||||
ConnectionId, IssuerCert_->issuerName(), Certificate.issuerName()));
|
||||
return false;
|
||||
// validate certificate agains trusted chain
|
||||
for (const auto &cert : ClientCasCerts_) {
|
||||
if (Certificate.issuedBy(cert)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
poco_warning(
|
||||
Logger(),
|
||||
fmt::format(
|
||||
"CERTIFICATE({}): issuer mismatch. Certificate not issued by any trusted CA",
|
||||
ConnectionId)
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -133,6 +137,13 @@ namespace OpenWifi {
|
||||
Context->addChainCertificate(Issuing);
|
||||
Context->addCertificateAuthority(Issuing);
|
||||
|
||||
// add certificates from clientcas to trust chain
|
||||
ClientCasCerts_ = Poco::Net::X509Certificate::readPEM(Svr.ClientCas());
|
||||
for (const auto &cert : ClientCasCerts_) {
|
||||
Context->addChainCertificate(cert);
|
||||
Context->addCertificateAuthority(cert);
|
||||
}
|
||||
|
||||
Poco::Crypto::RSAKey Key("", Svr.KeyFile(), Svr.KeyFilePassword());
|
||||
Context->usePrivateKey(Key);
|
||||
|
||||
|
||||
@@ -223,6 +223,7 @@ namespace OpenWifi {
|
||||
mutable std::array<std::mutex,MACHashMax> SerialNumbersMutex_;
|
||||
|
||||
std::unique_ptr<Poco::Crypto::X509Certificate> IssuerCert_;
|
||||
std::vector<Poco::Crypto::X509Certificate> ClientCasCerts_;
|
||||
std::list<std::unique_ptr<Poco::Net::HTTPServer>> WebServers_;
|
||||
Poco::ThreadPool DeviceConnectionPool_{"ws:dev-pool", 4, 256};
|
||||
Poco::Net::SocketReactor Reactor_;
|
||||
|
||||
@@ -111,7 +111,7 @@ namespace OpenWifi {
|
||||
i >> cache;
|
||||
|
||||
for (const auto &[Type, Platform] : cache.items()) {
|
||||
Platforms_[Type] = Poco::toLower(to_string(Platform));
|
||||
Platforms_[Type] = Poco::toLower(Platform.get<std::string>());
|
||||
}
|
||||
} catch (...) {
|
||||
}
|
||||
|
||||
@@ -91,6 +91,21 @@ namespace OpenWifi {
|
||||
TransactionId_, UUID, RPC, Poco::Thread::current()->id()));
|
||||
return Rtty(UUID, RPC, 60000ms, Restrictions);
|
||||
};
|
||||
case APCommands::Commands::package:{
|
||||
GWObjects::DeviceRestrictions Restrictions;
|
||||
if (!AP_WS_Server()->Connected(SerialNumberInt_, Restrictions)) {
|
||||
CallCanceled(Command_.c_str(), RESTAPI::Errors::DeviceNotConnected);
|
||||
return BadRequest(RESTAPI::Errors::DeviceNotConnected);
|
||||
}
|
||||
auto UUID = MicroServiceCreateUUID();
|
||||
auto RPC = CommandManager()->Next_RPC_ID();
|
||||
poco_debug(
|
||||
Logger_,
|
||||
fmt::format(
|
||||
"Command RTTY TID={} can proceed. Identified as {} and RPCID as {}. thr_id={}",
|
||||
TransactionId_, UUID, RPC, Poco::Thread::current()->id()));
|
||||
return GetPackages(UUID, RPC, 300000ms, Restrictions);
|
||||
}
|
||||
default:
|
||||
return BadRequest(RESTAPI::Errors::InvalidCommand);
|
||||
}
|
||||
@@ -128,6 +143,21 @@ namespace OpenWifi {
|
||||
return DeleteChecks();
|
||||
case APCommands::Commands::statistics:
|
||||
return DeleteStatistics();
|
||||
case APCommands::Commands::package: {
|
||||
GWObjects::DeviceRestrictions Restrictions;
|
||||
if (!AP_WS_Server()->Connected(SerialNumberInt_, Restrictions)) {
|
||||
CallCanceled(Command_.c_str(), RESTAPI::Errors::DeviceNotConnected);
|
||||
return BadRequest(RESTAPI::Errors::DeviceNotConnected);
|
||||
}
|
||||
auto UUID = MicroServiceCreateUUID();
|
||||
auto RPC = CommandManager()->Next_RPC_ID();
|
||||
poco_debug(
|
||||
Logger_,
|
||||
fmt::format(
|
||||
"Command RTTY TID={} can proceed. Identified as {} and RPCID as {}. thr_id={}",
|
||||
TransactionId_, UUID, RPC, Poco::Thread::current()->id()));
|
||||
return DeletePackages(UUID, RPC, 300000ms, Restrictions);
|
||||
}
|
||||
default:
|
||||
return BadRequest(RESTAPI::Errors::InvalidCommand);
|
||||
}
|
||||
@@ -170,7 +200,8 @@ namespace OpenWifi {
|
||||
{APCommands::Commands::powercycle, false, true, &RESTAPI_device_commandHandler::PowerCycle, 60000ms},
|
||||
{APCommands::Commands::fixedconfig, false, true, &RESTAPI_device_commandHandler::FixedConfig, 120000ms},
|
||||
{APCommands::Commands::cablediagnostics, false, true, &RESTAPI_device_commandHandler::CableDiagnostics, 120000ms},
|
||||
|
||||
{APCommands::Commands::reenroll, false, true, &RESTAPI_device_commandHandler::ReEnroll, 120000ms},
|
||||
{APCommands::Commands::package, false, true, &RESTAPI_device_commandHandler::PackageInstall, 120000ms},
|
||||
};
|
||||
|
||||
void RESTAPI_device_commandHandler::DoPost() {
|
||||
@@ -408,6 +439,265 @@ namespace OpenWifi {
|
||||
BadRequest(RESTAPI::Errors::NoRecordsDeleted);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::GetPackages(const std::string &CMD_UUID, uint64_t CMD_RPC,
|
||||
[[maybe_unused]] std::chrono::milliseconds timeout,
|
||||
[[maybe_unused]] const GWObjects::DeviceRestrictions &Restrictions) {
|
||||
poco_debug(Logger_, fmt::format("GET-PACKAGES({},{}): TID={} user={} serial={}. thr_id={}",
|
||||
TransactionId_, Requester(), SerialNumber_,
|
||||
Poco::Thread::current()->id()));
|
||||
|
||||
if (IsDeviceSimulated(SerialNumber_)) {
|
||||
return BadRequest(RESTAPI::Errors::SimulatedDeviceNotSupported);
|
||||
}
|
||||
|
||||
Poco::JSON::Object Params;
|
||||
Params.set(uCentralProtocol::OPERATION, "list");
|
||||
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
|
||||
|
||||
std::stringstream ParamStream;
|
||||
Params.stringify(ParamStream);
|
||||
|
||||
poco_information(Logger_, fmt::format("GET_OBJECT: {} for device {}", ParamStream.str(), SerialNumber_));
|
||||
|
||||
GWObjects::CommandDetails Cmd;
|
||||
Cmd.SerialNumber = SerialNumber_;
|
||||
Cmd.UUID = CMD_UUID;
|
||||
Cmd.SubmittedBy = Requester();
|
||||
Cmd.Command = uCentralProtocol::PACKAGE;
|
||||
Cmd.RunAt = 0;
|
||||
Cmd.Details = ParamStream.str();
|
||||
|
||||
RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::package, false, Cmd, Params,
|
||||
*Request, *Response, timeout, nullptr, nullptr, Logger_);
|
||||
|
||||
Poco::JSON::Object O, P;
|
||||
Cmd.to_json(O);
|
||||
|
||||
Poco::Dynamic::Var resultsVar = O.get("results");
|
||||
Poco::JSON::Object::Ptr resultsObj = resultsVar.extract<Poco::JSON::Object::Ptr>();
|
||||
Poco::JSON::Object::Ptr packages;
|
||||
|
||||
std::string UncompressedData;
|
||||
try {
|
||||
if (resultsObj->has("status")) {
|
||||
Poco::Dynamic::Var statusVar = resultsObj->get("status");
|
||||
Poco::JSON::Object::Ptr statusObj = statusVar.extract<Poco::JSON::Object::Ptr>();
|
||||
|
||||
if (statusObj->has(uCentralProtocol::COMPRESS_64)) {
|
||||
auto CompressedData = statusObj->get(uCentralProtocol::COMPRESS_64).toString();
|
||||
uint64_t compress_sz = 0;
|
||||
if (statusObj->has("compress_sz")) {
|
||||
compress_sz = statusObj->get("compress_sz").convert<uint64_t>();
|
||||
}
|
||||
|
||||
if (Utils::ExtractBase64CompressedData(CompressedData, UncompressedData, compress_sz)) {
|
||||
poco_information(Logger_,
|
||||
fmt::format("EVENT: Found compressed payload expanded to '{}'.",
|
||||
UncompressedData));
|
||||
Poco::JSON::Parser Parser;
|
||||
packages = Parser.parse(UncompressedData).extract<Poco::JSON::Object::Ptr>();
|
||||
} else {
|
||||
poco_warning(Logger_,
|
||||
fmt::format("INVALID-COMPRESSED-DATA: Cannot decompress data - content may be corrupt: size={}",
|
||||
CompressedData.size()));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
poco_trace(Logger_, "No compressed data found in status.");
|
||||
}
|
||||
} else {
|
||||
poco_warning(Logger_, "No status object found in results.");
|
||||
return;
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
poco_warning(Logger_,
|
||||
fmt::format("INVALID-COMPRESSED-JSON-DATA: Failed to parse compressed data: {}",
|
||||
E.displayText()));
|
||||
Logger_.log(E);
|
||||
return;
|
||||
} catch (const std::exception &E) {
|
||||
poco_warning(Logger_,
|
||||
fmt::format("INVALID-COMPRESSED-JSON-DATA: Unexpected error: {}",
|
||||
E.what()));
|
||||
return;
|
||||
}
|
||||
|
||||
if (resultsObj->has("status")) {
|
||||
Poco::Dynamic::Var statusVar = resultsObj->get("status");
|
||||
Poco::JSON::Object::Ptr statusObj = statusVar.extract<Poco::JSON::Object::Ptr>();
|
||||
statusObj->remove("compress_sz");
|
||||
statusObj->remove("compress_64");
|
||||
}
|
||||
|
||||
resultsObj->set("packages", packages->get("packages"));
|
||||
|
||||
return ReturnObject(*resultsObj);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::PackageInstall(
|
||||
const std::string &CMD_UUID, uint64_t CMD_RPC,
|
||||
[[maybe_unused]] std::chrono::milliseconds timeout,
|
||||
[[maybe_unused]] const GWObjects::DeviceRestrictions &Restrictions) {
|
||||
|
||||
if (UserInfo_.userinfo.userRole != SecurityObjects::ROOT &&
|
||||
UserInfo_.userinfo.userRole != SecurityObjects::ADMIN) {
|
||||
CallCanceled("INSTALLPACKAGE", CMD_UUID, CMD_RPC, RESTAPI::Errors::ACCESS_DENIED);
|
||||
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
|
||||
}
|
||||
|
||||
poco_debug(Logger_, fmt::format("INSTALL-PACKAGES({},{}): TID={} user={} serial={}", CMD_UUID,
|
||||
CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
|
||||
if (IsDeviceSimulated(SerialNumber_)) {
|
||||
CallCanceled("INSTALL-PACKAGES", CMD_UUID, CMD_RPC, RESTAPI::Errors::SimulatedDeviceNotSupported);
|
||||
return BadRequest(RESTAPI::Errors::SimulatedDeviceNotSupported);
|
||||
}
|
||||
|
||||
const auto &Obj = ParsedBody_;
|
||||
if (!Obj->has(RESTAPI::Protocol::SERIALNUMBER)) {
|
||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||
if (SerialNumber_ != SNum) {
|
||||
CallCanceled("INSTALL-PACKAGES", CMD_UUID, CMD_RPC, RESTAPI::Errors::SerialNumberMismatch);
|
||||
return BadRequest(RESTAPI::Errors::SerialNumberMismatch);
|
||||
}
|
||||
|
||||
std::ostringstream os;
|
||||
ParsedBody_->stringify(os);
|
||||
|
||||
poco_information(Logger_, fmt::format("INSTALL_OBJECT: {} for device {}", os.str(), SerialNumber_));
|
||||
|
||||
GWObjects::PackageInstall PI;
|
||||
if (!PI.from_json(ParsedBody_)) {
|
||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
Poco::JSON::Array::Ptr ArrayObj = Poco::SharedPtr<Poco::JSON::Array>(new Poco::JSON::Array);
|
||||
for (const auto &i : PI.pkgs) {
|
||||
Poco::JSON::Object::Ptr Obj =
|
||||
Poco::SharedPtr<Poco::JSON::Object>(new Poco::JSON::Object);
|
||||
i.to_json(*Obj);
|
||||
ArrayObj->add(Obj);
|
||||
}
|
||||
|
||||
Poco::JSON::Object Params;
|
||||
Params.set(uCentralProtocol::OPERATION, "install");
|
||||
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentralProtocol::PACKAGES, ArrayObj);
|
||||
|
||||
std::ostringstream os2;
|
||||
Params.stringify(os2);
|
||||
|
||||
poco_information(Logger_, fmt::format("INSTALL_OBJECT2: {} for device {}", os2.str(), SerialNumber_));
|
||||
|
||||
|
||||
std::stringstream ParamStream;
|
||||
Params.stringify(ParamStream);
|
||||
|
||||
GWObjects::CommandDetails Cmd;
|
||||
Cmd.SerialNumber = SerialNumber_;
|
||||
Cmd.UUID = CMD_UUID;
|
||||
Cmd.SubmittedBy = Requester();
|
||||
Cmd.Command = uCentralProtocol::PACKAGE;
|
||||
Cmd.RunAt = 0;
|
||||
Cmd.Details = ParamStream.str();
|
||||
|
||||
RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::package, false, Cmd, Params,
|
||||
*Request, *Response, timeout, nullptr, nullptr, Logger_);
|
||||
|
||||
Poco::JSON::Object O, P;
|
||||
Cmd.to_json(O);
|
||||
|
||||
Poco::Dynamic::Var resultsVar = O.get("results");
|
||||
Poco::JSON::Object::Ptr resultsObj = resultsVar.extract<Poco::JSON::Object::Ptr>();
|
||||
|
||||
return ReturnObject(*resultsObj);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::DeletePackages(
|
||||
const std::string &CMD_UUID, uint64_t CMD_RPC,
|
||||
[[maybe_unused]] std::chrono::milliseconds timeout,
|
||||
[[maybe_unused]] const GWObjects::DeviceRestrictions &Restrictions) {
|
||||
|
||||
if (UserInfo_.userinfo.userRole != SecurityObjects::ROOT &&
|
||||
UserInfo_.userinfo.userRole != SecurityObjects::ADMIN) {
|
||||
CallCanceled("DELETE-PACKAGES", CMD_UUID, CMD_RPC, RESTAPI::Errors::ACCESS_DENIED);
|
||||
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
|
||||
}
|
||||
|
||||
poco_debug(Logger_, fmt::format("DELETE-PACKAGES({},{}): TID={} user={} serial={}", CMD_UUID,
|
||||
CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
|
||||
if (IsDeviceSimulated(SerialNumber_)) {
|
||||
CallCanceled("DELETE-PACKAGES", CMD_UUID, CMD_RPC, RESTAPI::Errors::SimulatedDeviceNotSupported);
|
||||
return BadRequest(RESTAPI::Errors::SimulatedDeviceNotSupported);
|
||||
}
|
||||
|
||||
const auto &Obj = ParsedBody_;
|
||||
if (!Obj->has(RESTAPI::Protocol::SERIALNUMBER)) {
|
||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||
if (SerialNumber_ != SNum) {
|
||||
CallCanceled("DELETE-PACKAGES", CMD_UUID, CMD_RPC, RESTAPI::Errors::SerialNumberMismatch);
|
||||
return BadRequest(RESTAPI::Errors::SerialNumberMismatch);
|
||||
}
|
||||
|
||||
std::ostringstream os;
|
||||
ParsedBody_->stringify(os);
|
||||
|
||||
poco_information(Logger_, fmt::format("DELETE_OBJECT: {} for device {}", os.str(), SerialNumber_));
|
||||
|
||||
GWObjects::PackageRemove PR;
|
||||
if (!PR.from_json(ParsedBody_)) {
|
||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
Poco::JSON::Array::Ptr ArrayObj = Poco::SharedPtr<Poco::JSON::Array>(new Poco::JSON::Array);
|
||||
for (const auto &i : PR.pkgs) {
|
||||
Poco::JSON::Object::Ptr Obj =
|
||||
Poco::SharedPtr<Poco::JSON::Object>(new Poco::JSON::Object);
|
||||
i.to_json(*Obj);
|
||||
ArrayObj->add(Obj);
|
||||
}
|
||||
|
||||
Poco::JSON::Object Params;
|
||||
Params.set(uCentralProtocol::OPERATION, "delete");
|
||||
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentralProtocol::PACKAGES, ArrayObj);
|
||||
|
||||
std::ostringstream os2;
|
||||
Params.stringify(os2);
|
||||
|
||||
poco_information(Logger_, fmt::format("DELETE_OBJECT2: {} for device {}", os2.str(), SerialNumber_));
|
||||
|
||||
|
||||
std::stringstream ParamStream;
|
||||
Params.stringify(ParamStream);
|
||||
|
||||
GWObjects::CommandDetails Cmd;
|
||||
Cmd.SerialNumber = SerialNumber_;
|
||||
Cmd.UUID = CMD_UUID;
|
||||
Cmd.SubmittedBy = Requester();
|
||||
Cmd.Command = uCentralProtocol::PACKAGE;
|
||||
Cmd.RunAt = 0;
|
||||
Cmd.Details = ParamStream.str();
|
||||
|
||||
RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::package, false, Cmd, Params,
|
||||
*Request, *Response, timeout, nullptr, nullptr, Logger_);
|
||||
|
||||
Poco::JSON::Object O, P;
|
||||
Cmd.to_json(O);
|
||||
|
||||
Poco::Dynamic::Var resultsVar = O.get("results");
|
||||
Poco::JSON::Object::Ptr resultsObj = resultsVar.extract<Poco::JSON::Object::Ptr>();
|
||||
|
||||
return ReturnObject(*resultsObj);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::Ping(
|
||||
const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout,
|
||||
[[maybe_unused]] const GWObjects::DeviceRestrictions &Restrictions) {
|
||||
@@ -1651,4 +1941,45 @@ namespace OpenWifi {
|
||||
*ParsedBody_, *Request, *Response, timeout, nullptr, this,
|
||||
Logger_);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::ReEnroll(
|
||||
const std::string &CMD_UUID, uint64_t CMD_RPC,
|
||||
[[maybe_unused]] std::chrono::milliseconds timeout,
|
||||
[[maybe_unused]] const GWObjects::DeviceRestrictions &Restrictions) {
|
||||
|
||||
if(UserInfo_.userinfo.userRole != SecurityObjects::ROOT &&
|
||||
UserInfo_.userinfo.userRole != SecurityObjects::ADMIN) {
|
||||
CallCanceled("REENROLL", CMD_UUID, CMD_RPC, RESTAPI::Errors::ACCESS_DENIED);
|
||||
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
|
||||
}
|
||||
|
||||
poco_debug(Logger_, fmt::format("REENROLL({},{}): TID={} user={} serial={}", CMD_UUID,
|
||||
CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
|
||||
if(IsDeviceSimulated(SerialNumber_)) {
|
||||
CallCanceled("REENROLL", CMD_UUID, CMD_RPC, RESTAPI::Errors::SimulatedDeviceNotSupported);
|
||||
return BadRequest(RESTAPI::Errors::SimulatedDeviceNotSupported);
|
||||
}
|
||||
|
||||
GWObjects::ReEnroll PR;
|
||||
if(!PR.from_json(ParsedBody_)) {
|
||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
GWObjects::CommandDetails Cmd;
|
||||
Cmd.SerialNumber = SerialNumber_;
|
||||
Cmd.SubmittedBy = Requester();
|
||||
Cmd.UUID = CMD_UUID;
|
||||
Cmd.Command = uCentralProtocol::REENROLL;
|
||||
std::ostringstream os;
|
||||
ParsedBody_->stringify(os);
|
||||
Cmd.Details = os.str();
|
||||
Cmd.RunAt = PR.when;
|
||||
Cmd.ErrorCode = 0;
|
||||
Cmd.WaitingForFile = 0;
|
||||
|
||||
return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::reenroll, false, Cmd,
|
||||
*ParsedBody_, *Request, *Response, timeout, nullptr, this,
|
||||
Logger_);
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -33,6 +33,10 @@ namespace OpenWifi {
|
||||
void GetStatus();
|
||||
void GetChecks();
|
||||
void DeleteChecks();
|
||||
void GetPackages(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout,
|
||||
const GWObjects::DeviceRestrictions &R);
|
||||
void DeletePackages(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout,
|
||||
const GWObjects::DeviceRestrictions &R);
|
||||
|
||||
bool IsDeviceSimulated(std::string &Serial);
|
||||
|
||||
@@ -74,6 +78,10 @@ namespace OpenWifi {
|
||||
const GWObjects::DeviceRestrictions &R);
|
||||
void CableDiagnostics(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout,
|
||||
const GWObjects::DeviceRestrictions &R);
|
||||
void ReEnroll(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout,
|
||||
const GWObjects::DeviceRestrictions &R);
|
||||
void PackageInstall(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout,
|
||||
const GWObjects::DeviceRestrictions &R);
|
||||
|
||||
static auto PathName() {
|
||||
return std::list<std::string>{"/api/v1/device/{serialNumber}/{command}"};
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
#include "Daemon.h"
|
||||
#ifdef TIP_GATEWAY_SERVICE
|
||||
#include "AP_WS_Server.h"
|
||||
#include "StorageService.h"
|
||||
#include "CapabilitiesCache.h"
|
||||
#include "RADIUSSessionTracker.h"
|
||||
#include "StorageService.h"
|
||||
#endif
|
||||
|
||||
#include "RESTAPI_GWobjects.h"
|
||||
@@ -31,7 +31,8 @@ namespace OpenWifi::GWObjects {
|
||||
field_to_json(Obj, "serialNumber", SerialNumber);
|
||||
#ifdef TIP_GATEWAY_SERVICE
|
||||
field_to_json(Obj, "deviceType", StorageService()->GetPlatform(SerialNumber));
|
||||
field_to_json(Obj, "blackListed", StorageService()->IsBlackListed(Utils::MACToInt(SerialNumber)));
|
||||
field_to_json(Obj, "blackListed",
|
||||
StorageService()->IsBlackListed(Utils::MACToInt(SerialNumber)));
|
||||
#endif
|
||||
field_to_json(Obj, "macAddress", MACAddress);
|
||||
field_to_json(Obj, "manufacturer", Manufacturer);
|
||||
@@ -70,12 +71,12 @@ namespace OpenWifi::GWObjects {
|
||||
#ifdef TIP_GATEWAY_SERVICE
|
||||
ConnectionState ConState;
|
||||
#ifdef USE_MEDUSA_CLIENT
|
||||
auto Res = GS()->GetState(SerialNumber);
|
||||
if (Res.has_value()) {
|
||||
Res.value().to_json(SerialNumber,Obj);
|
||||
auto Res = GS()->GetState(SerialNumber);
|
||||
if (Res.has_value()) {
|
||||
Res.value().to_json(SerialNumber, Obj);
|
||||
#else
|
||||
if (AP_WS_Server()->GetState(SerialNumber, ConState)) {
|
||||
ConState.to_json(SerialNumber,Obj);
|
||||
if (AP_WS_Server()->GetState(SerialNumber, ConState)) {
|
||||
ConState.to_json(SerialNumber, Obj);
|
||||
#endif
|
||||
} else {
|
||||
field_to_json(Obj, "ipAddress", "");
|
||||
@@ -172,17 +173,16 @@ namespace OpenWifi::GWObjects {
|
||||
field_to_json(Obj, "recorded", Recorded);
|
||||
}
|
||||
|
||||
bool HealthCheck::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "UUID", UUID);
|
||||
field_from_json(Obj, "sanity", Sanity);
|
||||
field_from_json(Obj, "recorded", Recorded);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool HealthCheck::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "UUID", UUID);
|
||||
field_from_json(Obj, "sanity", Sanity);
|
||||
field_from_json(Obj, "recorded", Recorded);
|
||||
return true;
|
||||
} catch (...) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DefaultFirmware::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj, "deviceType", deviceType);
|
||||
@@ -275,7 +275,8 @@ namespace OpenWifi::GWObjects {
|
||||
return false;
|
||||
}
|
||||
|
||||
void ConnectionState::to_json([[maybe_unused]] const std::string &SerialNumber, Poco::JSON::Object &Obj) {
|
||||
void ConnectionState::to_json([[maybe_unused]] const std::string &SerialNumber,
|
||||
Poco::JSON::Object &Obj) {
|
||||
field_to_json(Obj, "ipAddress", Address);
|
||||
field_to_json(Obj, "txBytes", TX);
|
||||
field_to_json(Obj, "rxBytes", RX);
|
||||
@@ -297,14 +298,15 @@ namespace OpenWifi::GWObjects {
|
||||
field_to_json(Obj, "connectionCompletionTime", connectionCompletionTime);
|
||||
field_to_json(Obj, "totalConnectionTime", Utils::Now() - started);
|
||||
field_to_json(Obj, "certificateExpiryDate", certificateExpiryDate);
|
||||
field_to_json(Obj, "certificateIssuerName", certificateIssuerName);
|
||||
field_to_json(Obj, "connectReason", connectReason);
|
||||
field_to_json(Obj, "uptime", uptime);
|
||||
field_to_json(Obj, "compatible", Compatible);
|
||||
field_to_json(Obj, "compatible", Compatible);
|
||||
|
||||
#ifdef TIP_GATEWAY_SERVICE
|
||||
hasRADIUSSessions = RADIUSSessionTracker()->HasSessions(SerialNumber);
|
||||
#endif
|
||||
field_to_json(Obj, "hasRADIUSSessions", hasRADIUSSessions );
|
||||
field_to_json(Obj, "hasRADIUSSessions", hasRADIUSSessions);
|
||||
field_to_json(Obj, "hasGPS", hasGPS);
|
||||
field_to_json(Obj, "sanity", sanity);
|
||||
field_to_json(Obj, "memoryUsed", memoryUsed);
|
||||
@@ -334,44 +336,45 @@ namespace OpenWifi::GWObjects {
|
||||
}
|
||||
}
|
||||
|
||||
bool ConnectionState::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "compatible", Compatible);
|
||||
field_from_json(Obj, "ipAddress", Address);
|
||||
field_from_json(Obj, "txBytes", TX);
|
||||
field_from_json(Obj, "rxBytes", RX);
|
||||
field_from_json(Obj, "messageCount", MessageCount);
|
||||
field_from_json(Obj, "UUID", UUID);
|
||||
field_from_json(Obj, "connected", Connected);
|
||||
field_from_json(Obj, "firmware", Firmware);
|
||||
field_from_json(Obj, "lastContact", LastContact);
|
||||
field_from_json(Obj, "associations_2G", Associations_2G);
|
||||
field_from_json(Obj, "associations_5G", Associations_5G);
|
||||
field_from_json(Obj, "associations_6G", Associations_6G);
|
||||
field_from_json(Obj, "webSocketClients", webSocketClients);
|
||||
field_from_json(Obj, "websocketPackets", websocketPackets);
|
||||
field_from_json(Obj, "kafkaClients", kafkaClients);
|
||||
field_from_json(Obj, "kafkaPackets", kafkaPackets);
|
||||
field_from_json(Obj, "locale", locale);
|
||||
field_from_json(Obj, "started", started);
|
||||
field_from_json(Obj, "sessionId", sessionId);
|
||||
field_from_json(Obj, "connectionCompletionTime", connectionCompletionTime);
|
||||
field_from_json(Obj, "totalConnectionTime", totalConnectionTime);
|
||||
field_from_json(Obj, "certificateExpiryDate", certificateExpiryDate);
|
||||
field_from_json(Obj, "connectReason", connectReason);
|
||||
field_from_json(Obj, "uptime", uptime);
|
||||
field_from_json(Obj, "hasRADIUSSessions", hasRADIUSSessions );
|
||||
field_from_json(Obj, "hasGPS", hasGPS);
|
||||
field_from_json(Obj, "sanity", sanity);
|
||||
field_from_json(Obj, "memoryUsed", memoryUsed);
|
||||
field_from_json(Obj, "sanity", sanity);
|
||||
field_from_json(Obj, "load", load);
|
||||
field_from_json(Obj, "temperature", temperature);
|
||||
return true;
|
||||
} catch(const Poco::Exception &E) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool ConnectionState::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "compatible", Compatible);
|
||||
field_from_json(Obj, "ipAddress", Address);
|
||||
field_from_json(Obj, "txBytes", TX);
|
||||
field_from_json(Obj, "rxBytes", RX);
|
||||
field_from_json(Obj, "messageCount", MessageCount);
|
||||
field_from_json(Obj, "UUID", UUID);
|
||||
field_from_json(Obj, "connected", Connected);
|
||||
field_from_json(Obj, "firmware", Firmware);
|
||||
field_from_json(Obj, "lastContact", LastContact);
|
||||
field_from_json(Obj, "associations_2G", Associations_2G);
|
||||
field_from_json(Obj, "associations_5G", Associations_5G);
|
||||
field_from_json(Obj, "associations_6G", Associations_6G);
|
||||
field_from_json(Obj, "webSocketClients", webSocketClients);
|
||||
field_from_json(Obj, "websocketPackets", websocketPackets);
|
||||
field_from_json(Obj, "kafkaClients", kafkaClients);
|
||||
field_from_json(Obj, "kafkaPackets", kafkaPackets);
|
||||
field_from_json(Obj, "locale", locale);
|
||||
field_from_json(Obj, "started", started);
|
||||
field_from_json(Obj, "sessionId", sessionId);
|
||||
field_from_json(Obj, "connectionCompletionTime", connectionCompletionTime);
|
||||
field_from_json(Obj, "totalConnectionTime", totalConnectionTime);
|
||||
field_from_json(Obj, "certificateExpiryDate", certificateExpiryDate);
|
||||
field_from_json(Obj, "certificateIssuerName", certificateIssuerName);
|
||||
field_from_json(Obj, "connectReason", connectReason);
|
||||
field_from_json(Obj, "uptime", uptime);
|
||||
field_from_json(Obj, "hasRADIUSSessions", hasRADIUSSessions);
|
||||
field_from_json(Obj, "hasGPS", hasGPS);
|
||||
field_from_json(Obj, "sanity", sanity);
|
||||
field_from_json(Obj, "memoryUsed", memoryUsed);
|
||||
field_from_json(Obj, "sanity", sanity);
|
||||
field_from_json(Obj, "load", load);
|
||||
field_from_json(Obj, "temperature", temperature);
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DeviceConnectionStatistics::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj, "averageConnectionTime", averageConnectionTime);
|
||||
@@ -819,4 +822,115 @@ namespace OpenWifi::GWObjects {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ReEnroll::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "serial", serialNumber);
|
||||
field_from_json(Obj, "when", when);
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PackageInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "name", name);
|
||||
field_from_json(Obj, "version", version);
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void PackageInfo::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj, "name", name);
|
||||
field_to_json(Obj, "version", version);
|
||||
}
|
||||
|
||||
bool PackageList::from_json(const Poco::JSON::Array::Ptr &Obj) {
|
||||
try {
|
||||
std::ostringstream oss;
|
||||
Poco::JSON::Stringifier::stringify(Obj, oss);
|
||||
packageStringArray = oss.str();
|
||||
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void PackageList::to_json(Poco::JSON::Object &Obj) const {
|
||||
Obj.set("serialNumber", serialNumber);
|
||||
|
||||
Poco::JSON::Array packageJsonArray;
|
||||
for (const auto &pkg : packageArray) {
|
||||
Poco::JSON::Object pkgObj;
|
||||
pkg.to_json(pkgObj);
|
||||
packageJsonArray.add(pkgObj);
|
||||
}
|
||||
Obj.set("packageArray", packageJsonArray);
|
||||
|
||||
Obj.set("FirstUpdate", Poco::UInt64(FirstUpdate));
|
||||
Obj.set("LastUpdate", Poco::UInt64(LastUpdate));
|
||||
}
|
||||
|
||||
bool ToBeInstalled::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "name", name);
|
||||
field_from_json(Obj, "url", url);
|
||||
|
||||
Poco::URI uri(url);
|
||||
std::string scheme = uri.getScheme();
|
||||
if (scheme != "http" && scheme != "https") {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ToBeInstalled::to_json(Poco::JSON::Object &Obj) const {
|
||||
Obj.set("name", name);
|
||||
Obj.set("url", url);
|
||||
}
|
||||
|
||||
bool PackageInstall::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "serialNumber", serialNumber);
|
||||
field_from_json(Obj, "when", when);
|
||||
field_from_json(Obj, "packages", pkgs);
|
||||
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ToBeRemoved::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "name", name);
|
||||
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ToBeRemoved::to_json(Poco::JSON::Object &Obj) const {
|
||||
Obj.set("name", name);
|
||||
}
|
||||
|
||||
bool PackageRemove::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "serialNumber", serialNumber);
|
||||
field_from_json(Obj, "packages", pkgs);
|
||||
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} // namespace OpenWifi::GWObjects
|
||||
|
||||
@@ -42,6 +42,7 @@ namespace OpenWifi::GWObjects {
|
||||
uint64_t sessionId = 0;
|
||||
double connectionCompletionTime = 0.0;
|
||||
std::uint64_t certificateExpiryDate = 0;
|
||||
std::string certificateIssuerName;
|
||||
std::uint64_t hasRADIUSSessions = 0;
|
||||
bool hasGPS = false;
|
||||
std::uint64_t sanity=0;
|
||||
@@ -545,6 +546,57 @@ namespace OpenWifi::GWObjects {
|
||||
std::uint64_t when;
|
||||
std::vector<std::string> ports;
|
||||
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
struct ReEnroll {
|
||||
std::string serialNumber;
|
||||
std::uint64_t when;
|
||||
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
struct PackageInfo {
|
||||
std::string name;
|
||||
std::string version;
|
||||
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
};
|
||||
struct PackageList {
|
||||
std::string serialNumber;
|
||||
std::vector<PackageInfo> packageArray;
|
||||
uint64_t FirstUpdate = 0;
|
||||
uint64_t LastUpdate = 0;
|
||||
std::string packageStringArray;
|
||||
|
||||
bool from_json(const Poco::JSON::Array::Ptr &Obj);
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
};
|
||||
struct ToBeInstalled {
|
||||
std::string name;
|
||||
std::string url;
|
||||
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
};
|
||||
struct PackageInstall {
|
||||
std::string serialNumber;
|
||||
std::uint64_t when;
|
||||
std::vector<ToBeInstalled> pkgs;
|
||||
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
};
|
||||
struct ToBeRemoved {
|
||||
std::string name;
|
||||
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
};
|
||||
struct PackageRemove {
|
||||
std::string serialNumber;
|
||||
std::uint64_t when;
|
||||
std::vector<ToBeRemoved> pkgs;
|
||||
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
} // namespace OpenWifi::GWObjects
|
||||
|
||||
@@ -376,18 +376,21 @@ static std::string DefaultAPSchema = R"foo(
|
||||
"properties": {
|
||||
"port-mirror": {
|
||||
"description": "Enable mirror of traffic from multiple minotor ports to a single analysis port.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"monitor-ports": {
|
||||
"description": "The list of ports that we want to mirror.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"monitor-ports": {
|
||||
"description": "The list of ports that we want to mirror.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"analysis-port": {
|
||||
"description": "The port that mirror'ed packets should be sent to.",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"analysis-port": {
|
||||
"description": "The port that mirror'ed packets should be sent to.",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -3949,8 +3952,10 @@ static std::string DefaultAPSchema = R"foo(
|
||||
"inactive-deauth",
|
||||
"key-mismatch",
|
||||
"beacon-report",
|
||||
"radar-detected"
|
||||
]
|
||||
"radar-detected",
|
||||
"ft-finish",
|
||||
"sta-authorized"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7917,7 +7922,9 @@ static std::string DefaultSWITCHSchema = R"foo(
|
||||
"inactive-deauth",
|
||||
"key-mismatch",
|
||||
"beacon-report",
|
||||
"radar-detected"
|
||||
"radar-detected",
|
||||
"ft-finish",
|
||||
"sta-authorized"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,6 +68,16 @@ namespace OpenWifi {
|
||||
Context->addCertificateAuthority(Issuing);
|
||||
}
|
||||
|
||||
if (!client_cas_.empty()) {
|
||||
// add certificates specified in clientcas
|
||||
std::vector<Poco::Crypto::X509Certificate> Certs =
|
||||
Poco::Net::X509Certificate::readPEM(client_cas_);
|
||||
for (const auto &cert : Certs) {
|
||||
Context->addChainCertificate(cert);
|
||||
Context->addCertificateAuthority(cert);
|
||||
}
|
||||
}
|
||||
|
||||
Poco::Crypto::RSAKey Key("", key_file_, key_file_password_);
|
||||
Context->usePrivateKey(Key);
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ namespace OpenWifi {
|
||||
[[nodiscard]] inline auto KeyFile() const { return key_file_; };
|
||||
[[nodiscard]] inline auto CertFile() const { return cert_file_; };
|
||||
[[nodiscard]] inline auto RootCA() const { return root_ca_; };
|
||||
[[nodiscard]] inline auto ClientCas() const { return client_cas_; };
|
||||
[[nodiscard]] inline auto KeyFilePassword() const { return key_file_password_; };
|
||||
[[nodiscard]] inline auto IssuerCertFile() const { return issuer_cert_file_; };
|
||||
[[nodiscard]] inline auto Name() const { return name_; };
|
||||
|
||||
@@ -433,6 +433,9 @@ namespace OpenWifi::RESTAPI::Errors {
|
||||
|
||||
static const struct msg InvalidRRMAction { 1192, "Invalid RRM Action." };
|
||||
|
||||
static const struct msg InvalidPackageURL { 1193, "Invalid URL, must start with http:// or https://." };
|
||||
static const struct msg FailedToDownload { 1194, "Failed to download package." };
|
||||
|
||||
static const struct msg SimulationDoesNotExist {
|
||||
7000, "Simulation Instance ID does not exist."
|
||||
};
|
||||
@@ -550,6 +553,10 @@ namespace OpenWifi::RESTAPI::Protocol {
|
||||
static const char *DEBUG = "debug";
|
||||
static const char *SCRIPT = "script";
|
||||
static const char *TIMEOUT = "timeout";
|
||||
static const char *PACKAGE = "package";
|
||||
static const char *PACKAGES = "packages";
|
||||
static const char *PACKAGEINST = "packageInstall";
|
||||
static const char *PACKAGEDEL = "packageDelete";
|
||||
|
||||
static const char *NEWPASSWORD = "newPassword";
|
||||
static const char *USERS = "users";
|
||||
@@ -583,6 +590,7 @@ namespace OpenWifi::RESTAPI::Protocol {
|
||||
|
||||
static const char *FIXEDCONFIG = "fixedconfig";
|
||||
static const char *CABLEDIAGNOSTICS = "cable-diagnostics";
|
||||
static const char *REENROLL = "reenroll";
|
||||
} // namespace OpenWifi::RESTAPI::Protocol
|
||||
|
||||
namespace OpenWifi::uCentralProtocol {
|
||||
@@ -668,6 +676,9 @@ namespace OpenWifi::uCentralProtocol {
|
||||
static const char *SIGNATURE = "signature";
|
||||
static const char *INFO = "info";
|
||||
static const char *DATE = "date";
|
||||
static const char *PACKAGE = "package";
|
||||
static const char *PACKAGES = "packages";
|
||||
static const char *CATEGORY = "category";
|
||||
|
||||
static const char *SERIALNUMBER = "serialNumber";
|
||||
static const char *COMPATIBLE = "compatible";
|
||||
@@ -698,7 +709,9 @@ namespace OpenWifi::uCentralProtocol {
|
||||
|
||||
static const char *FIXEDCONFIG = "fixedconfig";
|
||||
static const char *CABLEDIAGNOSTICS = "cable-diagnostics";
|
||||
static const char *REENROLL = "reenroll";
|
||||
|
||||
static const char *OPERATION = "op";
|
||||
} // namespace OpenWifi::uCentralProtocol
|
||||
|
||||
namespace OpenWifi::uCentralProtocol::Events {
|
||||
@@ -733,7 +746,8 @@ namespace OpenWifi::uCentralProtocol::Events {
|
||||
ET_EVENT,
|
||||
ET_WIFISCAN,
|
||||
ET_ALARM,
|
||||
ET_REBOOTLOG
|
||||
ET_REBOOTLOG,
|
||||
ET_PACKAGE
|
||||
};
|
||||
|
||||
inline EVENT_MSG EventFromString(const std::string &Method) {
|
||||
@@ -767,6 +781,8 @@ namespace OpenWifi::uCentralProtocol::Events {
|
||||
return ET_ALARM;
|
||||
else if (strcmp(REBOOTLOG, Method.c_str()) == 0)
|
||||
return ET_REBOOTLOG;
|
||||
else if (strcmp(PACKAGE, Method.c_str()) == 0)
|
||||
return ET_PACKAGE;
|
||||
return ET_UNKNOWN;
|
||||
};
|
||||
} // namespace OpenWifi::uCentralProtocol::Events
|
||||
@@ -797,6 +813,8 @@ namespace OpenWifi::APCommands {
|
||||
powercycle,
|
||||
fixedconfig,
|
||||
cablediagnostics,
|
||||
reenroll,
|
||||
package,
|
||||
unknown
|
||||
};
|
||||
|
||||
@@ -812,7 +830,8 @@ namespace OpenWifi::APCommands {
|
||||
RESTAPI::Protocol::PING, RESTAPI::Protocol::SCRIPT,
|
||||
RESTAPI::Protocol::RRM, RESTAPI::Protocol::CERTUPDATE,
|
||||
RESTAPI::Protocol::TRANSFER, RESTAPI::Protocol::POWERCYCLE,
|
||||
RESTAPI::Protocol::FIXEDCONFIG, RESTAPI::Protocol::CABLEDIAGNOSTICS
|
||||
RESTAPI::Protocol::FIXEDCONFIG, RESTAPI::Protocol::CABLEDIAGNOSTICS,
|
||||
RESTAPI::Protocol::REENROLL, RESTAPI::Protocol::PACKAGE
|
||||
};
|
||||
|
||||
inline const char *to_string(Commands Cmd) { return uCentralAPCommands[(uint8_t)Cmd]; }
|
||||
|
||||
@@ -49,8 +49,7 @@ namespace OpenWifi {
|
||||
"Data TEXT, "
|
||||
"Recorded BIGINT, "
|
||||
"INDEX StatSerial0 (SerialNumber)), ",
|
||||
"INDEX StatSerial (SerialNumber ASC, Recorded ASC))",
|
||||
Poco::Data::Keywords::now;
|
||||
"INDEX StatSerial (SerialNumber ASC, Recorded ASC))", Poco::Data::Keywords::now;
|
||||
}
|
||||
return 0;
|
||||
} catch (const Poco::Exception &E) {
|
||||
@@ -154,8 +153,7 @@ namespace OpenWifi {
|
||||
"alter table devices add column lastRecordedContact bigint",
|
||||
"alter table devices add column simulated boolean",
|
||||
"alter table devices add column certificateExpiryDate bigint",
|
||||
"alter table devices add column connectReason TEXT"
|
||||
};
|
||||
"alter table devices add column connectReason TEXT"};
|
||||
|
||||
for (const auto &i : Script) {
|
||||
try {
|
||||
@@ -279,9 +277,7 @@ namespace OpenWifi {
|
||||
Poco::Data::Keywords::now;
|
||||
}
|
||||
|
||||
std::vector<std::string> Script{
|
||||
"alter table DefaultConfigs add column Platform text"
|
||||
};
|
||||
std::vector<std::string> Script{"alter table DefaultConfigs add column Platform text"};
|
||||
|
||||
for (const auto &i : Script) {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user