mirror of
https://github.com/Telecominfraproject/wlan-cloud-ucentralgw.git
synced 2025-10-29 09:52:27 +00:00
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
This commit is contained in:
183
.clang-format
183
.clang-format
@@ -1,7 +1,178 @@
|
||||
|
||||
BasedOnStyle: LLVM
|
||||
TabWidth: 4
|
||||
IndentWidth: 4
|
||||
UseTab: Always
|
||||
ColumnLimit: 100
|
||||
---
|
||||
Language: Cpp
|
||||
# BasedOnStyle: LLVM
|
||||
AccessModifierOffset: -2
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignArrayOfStructures: None
|
||||
AlignConsecutiveMacros: None
|
||||
AlignConsecutiveAssignments: None
|
||||
AlignConsecutiveBitFields: None
|
||||
AlignConsecutiveDeclarations: None
|
||||
AlignEscapedNewlines: Right
|
||||
AlignOperands: Align
|
||||
AlignTrailingComments: true
|
||||
AllowAllArgumentsOnNextLine: true
|
||||
AllowAllConstructorInitializersOnNextLine: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortEnumsOnASingleLine: true
|
||||
AllowShortBlocksOnASingleLine: Never
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
AllowShortLambdasOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: MultiLine
|
||||
AttributeMacros:
|
||||
- __capability
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterClass: false
|
||||
AfterControlStatement: Never
|
||||
AfterEnum: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
AfterExternBlock: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
BeforeLambdaBody: false
|
||||
BeforeWhile: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyRecord: true
|
||||
SplitEmptyNamespace: true
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeConceptDeclarations: true
|
||||
BreakBeforeBraces: Attach
|
||||
BreakBeforeInheritanceComma: false
|
||||
BreakInheritanceList: BeforeColon
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakStringLiterals: true
|
||||
ColumnLimit: 100
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DeriveLineEnding: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
EmptyLineAfterAccessModifier: Never
|
||||
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
FixNamespaceComments: true
|
||||
ForEachMacros:
|
||||
- foreach
|
||||
- Q_FOREACH
|
||||
- BOOST_FOREACH
|
||||
IfMacros:
|
||||
- KJ_IF_MAYBE
|
||||
IncludeBlocks: Preserve
|
||||
IncludeCategories:
|
||||
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||
Priority: 2
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||
Priority: 3
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
- Regex: '.*'
|
||||
Priority: 1
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
IncludeIsMainRegex: '(Test)?$'
|
||||
IncludeIsMainSourceRegex: ''
|
||||
IndentAccessModifiers: false
|
||||
IndentCaseLabels: false
|
||||
IndentCaseBlocks: false
|
||||
IndentGotoLabels: true
|
||||
IndentPPDirectives: None
|
||||
IndentExternBlock: AfterExternBlock
|
||||
IndentRequires: false
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
InsertTrailingCommas: None
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
LambdaBodyIndentation: Signature
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: All
|
||||
ObjCBinPackProtocolList: Auto
|
||||
ObjCBlockIndentWidth: 2
|
||||
ObjCBreakBeforeNestedBlockParam: true
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PenaltyBreakAssignment: 2
|
||||
PenaltyBreakBeforeFirstCallParameter: 19
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyBreakTemplateDeclaration: 10
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
PenaltyIndentedWhitespace: 0
|
||||
PointerAlignment: Right
|
||||
PPIndentWidth: -1
|
||||
ReferenceAlignment: Pointer
|
||||
ReflowComments: true
|
||||
ShortNamespaceLines: 1
|
||||
SortIncludes: CaseSensitive
|
||||
SortJavaStaticImport: Before
|
||||
SortUsingDeclarations: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCaseColon: false
|
||||
SpaceBeforeCpp11BracedList: false
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceAroundPointerQualifiers: Default
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceInEmptyBlock: false
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: Never
|
||||
SpacesInConditionalStatement: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInLineCommentPrefix:
|
||||
Minimum: 1
|
||||
Maximum: -1
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
SpaceBeforeSquareBrackets: false
|
||||
BitFieldColonSpacing: Both
|
||||
Standard: Latest
|
||||
StatementAttributeLikeMacros:
|
||||
- Q_EMIT
|
||||
StatementMacros:
|
||||
- Q_UNUSED
|
||||
- QT_REQUIRE_VERSION
|
||||
TabWidth: 4
|
||||
UseCRLF: false
|
||||
UseTab: Always
|
||||
WhitespaceSensitiveMacros:
|
||||
- STRINGIZE
|
||||
- PP_STRINGIZE
|
||||
- BOOST_PP_STRINGIZE
|
||||
- NS_SWIFT_NAME
|
||||
- CF_SWIFT_NAME
|
||||
...
|
||||
|
||||
|
||||
@@ -195,7 +195,7 @@ add_executable( owgw
|
||||
src/AP_WS_Process_telemetry.cpp
|
||||
src/AP_WS_Process_venuebroadcast.cpp
|
||||
src/RADSEC_server.h
|
||||
src/UI_GW_WebSocketNotifications.cpp src/UI_GW_WebSocketNotifications.h src/framework/RESTAPI_SystemConfiguration.h src/ScriptManager.cpp src/ScriptManager.h src/RESTAPI/RESTAPI_scripts_handler.cpp src/RESTAPI/RESTAPI_scripts_handler.h src/RESTAPI/RESTAPI_script_handler.cpp src/RESTAPI/RESTAPI_script_handler.h src/storage/storage_scripts.cpp src/storage/storage_scripts.h src/SignatureMgr.cpp src/SignatureMgr.h src/AP_WS_Process_event.cpp src/AP_WS_Process_wifiscan.cpp src/AP_WS_Process_alarm.cpp src/GWKafkaEvents.cpp src/GWKafkaEvents.h)
|
||||
src/UI_GW_WebSocketNotifications.cpp src/UI_GW_WebSocketNotifications.h src/framework/RESTAPI_SystemConfiguration.h src/ScriptManager.cpp src/ScriptManager.h src/RESTAPI/RESTAPI_scripts_handler.cpp src/RESTAPI/RESTAPI_scripts_handler.h src/RESTAPI/RESTAPI_script_handler.cpp src/RESTAPI/RESTAPI_script_handler.h src/storage/storage_scripts.cpp src/storage/storage_scripts.h src/SignatureMgr.h src/AP_WS_Process_event.cpp src/AP_WS_Process_wifiscan.cpp src/AP_WS_Process_alarm.cpp src/GWKafkaEvents.cpp src/GWKafkaEvents.h)
|
||||
|
||||
if(NOT SMALL_BUILD)
|
||||
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
|
||||
#include "AP_WS_Connection.h"
|
||||
|
||||
#include "Poco/Net/SecureStreamSocketImpl.h"
|
||||
#include "Poco/Net/HTTPServerResponseImpl.h"
|
||||
#include "Poco/Base64Decoder.h"
|
||||
#include "Poco/Net/Context.h"
|
||||
#include "Poco/Net/HTTPServerRequestImpl.h"
|
||||
#include "Poco/Net/HTTPServerResponseImpl.h"
|
||||
#include "Poco/Net/NetException.h"
|
||||
#include "Poco/Net/SSLException.h"
|
||||
#include "Poco/Net/Context.h"
|
||||
#include "Poco/Base64Decoder.h"
|
||||
#include "Poco/Net/SecureStreamSocketImpl.h"
|
||||
#include "Poco/Net/WebSocketImpl.h"
|
||||
#include "Poco/zlib.h"
|
||||
|
||||
@@ -21,22 +21,25 @@
|
||||
#include "StorageService.h"
|
||||
#include "TelemetryStream.h"
|
||||
|
||||
#include "GWKafkaEvents.h"
|
||||
#include "UI_GW_WebSocketNotifications.h"
|
||||
#include "framework/KafkaManager.h"
|
||||
#include "framework/MicroServiceFuncs.h"
|
||||
#include "framework/utils.h"
|
||||
#include "UI_GW_WebSocketNotifications.h"
|
||||
#include "GWKafkaEvents.h"
|
||||
|
||||
#include "fmt/format.h"
|
||||
|
||||
#include "framework/ow_constants.h"
|
||||
|
||||
|
||||
#include "RADIUS_proxy_server.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
#define DBL { std::cout << __LINE__ << " ID: " << ConnectionId_ << " Ser: " << SerialNumber_ << std::endl; }
|
||||
#define DBL \
|
||||
{ \
|
||||
std::cout << __LINE__ << " ID: " << ConnectionId_ << " Ser: " << SerialNumber_ \
|
||||
<< std::endl; \
|
||||
}
|
||||
|
||||
void AP_WS_Connection::LogException(const Poco::Exception &E) {
|
||||
poco_information(Logger_, fmt::format("EXCEPTION({}): {}", CId_, E.displayText()));
|
||||
@@ -44,12 +47,9 @@ namespace OpenWifi {
|
||||
|
||||
AP_WS_Connection::AP_WS_Connection(Poco::Net::HTTPServerRequest &request,
|
||||
Poco::Net::HTTPServerResponse &response,
|
||||
uint64_t connection_id,
|
||||
Poco::Logger &L,
|
||||
uint64_t connection_id, Poco::Logger &L,
|
||||
Poco::Net::SocketReactor &R)
|
||||
: Logger_(L) ,
|
||||
Reactor_(R)
|
||||
{
|
||||
: Logger_(L), Reactor_(R) {
|
||||
State_.sessionId = connection_id;
|
||||
WS_ = std::make_unique<Poco::Net::WebSocket>(request, response);
|
||||
|
||||
@@ -61,14 +61,14 @@ namespace OpenWifi {
|
||||
WS_->setKeepAlive(true);
|
||||
WS_->setBlocking(false);
|
||||
|
||||
Reactor_.addEventHandler(
|
||||
*WS_, Poco::NObserver<AP_WS_Connection, Poco::Net::ReadableNotification>(
|
||||
Reactor_.addEventHandler(*WS_,
|
||||
Poco::NObserver<AP_WS_Connection, Poco::Net::ReadableNotification>(
|
||||
*this, &AP_WS_Connection::OnSocketReadable));
|
||||
Reactor_.addEventHandler(
|
||||
*WS_, Poco::NObserver<AP_WS_Connection, Poco::Net::ShutdownNotification>(
|
||||
Reactor_.addEventHandler(*WS_,
|
||||
Poco::NObserver<AP_WS_Connection, Poco::Net::ShutdownNotification>(
|
||||
*this, &AP_WS_Connection::OnSocketShutdown));
|
||||
Reactor_.addEventHandler(
|
||||
*WS_, Poco::NObserver<AP_WS_Connection, Poco::Net::ErrorNotification>(
|
||||
Reactor_.addEventHandler(*WS_,
|
||||
Poco::NObserver<AP_WS_Connection, Poco::Net::ErrorNotification>(
|
||||
*this, &AP_WS_Connection::OnSocketError));
|
||||
Registered_ = true;
|
||||
Valid_ = true;
|
||||
@@ -84,7 +84,8 @@ namespace OpenWifi {
|
||||
std::lock_guard Lock(ConnectionMutex_);
|
||||
try {
|
||||
auto SockImpl = dynamic_cast<Poco::Net::WebSocketImpl *>(WS_->impl());
|
||||
auto SS = dynamic_cast<Poco::Net::SecureStreamSocketImpl*>(SockImpl->streamSocketImpl());
|
||||
auto SS =
|
||||
dynamic_cast<Poco::Net::SecureStreamSocketImpl *>(SockImpl->streamSocketImpl());
|
||||
|
||||
PeerAddress_ = SS->peerAddress().host();
|
||||
CId_ = Utils::FormatIPv6(SS->peerAddress().toString());
|
||||
@@ -92,16 +93,22 @@ namespace OpenWifi {
|
||||
State_.started = Utils::Now();
|
||||
|
||||
if (!SS->secure()) {
|
||||
poco_warning(Logger_,fmt::format("TLS-CONNECTION({}): Session={} Connection is NOT secure. Device is not allowed.", CId_, State_.sessionId ));
|
||||
poco_warning(Logger_, fmt::format("TLS-CONNECTION({}): Session={} Connection is "
|
||||
"NOT secure. Device is not allowed.",
|
||||
CId_, State_.sessionId));
|
||||
EndConnection();
|
||||
return false;
|
||||
}
|
||||
|
||||
poco_debug(Logger_,fmt::format("TLS-CONNECTION({}): Session={} Connection is secure.", CId_, State_.sessionId ));
|
||||
poco_debug(Logger_, fmt::format("TLS-CONNECTION({}): Session={} Connection is secure.",
|
||||
CId_, State_.sessionId));
|
||||
|
||||
if (!SS->havePeerCertificate()) {
|
||||
State_.VerifiedCertificate = GWObjects::NO_CERTIFICATE;
|
||||
poco_warning(Logger_,fmt::format("TLS-CONNECTION({}): Session={} No certificates available..", CId_, State_.sessionId ));
|
||||
poco_warning(
|
||||
Logger_,
|
||||
fmt::format("TLS-CONNECTION({}): Session={} No certificates available..", CId_,
|
||||
State_.sessionId));
|
||||
EndConnection();
|
||||
return false;
|
||||
}
|
||||
@@ -109,7 +116,9 @@ namespace OpenWifi {
|
||||
Poco::Crypto::X509Certificate PeerCert(SS->peerCertificate());
|
||||
if (!AP_WS_Server()->ValidateCertificate(CId_, PeerCert)) {
|
||||
State_.VerifiedCertificate = GWObjects::NO_CERTIFICATE;
|
||||
poco_warning(Logger_, fmt::format("TLS-CONNECTION({}): Session={} Device certificate is not valid. Device is not allowed.",
|
||||
poco_warning(Logger_,
|
||||
fmt::format("TLS-CONNECTION({}): Session={} Device certificate is not "
|
||||
"valid. Device is not allowed.",
|
||||
CId_, State_.sessionId));
|
||||
EndConnection();
|
||||
return false;
|
||||
@@ -118,12 +127,12 @@ namespace OpenWifi {
|
||||
CN_ = Poco::trim(Poco::toLower(PeerCert.commonName()));
|
||||
State_.VerifiedCertificate = GWObjects::VALID_CERTIFICATE;
|
||||
poco_debug(Logger_,
|
||||
fmt::format("TLS-CONNECTION({}): Session={} Valid certificate: CN={}", CId_, State_.sessionId , CN_));
|
||||
fmt::format("TLS-CONNECTION({}): Session={} Valid certificate: CN={}", CId_,
|
||||
State_.sessionId, CN_));
|
||||
|
||||
if (AP_WS_Server::IsSim(CN_) && !AP_WS_Server()->IsSimEnabled()) {
|
||||
poco_warning(
|
||||
Logger_,
|
||||
fmt::format("TLS-CONNECTION({}): Session={} Sim Device {} is not allowed. Disconnecting.",
|
||||
poco_warning(Logger_, fmt::format("TLS-CONNECTION({}): Session={} Sim Device {} is "
|
||||
"not allowed. Disconnecting.",
|
||||
CId_, State_.sessionId, CN_));
|
||||
EndConnection();
|
||||
return false;
|
||||
@@ -135,7 +144,8 @@ namespace OpenWifi {
|
||||
DeviceBlacklistedKafkaEvent KE(CN_, Utils::Now(), reason, author, created, CId_);
|
||||
poco_warning(
|
||||
Logger_,
|
||||
fmt::format("TLS-CONNECTION({}): Session={} Device {} is black listed. Disconnecting.",
|
||||
fmt::format(
|
||||
"TLS-CONNECTION({}): Session={} Device {} is black listed. Disconnecting.",
|
||||
CId_, State_.sessionId, CN_));
|
||||
EndConnection();
|
||||
return false;
|
||||
@@ -145,41 +155,62 @@ namespace OpenWifi {
|
||||
SerialNumber_ = CN_;
|
||||
SerialNumberInt_ = Utils::SerialNumberToInt(SerialNumber_);
|
||||
|
||||
poco_debug(Logger_, fmt::format("TLS-CONNECTION({}): Session={} CN={} Completed. (t={})", CId_, State_.sessionId , CN_, ConcurrentStartingDevices_));
|
||||
poco_debug(Logger_,
|
||||
fmt::format("TLS-CONNECTION({}): Session={} CN={} Completed. (t={})", CId_,
|
||||
State_.sessionId, CN_, ConcurrentStartingDevices_));
|
||||
DeviceValidated_ = true;
|
||||
return true;
|
||||
|
||||
} catch (const Poco::Net::CertificateValidationException &E) {
|
||||
poco_error(Logger_,fmt::format("CONNECTION({}): Session:{} Poco::CertificateValidationException Certificate Validation failed during connection. Device will have to retry.",
|
||||
poco_error(
|
||||
Logger_,
|
||||
fmt::format(
|
||||
"CONNECTION({}): Session:{} Poco::CertificateValidationException Certificate "
|
||||
"Validation failed during connection. Device will have to retry.",
|
||||
CId_, State_.sessionId));
|
||||
Logger_.log(E);
|
||||
} catch (const Poco::Net::WebSocketException &E) {
|
||||
poco_error(Logger_,fmt::format("CONNECTION({}): Session:{} Poco::WebSocketException WebSocket error during connection. Device will have to retry.",
|
||||
poco_error(Logger_,
|
||||
fmt::format("CONNECTION({}): Session:{} Poco::WebSocketException WebSocket "
|
||||
"error during connection. Device will have to retry.",
|
||||
CId_, State_.sessionId));
|
||||
Logger_.log(E);
|
||||
} catch (const Poco::Net::ConnectionAbortedException &E) {
|
||||
poco_error(Logger_,fmt::format("CONNECTION({}):Session:{} Poco::ConnectionAbortedException Connection was aborted during connection. Device will have to retry.",
|
||||
poco_error(
|
||||
Logger_,
|
||||
fmt::format("CONNECTION({}):Session:{} Poco::ConnectionAbortedException "
|
||||
"Connection was aborted during connection. Device will have to retry.",
|
||||
CId_, State_.sessionId));
|
||||
Logger_.log(E);
|
||||
} catch (const Poco::Net::ConnectionResetException &E) {
|
||||
poco_error(Logger_,fmt::format("CONNECTION({}): Session:{} Poco::ConnectionResetException Connection was reset during connection. Device will have to retry.",
|
||||
poco_error(
|
||||
Logger_,
|
||||
fmt::format("CONNECTION({}): Session:{} Poco::ConnectionResetException Connection "
|
||||
"was reset during connection. Device will have to retry.",
|
||||
CId_, State_.sessionId));
|
||||
Logger_.log(E);
|
||||
} catch (const Poco::Net::InvalidCertificateException &E) {
|
||||
poco_error(Logger_,fmt::format(
|
||||
"CONNECTION({}): Session:{} Poco::InvalidCertificateException Invalid certificate. Device will have to retry.",
|
||||
poco_error(Logger_,
|
||||
fmt::format("CONNECTION({}): Session:{} Poco::InvalidCertificateException "
|
||||
"Invalid certificate. Device will have to retry.",
|
||||
CId_, State_.sessionId));
|
||||
Logger_.log(E);
|
||||
} catch (const Poco::Net::SSLException &E) {
|
||||
poco_error(Logger_,fmt::format("CONNECTION({}): Session:{} Poco::SSLException SSL Exception during connection. Device will have to retry.",
|
||||
poco_error(Logger_,
|
||||
fmt::format("CONNECTION({}): Session:{} Poco::SSLException SSL Exception "
|
||||
"during connection. Device will have to retry.",
|
||||
CId_, State_.sessionId));
|
||||
Logger_.log(E);
|
||||
} catch (const Poco::Exception &E) {
|
||||
poco_error(Logger_,fmt::format("CONNECTION({}): Session:{} Poco::Exception caught during device connection. Device will have to retry.",
|
||||
poco_error(Logger_, fmt::format("CONNECTION({}): Session:{} Poco::Exception caught "
|
||||
"during device connection. Device will have to retry.",
|
||||
CId_, State_.sessionId));
|
||||
Logger_.log(E);
|
||||
} catch (...) {
|
||||
poco_error(Logger_,fmt::format("CONNECTION({}): Session:{} Exception caught during device connection. Device will have to retry. Unsecure connect denied.",
|
||||
poco_error(
|
||||
Logger_,
|
||||
fmt::format("CONNECTION({}): Session:{} Exception caught during device connection. "
|
||||
"Device will have to retry. Unsecure connect denied.",
|
||||
CId_, State_.sessionId));
|
||||
}
|
||||
EndConnection();
|
||||
@@ -254,7 +285,8 @@ namespace OpenWifi {
|
||||
GWObjects::Device D;
|
||||
if (StorageService()->GetDevice(SerialNumber_, D)) {
|
||||
|
||||
// This is the case where the cache is empty after a restart. So GoodConfig will 0. If the device already has the right UUID, we just return.
|
||||
// This is the case where the cache is empty after a restart. So GoodConfig will 0. If
|
||||
//the device already has the right UUID, we just return.
|
||||
if (D.UUID == UUID) {
|
||||
UpgradedUUID = UUID;
|
||||
ConfigurationCache().Add(SerialNumberInt_, UUID);
|
||||
@@ -262,8 +294,8 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
if (UUID > D.UUID) {
|
||||
// so we have a problem, the device has a newer config than we have. So we need to make sure our config
|
||||
// is newer.
|
||||
// so we have a problem, the device has a newer config than we have. So we need to
|
||||
//make sure our config is newer.
|
||||
Config::Config Cfg(D.Configuration);
|
||||
D.UUID = UUID + 2;
|
||||
UpgradedUUID = D.UUID;
|
||||
@@ -291,12 +323,16 @@ namespace OpenWifi {
|
||||
std::ostringstream O;
|
||||
Poco::JSON::Stringifier::stringify(Params, O);
|
||||
Cmd.Details = O.str();
|
||||
poco_information(Logger_,fmt::format("CFG-UPGRADE({}): Current ID: {}, newer configuration {}.",
|
||||
poco_information(Logger_,
|
||||
fmt::format("CFG-UPGRADE({}): Current ID: {}, newer configuration {}.",
|
||||
CId_, UUID, D.UUID));
|
||||
bool Sent;
|
||||
|
||||
StorageService()->AddCommand(SerialNumber_, Cmd, Storage::CommandExecutionType::COMMAND_EXECUTED);
|
||||
CommandManager()->PostCommand(CommandManager()->Next_RPC_ID(), APCommands::to_apcommand(Cmd.Command.c_str()),SerialNumber_, Cmd.Command, Params, Cmd.UUID, Sent, false, false);
|
||||
StorageService()->AddCommand(SerialNumber_, Cmd,
|
||||
Storage::CommandExecutionType::COMMAND_EXECUTED);
|
||||
CommandManager()->PostCommand(
|
||||
CommandManager()->Next_RPC_ID(), APCommands::to_apcommand(Cmd.Command.c_str()),
|
||||
SerialNumber_, Cmd.Command, Params, Cmd.UUID, Sent, false, false);
|
||||
|
||||
GWWebSocketNotifications::SingleDeviceConfigurationChange_t Notification;
|
||||
Notification.content.serialNumber = D.SerialNumber;
|
||||
@@ -310,7 +346,8 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
void AP_WS_Connection::ProcessJSONRPCResult(Poco::JSON::Object::Ptr Doc) {
|
||||
poco_debug(Logger_,fmt::format("RECEIVED-RPC({}): {}.", CId_, Doc->get(uCentralProtocol::ID).toString()));
|
||||
poco_debug(Logger_, fmt::format("RECEIVED-RPC({}): {}.", CId_,
|
||||
Doc->get(uCentralProtocol::ID).toString()));
|
||||
CommandManager()->PostCommandResult(SerialNumber_, Doc);
|
||||
}
|
||||
|
||||
@@ -318,13 +355,15 @@ namespace OpenWifi {
|
||||
auto Method = Doc->get(uCentralProtocol::METHOD).toString();
|
||||
auto EventType = uCentralProtocol::Events::EventFromString(Method);
|
||||
if (EventType == uCentralProtocol::Events::ET_UNKNOWN) {
|
||||
poco_warning(Logger_,fmt::format("ILLEGAL-PROTOCOL({}): Unknown message type '{}'", CId_, Method));
|
||||
poco_warning(Logger_, fmt::format("ILLEGAL-PROTOCOL({}): Unknown message type '{}'",
|
||||
CId_, Method));
|
||||
Errors_++;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Doc->isObject(uCentralProtocol::PARAMS)) {
|
||||
poco_warning(Logger_,fmt::format("MISSING-PARAMS({}): params must be an object.", CId_));
|
||||
poco_warning(Logger_,
|
||||
fmt::format("MISSING-PARAMS({}): params must be an object.", CId_));
|
||||
Errors_++;
|
||||
return;
|
||||
}
|
||||
@@ -340,19 +379,24 @@ namespace OpenWifi {
|
||||
compress_sz = ParamsObj->get("compress_sz");
|
||||
}
|
||||
|
||||
if (Utils::ExtractBase64CompressedData(CompressedData, UncompressedData, compress_sz)) {
|
||||
poco_trace(Logger_,fmt::format("EVENT({}): Found compressed payload expanded to '{}'.",
|
||||
if (Utils::ExtractBase64CompressedData(CompressedData, UncompressedData,
|
||||
compress_sz)) {
|
||||
poco_trace(Logger_,
|
||||
fmt::format("EVENT({}): Found compressed payload expanded to '{}'.",
|
||||
CId_, UncompressedData));
|
||||
Poco::JSON::Parser Parser;
|
||||
ParamsObj = Parser.parse(UncompressedData).extract<Poco::JSON::Object::Ptr>();
|
||||
} else {
|
||||
poco_warning(Logger_,fmt::format("INVALID-COMPRESSED-DATA({}): Compressed cannot be uncompressed - content must be corrupt..: size={}",
|
||||
poco_warning(Logger_,
|
||||
fmt::format("INVALID-COMPRESSED-DATA({}): Compressed cannot be "
|
||||
"uncompressed - content must be corrupt..: size={}",
|
||||
CId_, CompressedData.size()));
|
||||
Errors_++;
|
||||
return;
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
poco_warning(Logger_,fmt::format("INVALID-COMPRESSED-JSON-DATA({}): Compressed cannot be parsed - JSON must be corrupt..",
|
||||
poco_warning(Logger_, fmt::format("INVALID-COMPRESSED-JSON-DATA({}): Compressed "
|
||||
"cannot be parsed - JSON must be corrupt..",
|
||||
CId_));
|
||||
Logger_.log(E);
|
||||
return;
|
||||
@@ -360,11 +404,14 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
if (!ParamsObj->has(uCentralProtocol::SERIAL)) {
|
||||
poco_warning(Logger_,fmt::format("MISSING-PARAMS({}): Serial number is missing in message.", CId_));
|
||||
poco_warning(
|
||||
Logger_,
|
||||
fmt::format("MISSING-PARAMS({}): Serial number is missing in message.", CId_));
|
||||
return;
|
||||
}
|
||||
|
||||
auto Serial = Poco::trim(Poco::toLower(ParamsObj->get(uCentralProtocol::SERIAL).toString()));
|
||||
auto Serial =
|
||||
Poco::trim(Poco::toLower(ParamsObj->get(uCentralProtocol::SERIAL).toString()));
|
||||
if (!Utils::ValidSerialNumber(Serial)) {
|
||||
Poco::Exception E(
|
||||
fmt::format(
|
||||
@@ -445,13 +492,15 @@ namespace OpenWifi {
|
||||
// this will never be called but some compilers will complain if we do not have a case for
|
||||
// every single values of an enum
|
||||
case uCentralProtocol::Events::ET_UNKNOWN: {
|
||||
poco_warning(Logger_, fmt::format("ILLEGAL-EVENT({}): Event '{}' unknown. CN={}", CId_, Method, CN_));
|
||||
poco_warning(Logger_, fmt::format("ILLEGAL-EVENT({}): Event '{}' unknown. CN={}", CId_,
|
||||
Method, CN_));
|
||||
Errors_++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool AP_WS_Connection::StartTelemetry(uint64_t RPCID, const std::vector<std::string> & TelemetryTypes) {
|
||||
bool AP_WS_Connection::StartTelemetry(uint64_t RPCID,
|
||||
const std::vector<std::string> &TelemetryTypes) {
|
||||
poco_information(Logger_, fmt::format("TELEMETRY({}): Starting.", CId_));
|
||||
Poco::JSON::Object StartMessage;
|
||||
StartMessage.set("jsonrpc", "2.0");
|
||||
@@ -500,13 +549,18 @@ namespace OpenWifi {
|
||||
State_.webSocketClients = TelemetryWebSocketRefCount_;
|
||||
}
|
||||
|
||||
bool AP_WS_Connection::SetWebSocketTelemetryReporting(uint64_t RPCID, uint64_t Interval,
|
||||
uint64_t LifeTime, const std::vector<std::string> & TelemetryTypes) {
|
||||
bool AP_WS_Connection::SetWebSocketTelemetryReporting(
|
||||
uint64_t RPCID, uint64_t Interval, uint64_t LifeTime,
|
||||
const std::vector<std::string> &TelemetryTypes) {
|
||||
std::unique_lock Lock(TelemetryMutex_);
|
||||
TelemetryWebSocketRefCount_++;
|
||||
TelemetryInterval_ = TelemetryInterval_ ? ( Interval< TelemetryInterval_ ? Interval : TelemetryInterval_) : Interval;
|
||||
TelemetryInterval_ = TelemetryInterval_
|
||||
? (Interval < TelemetryInterval_ ? Interval : TelemetryInterval_)
|
||||
: Interval;
|
||||
auto TelemetryWebSocketTimer = LifeTime + Utils::Now();
|
||||
TelemetryWebSocketTimer_ = TelemetryWebSocketTimer > TelemetryWebSocketTimer_ ? TelemetryWebSocketTimer : TelemetryWebSocketTimer_;
|
||||
TelemetryWebSocketTimer_ = TelemetryWebSocketTimer > TelemetryWebSocketTimer_
|
||||
? TelemetryWebSocketTimer
|
||||
: TelemetryWebSocketTimer_;
|
||||
UpdateCounts();
|
||||
if (!TelemetryReporting_) {
|
||||
TelemetryReporting_ = true;
|
||||
@@ -515,12 +569,18 @@ namespace OpenWifi {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AP_WS_Connection::SetKafkaTelemetryReporting(uint64_t RPCID, uint64_t Interval, uint64_t LifeTime, const std::vector<std::string> & TelemetryTypes) {
|
||||
bool
|
||||
AP_WS_Connection::SetKafkaTelemetryReporting(uint64_t RPCID, uint64_t Interval,
|
||||
uint64_t LifeTime,
|
||||
const std::vector<std::string> &TelemetryTypes) {
|
||||
std::unique_lock Lock(TelemetryMutex_);
|
||||
TelemetryKafkaRefCount_++;
|
||||
TelemetryInterval_ = TelemetryInterval_ ? ( Interval<TelemetryInterval_ ? Interval : TelemetryInterval_) : Interval;
|
||||
TelemetryInterval_ = TelemetryInterval_
|
||||
? (Interval < TelemetryInterval_ ? Interval : TelemetryInterval_)
|
||||
: Interval;
|
||||
auto TelemetryKafkaTimer = LifeTime + Utils::Now();
|
||||
TelemetryKafkaTimer_ = TelemetryKafkaTimer > TelemetryKafkaTimer_ ? TelemetryKafkaTimer : TelemetryKafkaTimer_;
|
||||
TelemetryKafkaTimer_ =
|
||||
TelemetryKafkaTimer > TelemetryKafkaTimer_ ? TelemetryKafkaTimer : TelemetryKafkaTimer_;
|
||||
UpdateCounts();
|
||||
if (!TelemetryReporting_) {
|
||||
TelemetryReporting_ = true;
|
||||
@@ -553,17 +613,20 @@ namespace OpenWifi {
|
||||
return true;
|
||||
}
|
||||
|
||||
void AP_WS_Connection::OnSocketShutdown([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf) {
|
||||
void AP_WS_Connection::OnSocketShutdown(
|
||||
[[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf) {
|
||||
poco_trace(Logger_, fmt::format("SOCKET-SHUTDOWN({}): Closing.", CId_));
|
||||
return EndConnection();
|
||||
}
|
||||
|
||||
void AP_WS_Connection::OnSocketError([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf) {
|
||||
void AP_WS_Connection::OnSocketError(
|
||||
[[maybe_unused]] const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf) {
|
||||
poco_trace(Logger_, fmt::format("SOCKET-ERROR({}): Closing.", CId_));
|
||||
return EndConnection();
|
||||
}
|
||||
|
||||
void AP_WS_Connection::OnSocketReadable([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) {
|
||||
void AP_WS_Connection::OnSocketReadable(
|
||||
[[maybe_unused]] const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) {
|
||||
|
||||
if (!Valid_)
|
||||
return;
|
||||
@@ -581,10 +644,13 @@ namespace OpenWifi {
|
||||
return EndConnection();
|
||||
} catch (const std::exception &E) {
|
||||
std::string W = E.what();
|
||||
poco_information(Logger_, fmt::format("std::exception caught: {}. Connection terminated with {}", W, CId_));
|
||||
poco_information(
|
||||
Logger_,
|
||||
fmt::format("std::exception caught: {}. Connection terminated with {}", W, CId_));
|
||||
return EndConnection();
|
||||
} catch (...) {
|
||||
poco_information(Logger_, fmt::format("Unknown exception for {}. Connection terminated.", CId_));
|
||||
poco_information(Logger_,
|
||||
fmt::format("Unknown exception for {}. Connection terminated.", CId_));
|
||||
return EndConnection();
|
||||
}
|
||||
}
|
||||
@@ -598,7 +664,9 @@ namespace OpenWifi {
|
||||
Op = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK;
|
||||
|
||||
if (IncomingSize == 0 && flags == 0 && Op == 0) {
|
||||
poco_information(Logger_, fmt::format("DISCONNECT({}): device has disconnected. Session={}", CId_, State_.sessionId));
|
||||
poco_information(Logger_,
|
||||
fmt::format("DISCONNECT({}): device has disconnected. Session={}",
|
||||
CId_, State_.sessionId));
|
||||
return EndConnection();
|
||||
}
|
||||
|
||||
@@ -639,8 +707,9 @@ namespace OpenWifi {
|
||||
} break;
|
||||
|
||||
case Poco::Net::WebSocket::FRAME_OP_TEXT: {
|
||||
poco_trace(Logger_, fmt::format("FRAME({}): Frame received (length={}, flags={}). Msg={}", CId_,
|
||||
IncomingSize, flags, IncomingFrame.begin()));
|
||||
poco_trace(Logger_,
|
||||
fmt::format("FRAME({}): Frame received (length={}, flags={}). Msg={}",
|
||||
CId_, IncomingSize, flags, IncomingFrame.begin()));
|
||||
|
||||
Poco::JSON::Parser parser;
|
||||
auto ParsedMessage = parser.parse(IncomingFrame.begin());
|
||||
@@ -652,10 +721,12 @@ namespace OpenWifi {
|
||||
ProcessJSONRPCEvent(IncomingJSON);
|
||||
} else if (IncomingJSON->has(uCentralProtocol::RESULT) &&
|
||||
IncomingJSON->has(uCentralProtocol::ID)) {
|
||||
poco_trace(Logger_, fmt::format("RPC-RESULT({}): payload: {}", CId_, IncomingFrame.begin()));
|
||||
poco_trace(Logger_, fmt::format("RPC-RESULT({}): payload: {}", CId_,
|
||||
IncomingFrame.begin()));
|
||||
ProcessJSONRPCResult(IncomingJSON);
|
||||
} else {
|
||||
poco_warning(Logger_,
|
||||
poco_warning(
|
||||
Logger_,
|
||||
fmt::format("INVALID-PAYLOAD({}): Payload is not JSON-RPC 2.0: {}",
|
||||
CId_, IncomingFrame.begin()));
|
||||
}
|
||||
@@ -665,8 +736,10 @@ namespace OpenWifi {
|
||||
std::ostringstream iS;
|
||||
IncomingJSON->stringify(iS);
|
||||
std::cout << iS.str() << std::endl;
|
||||
poco_warning(Logger_, fmt::format(
|
||||
"FRAME({}): illegal transaction header, missing 'jsonrpc'", CId_));
|
||||
poco_warning(
|
||||
Logger_,
|
||||
fmt::format("FRAME({}): illegal transaction header, missing 'jsonrpc'",
|
||||
CId_));
|
||||
Errors_++;
|
||||
}
|
||||
return;
|
||||
@@ -679,75 +752,79 @@ namespace OpenWifi {
|
||||
} break;
|
||||
|
||||
default: {
|
||||
poco_warning(Logger_, fmt::format("UNKNOWN({}): unknown WS Frame operation: {}", CId_,
|
||||
std::to_string(Op)));
|
||||
poco_warning(Logger_, fmt::format("UNKNOWN({}): unknown WS Frame operation: {}",
|
||||
CId_, std::to_string(Op)));
|
||||
} break;
|
||||
}
|
||||
} catch (const Poco::Net::ConnectionResetException &E) {
|
||||
poco_warning(Logger_, fmt::format("ConnectionResetException({}): Text:{} Payload:{} Session:{}",
|
||||
CId_,
|
||||
E.displayText(),
|
||||
poco_warning(Logger_,
|
||||
fmt::format("ConnectionResetException({}): Text:{} Payload:{} Session:{}",
|
||||
CId_, E.displayText(),
|
||||
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
||||
State_.sessionId));
|
||||
return EndConnection();
|
||||
} catch (const Poco::JSON::JSONException &E) {
|
||||
poco_warning(Logger_, fmt::format("JSONException({}): Text:{} Payload:{} Session:{}",
|
||||
CId_,
|
||||
poco_warning(Logger_,
|
||||
fmt::format("JSONException({}): Text:{} Payload:{} Session:{}", CId_,
|
||||
E.displayText(),
|
||||
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
||||
State_.sessionId));
|
||||
return EndConnection();
|
||||
} catch (const Poco::Net::WebSocketException &E) {
|
||||
poco_warning(Logger_, fmt::format("WebSocketException({}): Text:{} Payload:{} Session:{}",
|
||||
CId_,
|
||||
poco_warning(Logger_,
|
||||
fmt::format("WebSocketException({}): Text:{} Payload:{} Session:{}", CId_,
|
||||
E.displayText(),
|
||||
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
||||
State_.sessionId));
|
||||
return EndConnection();
|
||||
} catch (const Poco::Net::SSLConnectionUnexpectedlyClosedException &E) {
|
||||
poco_warning(Logger_, fmt::format("SSLConnectionUnexpectedlyClosedException({}): Text:{} Payload:{} Session:{}",
|
||||
CId_,
|
||||
E.displayText(),
|
||||
poco_warning(
|
||||
Logger_,
|
||||
fmt::format(
|
||||
"SSLConnectionUnexpectedlyClosedException({}): Text:{} Payload:{} Session:{}",
|
||||
CId_, E.displayText(),
|
||||
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
||||
State_.sessionId));
|
||||
return EndConnection();
|
||||
} catch (const Poco::Net::SSLException &E) {
|
||||
poco_warning(Logger_, fmt::format("SSLException({}): Text:{} Payload:{} Session:{}",
|
||||
CId_,
|
||||
poco_warning(Logger_,
|
||||
fmt::format("SSLException({}): Text:{} Payload:{} Session:{}", CId_,
|
||||
E.displayText(),
|
||||
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
||||
State_.sessionId));
|
||||
return EndConnection();
|
||||
} catch (const Poco::Net::NetException &E) {
|
||||
poco_warning(Logger_, fmt::format("NetException({}): Text:{} Payload:{} Session:{}",
|
||||
CId_,
|
||||
poco_warning(Logger_,
|
||||
fmt::format("NetException({}): Text:{} Payload:{} Session:{}", CId_,
|
||||
E.displayText(),
|
||||
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
||||
State_.sessionId));
|
||||
return EndConnection();
|
||||
} catch (const Poco::IOException &E) {
|
||||
poco_warning(Logger_, fmt::format("IOException({}): Text:{} Payload:{} Session:{}",
|
||||
CId_,
|
||||
poco_warning(Logger_,
|
||||
fmt::format("IOException({}): Text:{} Payload:{} Session:{}", CId_,
|
||||
E.displayText(),
|
||||
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
||||
State_.sessionId));
|
||||
return EndConnection();
|
||||
} catch (const Poco::Exception &E) {
|
||||
poco_warning(Logger_, fmt::format("Exception({}): Text:{} Payload:{} Session:{}",
|
||||
CId_,
|
||||
poco_warning(Logger_,
|
||||
fmt::format("Exception({}): Text:{} Payload:{} Session:{}", CId_,
|
||||
E.displayText(),
|
||||
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
||||
State_.sessionId));
|
||||
return EndConnection();
|
||||
} catch (const std::exception &E) {
|
||||
poco_warning(Logger_, fmt::format("std::exception({}): Text:{} Payload:{} Session:{}",
|
||||
CId_,
|
||||
poco_warning(Logger_,
|
||||
fmt::format("std::exception({}): Text:{} Payload:{} Session:{}", CId_,
|
||||
E.what(),
|
||||
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
||||
State_.sessionId));
|
||||
return EndConnection();
|
||||
} catch (...) {
|
||||
poco_error(Logger_,fmt::format("UnknownException({}): Device must be disconnected. Unknown exception. Session:{}", CId_, State_.sessionId));
|
||||
poco_error(Logger_, fmt::format("UnknownException({}): Device must be disconnected. "
|
||||
"Unknown exception. Session:{}",
|
||||
CId_, State_.sessionId));
|
||||
return EndConnection();
|
||||
}
|
||||
|
||||
@@ -763,9 +840,10 @@ namespace OpenWifi {
|
||||
size_t BytesSent = WS_->sendFrame(Payload.c_str(), (int)Payload.size());
|
||||
|
||||
/*
|
||||
* There is a possibility to actually try and send data but the device is no longer listening.
|
||||
* This code attempts to wait 5 seconds to see if the device is actually still listening.
|
||||
* if the data is not acked under 5 seconds, then we consider that the data never made it or the device is disconnected somehow.
|
||||
* There is a possibility to actually try and send data but the device is no longer
|
||||
* listening. This code attempts to wait 5 seconds to see if the device is actually
|
||||
* still listening. if the data is not acked under 5 seconds, then we consider that the
|
||||
* data never made it or the device is disconnected somehow.
|
||||
*/
|
||||
#if defined(__APPLE__)
|
||||
tcp_connection_info info;
|
||||
@@ -774,7 +852,8 @@ namespace OpenWifi {
|
||||
do {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
socklen_t opt_len = sizeof(info);
|
||||
getsockopt(WS_->impl()->sockfd(),SOL_SOCKET,TCP_CONNECTION_INFO,(void *)&info,&opt_len);
|
||||
getsockopt(WS_->impl()->sockfd(), SOL_SOCKET, TCP_CONNECTION_INFO, (void *)&info,
|
||||
&opt_len);
|
||||
} while (!info.tcpi_tfo_syn_data_acked && expireAt > std::chrono::system_clock::now());
|
||||
if (!info.tcpi_tfo_syn_data_acked)
|
||||
return false;
|
||||
@@ -812,7 +891,8 @@ namespace OpenWifi {
|
||||
return ofs.str();
|
||||
}
|
||||
|
||||
bool AP_WS_Connection::SendRadiusAuthenticationData(const unsigned char * buffer, std::size_t size) {
|
||||
bool AP_WS_Connection::SendRadiusAuthenticationData(const unsigned char *buffer,
|
||||
std::size_t size) {
|
||||
Poco::JSON::Object Answer;
|
||||
Answer.set(uCentralProtocol::RADIUS, uCentralProtocol::RADIUSAUTH);
|
||||
Answer.set(uCentralProtocol::RADIUSDATA, Base64Encode(buffer, size));
|
||||
@@ -848,16 +928,19 @@ namespace OpenWifi {
|
||||
if (Type == uCentralProtocol::RADIUSACCT) {
|
||||
auto Data = Doc->get(uCentralProtocol::RADIUSDATA).toString();
|
||||
auto DecodedData = Base64Decode(Data);
|
||||
RADIUS_proxy_server()->SendAccountingData(SerialNumber_,DecodedData.c_str(),DecodedData.size());
|
||||
RADIUS_proxy_server()->SendAccountingData(SerialNumber_, DecodedData.c_str(),
|
||||
DecodedData.size());
|
||||
} else if (Type == uCentralProtocol::RADIUSAUTH) {
|
||||
auto Data = Doc->get(uCentralProtocol::RADIUSDATA).toString();
|
||||
auto DecodedData = Base64Decode(Data);
|
||||
RADIUS_proxy_server()->SendAuthenticationData(SerialNumber_,DecodedData.c_str(),DecodedData.size());
|
||||
RADIUS_proxy_server()->SendAuthenticationData(SerialNumber_, DecodedData.c_str(),
|
||||
DecodedData.size());
|
||||
} else if (Type == uCentralProtocol::RADIUSCOA) {
|
||||
auto Data = Doc->get(uCentralProtocol::RADIUSDATA).toString();
|
||||
auto DecodedData = Base64Decode(Data);
|
||||
RADIUS_proxy_server()->SendCoAData(SerialNumber_,DecodedData.c_str(),DecodedData.size());
|
||||
}
|
||||
RADIUS_proxy_server()->SendCoAData(SerialNumber_, DecodedData.c_str(),
|
||||
DecodedData.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -4,14 +4,14 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <shared_mutex>
|
||||
#include <string>
|
||||
|
||||
#include "Poco/JSON/Object.h"
|
||||
#include "Poco/Logger.h"
|
||||
#include "Poco/Net/SocketNotification.h"
|
||||
#include "Poco/Net/SocketReactor.h"
|
||||
#include "Poco/Net/StreamSocket.h"
|
||||
#include "Poco/JSON/Object.h"
|
||||
#include "Poco/Net/SocketNotification.h"
|
||||
#include "Poco/Logger.h"
|
||||
#include "Poco/Net/WebSocket.h"
|
||||
|
||||
#include "RESTObjects/RESTAPI_GWobjects.h"
|
||||
@@ -20,12 +20,11 @@ namespace OpenWifi {
|
||||
|
||||
class AP_WS_Connection {
|
||||
static constexpr int BufSize = 256000;
|
||||
|
||||
public:
|
||||
explicit AP_WS_Connection(Poco::Net::HTTPServerRequest &request,
|
||||
Poco::Net::HTTPServerResponse &response,
|
||||
uint64_t connection_id,
|
||||
Poco::Logger &L,
|
||||
Poco::Net::SocketReactor &R);
|
||||
Poco::Net::HTTPServerResponse &response, uint64_t connection_id,
|
||||
Poco::Logger &L, Poco::Net::SocketReactor &R);
|
||||
~AP_WS_Connection();
|
||||
|
||||
void EndConnection();
|
||||
@@ -44,11 +43,17 @@ namespace OpenWifi {
|
||||
void OnSocketShutdown(const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf);
|
||||
void OnSocketError(const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf);
|
||||
bool LookForUpgrade(uint64_t UUID, uint64_t &UpgradedUUID);
|
||||
static bool ExtractBase64CompressedData(const std::string & CompressedData, std::string & UnCompressedData, uint64_t compress_sz);
|
||||
static bool ExtractBase64CompressedData(const std::string &CompressedData,
|
||||
std::string &UnCompressedData,
|
||||
uint64_t compress_sz);
|
||||
void LogException(const Poco::Exception &E);
|
||||
inline Poco::Logger &Logger() { return Logger_; }
|
||||
bool SetWebSocketTelemetryReporting(uint64_t RPCID, uint64_t interval, uint64_t TelemetryWebSocketTimer, const std::vector<std::string> & TelemetryTypes);
|
||||
bool SetKafkaTelemetryReporting(uint64_t RPCID, uint64_t interval, uint64_t TelemetryKafkaTimer, const std::vector<std::string> & TelemetryTypes);
|
||||
bool SetWebSocketTelemetryReporting(uint64_t RPCID, uint64_t interval,
|
||||
uint64_t TelemetryWebSocketTimer,
|
||||
const std::vector<std::string> &TelemetryTypes);
|
||||
bool SetKafkaTelemetryReporting(uint64_t RPCID, uint64_t interval,
|
||||
uint64_t TelemetryKafkaTimer,
|
||||
const std::vector<std::string> &TelemetryTypes);
|
||||
bool StopWebSocketTelemetry(uint64_t RPCID);
|
||||
bool StopKafkaTelemetry(uint64_t RPCID);
|
||||
|
||||
@@ -147,7 +152,8 @@ namespace OpenWifi {
|
||||
GWObjects::ConnectionState State_;
|
||||
std::string RawLastStats_;
|
||||
GWObjects::HealthCheck RawLastHealthcheck_;
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> ConnectionStart_ = std::chrono::high_resolution_clock::now();
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> ConnectionStart_ =
|
||||
std::chrono::high_resolution_clock::now();
|
||||
std::chrono::duration<double, std::milli> ConnectionCompletionTime_{0.0};
|
||||
std::atomic_flag Dead_ = false;
|
||||
std::atomic_bool DeviceValidated_ = false;
|
||||
@@ -161,4 +167,4 @@ namespace OpenWifi {
|
||||
void UpdateCounts();
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -4,16 +4,16 @@
|
||||
#include "AP_WS_Connection.h"
|
||||
#include "StorageService.h"
|
||||
|
||||
#include "framework/ow_constants.h"
|
||||
#include "fmt/format.h"
|
||||
#include "framework/KafkaManager.h"
|
||||
#include "framework/ow_constants.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
void AP_WS_Connection::Process_alarm(Poco::JSON::Object::Ptr ParamsObj) {
|
||||
if (!State_.Connected) {
|
||||
poco_warning(
|
||||
Logger_,
|
||||
fmt::format("INVALID-PROTOCOL({}): Device '{}' is not following protocol", CId_, CN_));
|
||||
poco_warning(Logger_,
|
||||
fmt::format("INVALID-PROTOCOL({}): Device '{}' is not following protocol",
|
||||
CId_, CN_));
|
||||
Errors_++;
|
||||
return;
|
||||
}
|
||||
@@ -29,4 +29,4 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -9,8 +9,9 @@
|
||||
namespace OpenWifi {
|
||||
void AP_WS_Connection::Process_cfgpending(Poco::JSON::Object::Ptr ParamsObj) {
|
||||
if (!State_.Connected) {
|
||||
poco_warning(Logger_, fmt::format(
|
||||
"INVALID-PROTOCOL({}): Device '{}' is not following protocol", CId_, CN_));
|
||||
poco_warning(Logger_,
|
||||
fmt::format("INVALID-PROTOCOL({}): Device '{}' is not following protocol",
|
||||
CId_, CN_));
|
||||
Errors_++;
|
||||
return;
|
||||
}
|
||||
@@ -18,9 +19,10 @@ namespace OpenWifi {
|
||||
|
||||
[[maybe_unused]] uint64_t UUID = ParamsObj->get(uCentralProtocol::UUID);
|
||||
[[maybe_unused]] uint64_t Active = ParamsObj->get(uCentralProtocol::ACTIVE);
|
||||
poco_trace(Logger_, fmt::format("CFG-PENDING({}): Active: {} Target: {}", CId_, Active, UUID));
|
||||
poco_trace(Logger_,
|
||||
fmt::format("CFG-PENDING({}): Active: {} Target: {}", CId_, Active, UUID));
|
||||
} else {
|
||||
poco_warning(Logger_, fmt::format("CFG-PENDING({}): Missing some parameters", CId_));
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -4,10 +4,10 @@
|
||||
|
||||
#include "AP_WS_Connection.h"
|
||||
#include "AP_WS_Server.h"
|
||||
#include "StorageService.h"
|
||||
#include "FindCountry.h"
|
||||
#include "Daemon.h"
|
||||
#include "CentralConfig.h"
|
||||
#include "Daemon.h"
|
||||
#include "FindCountry.h"
|
||||
#include "StorageService.h"
|
||||
|
||||
#include "CommandManager.h"
|
||||
|
||||
@@ -19,7 +19,9 @@
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
[[maybe_unused]] static void SendKafkaFirmwareUpdate(const std::string &SerialNumber, const std::string &OldFirmware, const std::string &NewFirmware) {
|
||||
[[maybe_unused]] static void SendKafkaFirmwareUpdate(const std::string &SerialNumber,
|
||||
const std::string &OldFirmware,
|
||||
const std::string &NewFirmware) {
|
||||
if (KafkaManager()->Enabled()) {
|
||||
Poco::JSON::Object EventDetails;
|
||||
EventDetails.set("oldFirmware", OldFirmware);
|
||||
@@ -34,9 +36,9 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
|
||||
void AP_WS_Connection::Process_connect(Poco::JSON::Object::Ptr ParamsObj, const std::string &Serial) {
|
||||
if (ParamsObj->has(uCentralProtocol::UUID) &&
|
||||
ParamsObj->has(uCentralProtocol::FIRMWARE) &&
|
||||
void AP_WS_Connection::Process_connect(Poco::JSON::Object::Ptr ParamsObj,
|
||||
const std::string &Serial) {
|
||||
if (ParamsObj->has(uCentralProtocol::UUID) && ParamsObj->has(uCentralProtocol::FIRMWARE) &&
|
||||
ParamsObj->has(uCentralProtocol::CAPABILITIES)) {
|
||||
uint64_t UUID = ParamsObj->get(uCentralProtocol::UUID);
|
||||
auto Firmware = ParamsObj->get(uCentralProtocol::FIRMWARE).toString();
|
||||
@@ -82,7 +84,8 @@ namespace OpenWifi {
|
||||
int Updated{0};
|
||||
if (!Firmware.empty()) {
|
||||
if (Firmware != DeviceInfo.Firmware) {
|
||||
DeviceFirmwareChangeKafkaEvent KEvent(SerialNumber_, Utils::Now(),DeviceInfo.Firmware, Firmware );
|
||||
DeviceFirmwareChangeKafkaEvent KEvent(SerialNumber_, Utils::Now(),
|
||||
DeviceInfo.Firmware, Firmware);
|
||||
DeviceInfo.Firmware = Firmware;
|
||||
DeviceInfo.LastFWUpdate = Utils::Now();
|
||||
++Updated;
|
||||
@@ -128,27 +131,33 @@ namespace OpenWifi {
|
||||
|
||||
State_.Compatible = Compatible_;
|
||||
State_.Connected = true;
|
||||
ConnectionCompletionTime_ = std::chrono::high_resolution_clock::now() - ConnectionStart_;
|
||||
ConnectionCompletionTime_ =
|
||||
std::chrono::high_resolution_clock::now() - ConnectionStart_;
|
||||
State_.connectionCompletionTime = ConnectionCompletionTime_.count();
|
||||
|
||||
if (State_.VerifiedCertificate == GWObjects::VALID_CERTIFICATE) {
|
||||
if (( Utils::SerialNumberMatch(CN_, SerialNumber_, (int)AP_WS_Server()->MismatchDepth())) ||
|
||||
if ((Utils::SerialNumberMatch(CN_, SerialNumber_,
|
||||
(int)AP_WS_Server()->MismatchDepth())) ||
|
||||
AP_WS_Server()->IsSimSerialNumber(CN_)) {
|
||||
State_.VerifiedCertificate = GWObjects::VERIFIED;
|
||||
poco_information(Logger_, fmt::format("CONNECT({}): Fully validated and authenticated device. Session={} ConnectionCompletion Time={}",
|
||||
CId_,
|
||||
State_.sessionId,
|
||||
poco_information(Logger_,
|
||||
fmt::format("CONNECT({}): Fully validated and authenticated "
|
||||
"device. Session={} ConnectionCompletion Time={}",
|
||||
CId_, State_.sessionId,
|
||||
State_.connectionCompletionTime));
|
||||
} else {
|
||||
State_.VerifiedCertificate = GWObjects::MISMATCH_SERIAL;
|
||||
if (AP_WS_Server()->AllowSerialNumberMismatch()) {
|
||||
poco_information(
|
||||
Logger_, fmt::format("CONNECT({}): Serial number mismatch allowed. CN={} Serial={} Session={} ConnectionCompletion Time={}",
|
||||
Logger_,
|
||||
fmt::format("CONNECT({}): Serial number mismatch allowed. CN={} "
|
||||
"Serial={} Session={} ConnectionCompletion Time={}",
|
||||
CId_, CN_, SerialNumber_, State_.sessionId,
|
||||
State_.connectionCompletionTime));
|
||||
} else {
|
||||
poco_information(
|
||||
Logger_, fmt::format("CONNECT({}): Serial number mismatch disallowed. Device rejected. CN={} Serial={} Session={}",
|
||||
Logger_, fmt::format("CONNECT({}): Serial number mismatch disallowed. "
|
||||
"Device rejected. CN={} Serial={} Session={}",
|
||||
CId_, CN_, SerialNumber_, State_.sessionId));
|
||||
return EndConnection();
|
||||
}
|
||||
@@ -159,7 +168,8 @@ namespace OpenWifi {
|
||||
Notification.content.serialNumber = SerialNumber_;
|
||||
GWWebSocketNotifications::DeviceConnected(Notification);
|
||||
|
||||
// std::cout << "Serial: " << SerialNumber_ << "Session: " << State_.sessionId << std::endl;
|
||||
// std::cout << "Serial: " << SerialNumber_ << "Session: " << State_.sessionId <<
|
||||
// std::endl;
|
||||
|
||||
if (KafkaManager()->Enabled()) {
|
||||
Poco::JSON::Stringifier Stringify;
|
||||
@@ -172,9 +182,12 @@ namespace OpenWifi {
|
||||
KafkaManager()->PostMessage(KafkaTopics::CONNECTION, SerialNumber_, OS.str());
|
||||
}
|
||||
} else {
|
||||
poco_warning(Logger_,fmt::format("INVALID-PROTOCOL({}): Missing one of uuid, firmware, or capabilities", CId_));
|
||||
poco_warning(
|
||||
Logger_,
|
||||
fmt::format("INVALID-PROTOCOL({}): Missing one of uuid, firmware, or capabilities",
|
||||
CId_));
|
||||
Errors_++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -5,8 +5,8 @@
|
||||
#include "AP_WS_Connection.h"
|
||||
#include "StorageService.h"
|
||||
|
||||
#include "framework/ow_constants.h"
|
||||
#include "fmt/format.h"
|
||||
#include "framework/ow_constants.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
void AP_WS_Connection::Process_crashlog(Poco::JSON::Object::Ptr ParamsObj) {
|
||||
@@ -34,4 +34,4 @@ namespace OpenWifi {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -9,10 +9,12 @@
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
void AP_WS_Connection::Process_deviceupdate(Poco::JSON::Object::Ptr ParamsObj, std::string &Serial) {
|
||||
void AP_WS_Connection::Process_deviceupdate(Poco::JSON::Object::Ptr ParamsObj,
|
||||
std::string &Serial) {
|
||||
if (!State_.Connected) {
|
||||
poco_warning(Logger_, fmt::format(
|
||||
"INVALID-PROTOCOL({}): Device '{}' is not following protocol", CId_, CN_));
|
||||
poco_warning(Logger_,
|
||||
fmt::format("INVALID-PROTOCOL({}): Device '{}' is not following protocol",
|
||||
CId_, CN_));
|
||||
Errors_++;
|
||||
return;
|
||||
}
|
||||
@@ -20,8 +22,10 @@ namespace OpenWifi {
|
||||
auto Password = ParamsObj->get("currentPassword").toString();
|
||||
|
||||
StorageService()->SetDevicePassword(Serial, Password);
|
||||
poco_trace(Logger_, fmt::format("DEVICEUPDATE({}): Device is updating its login password.", Serial));
|
||||
poco_trace(
|
||||
Logger_,
|
||||
fmt::format("DEVICEUPDATE({}): Device is updating its login password.", Serial));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -4,16 +4,16 @@
|
||||
#include "AP_WS_Connection.h"
|
||||
#include "StorageService.h"
|
||||
|
||||
#include "framework/ow_constants.h"
|
||||
#include "fmt/format.h"
|
||||
#include "framework/KafkaManager.h"
|
||||
#include "framework/ow_constants.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
void AP_WS_Connection::Process_event(Poco::JSON::Object::Ptr ParamsObj) {
|
||||
if (!State_.Connected) {
|
||||
poco_warning(
|
||||
Logger_,
|
||||
fmt::format("INVALID-PROTOCOL({}): Device '{}' is not following protocol", CId_, CN_));
|
||||
poco_warning(Logger_,
|
||||
fmt::format("INVALID-PROTOCOL({}): Device '{}' is not following protocol",
|
||||
CId_, CN_));
|
||||
Errors_++;
|
||||
return;
|
||||
}
|
||||
@@ -44,7 +44,6 @@ namespace OpenWifi {
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.log(E);
|
||||
} catch (...) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -5,16 +5,17 @@
|
||||
#include "AP_WS_Connection.h"
|
||||
#include "StorageService.h"
|
||||
|
||||
#include "fmt/format.h"
|
||||
#include "framework/KafkaManager.h"
|
||||
#include "framework/utils.h"
|
||||
#include "fmt/format.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
void AP_WS_Connection::Process_healthcheck(Poco::JSON::Object::Ptr ParamsObj) {
|
||||
if (!State_.Connected) {
|
||||
poco_warning(Logger_, fmt::format(
|
||||
"INVALID-PROTOCOL({}): Device '{}' is not following protocol", CId_, CN_));
|
||||
poco_warning(Logger_,
|
||||
fmt::format("INVALID-PROTOCOL({}): Device '{}' is not following protocol",
|
||||
CId_, CN_));
|
||||
Errors_++;
|
||||
return;
|
||||
}
|
||||
@@ -31,12 +32,10 @@ namespace OpenWifi {
|
||||
request_uuid = ParamsObj->get(uCentralProtocol::REQUEST_UUID).toString();
|
||||
|
||||
if (request_uuid.empty()) {
|
||||
poco_trace(Logger_,
|
||||
fmt::format("HEALTHCHECK({}): UUID={} Updating.", CId_, UUID));
|
||||
poco_trace(Logger_, fmt::format("HEALTHCHECK({}): UUID={} Updating.", CId_, UUID));
|
||||
} else {
|
||||
poco_trace(Logger_,
|
||||
fmt::format("HEALTHCHECK({}): UUID={} Updating for CMD={}.", CId_,
|
||||
UUID, request_uuid));
|
||||
poco_trace(Logger_, fmt::format("HEALTHCHECK({}): UUID={} Updating for CMD={}.",
|
||||
CId_, UUID, request_uuid));
|
||||
}
|
||||
|
||||
uint64_t UpgradedUUID;
|
||||
@@ -71,4 +70,4 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -5,15 +5,15 @@
|
||||
#include "AP_WS_Connection.h"
|
||||
#include "StorageService.h"
|
||||
|
||||
#include "framework/ow_constants.h"
|
||||
#include "fmt/format.h"
|
||||
#include "framework/ow_constants.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
void AP_WS_Connection::Process_log(Poco::JSON::Object::Ptr ParamsObj) {
|
||||
if (!State_.Connected) {
|
||||
poco_warning(
|
||||
Logger_,
|
||||
fmt::format("INVALID-PROTOCOL({}): Device '{}' is not following protocol", CId_, CN_));
|
||||
poco_warning(Logger_,
|
||||
fmt::format("INVALID-PROTOCOL({}): Device '{}' is not following protocol",
|
||||
CId_, CN_));
|
||||
Errors_++;
|
||||
return;
|
||||
}
|
||||
@@ -41,4 +41,4 @@ namespace OpenWifi {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -15,4 +15,4 @@ namespace OpenWifi {
|
||||
poco_warning(Logger_, fmt::format("PING({}): Missing parameter.", CId_));
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -3,12 +3,11 @@
|
||||
//
|
||||
|
||||
#include "AP_WS_Connection.h"
|
||||
#include "StorageService.h"
|
||||
#include "CommandManager.h"
|
||||
#include "StorageService.h"
|
||||
|
||||
#include "framework/ow_constants.h"
|
||||
#include "framework/MicroServiceFuncs.h"
|
||||
#include "fmt/format.h"
|
||||
#include "framework/MicroServiceFuncs.h"
|
||||
#include "framework/ow_constants.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
@@ -52,16 +51,24 @@ namespace OpenWifi {
|
||||
Poco::JSON::Stringifier::stringify(Params, O);
|
||||
Cmd.Details = O.str();
|
||||
bool Sent;
|
||||
CommandManager()->PostCommand(CommandManager()->Next_RPC_ID(), APCommands::Commands::reboot, SerialNumber_, Cmd.Command, Params, Cmd.UUID, Sent, false, false);
|
||||
StorageService()->AddCommand(SerialNumber_, Cmd, Storage::CommandExecutionType::COMMAND_EXECUTED);
|
||||
poco_information(Logger_, fmt::format("RECOVERY({}): Recovery mode received, need for a reboot.", CId_));
|
||||
CommandManager()->PostCommand(CommandManager()->Next_RPC_ID(),
|
||||
APCommands::Commands::reboot, SerialNumber_,
|
||||
Cmd.Command, Params, Cmd.UUID, Sent, false, false);
|
||||
StorageService()->AddCommand(SerialNumber_, Cmd,
|
||||
Storage::CommandExecutionType::COMMAND_EXECUTED);
|
||||
poco_information(
|
||||
Logger_,
|
||||
fmt::format("RECOVERY({}): Recovery mode received, need for a reboot.", CId_));
|
||||
} else {
|
||||
poco_information(Logger_, fmt::format(
|
||||
"RECOVERY({}): Recovery mode received, no need for a reboot.", CId_));
|
||||
poco_information(
|
||||
Logger_,
|
||||
fmt::format("RECOVERY({}): Recovery mode received, no need for a reboot.",
|
||||
CId_));
|
||||
}
|
||||
} else {
|
||||
poco_warning(Logger_, fmt::format("RECOVERY({}): Recovery missing one of serialnumber, firmware, uuid, loglines, reboot",
|
||||
poco_warning(Logger_, fmt::format("RECOVERY({}): Recovery missing one of serialnumber, "
|
||||
"firmware, uuid, loglines, reboot",
|
||||
CId_));
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -3,8 +3,8 @@
|
||||
//
|
||||
|
||||
#include "AP_WS_Connection.h"
|
||||
#include "StorageService.h"
|
||||
#include "StateUtils.h"
|
||||
#include "StorageService.h"
|
||||
|
||||
#include "UI_GW_WebSocketNotifications.h"
|
||||
|
||||
@@ -16,8 +16,9 @@
|
||||
namespace OpenWifi {
|
||||
void AP_WS_Connection::Process_state(Poco::JSON::Object::Ptr ParamsObj) {
|
||||
if (!State_.Connected) {
|
||||
poco_warning(Logger_, fmt::format(
|
||||
"INVALID-PROTOCOL({}): Device '{}' is not following protocol", CId_, CN_));
|
||||
poco_warning(Logger_,
|
||||
fmt::format("INVALID-PROTOCOL({}): Device '{}' is not following protocol",
|
||||
CId_, CN_));
|
||||
Errors_++;
|
||||
return;
|
||||
}
|
||||
@@ -34,8 +35,8 @@ namespace OpenWifi {
|
||||
if (request_uuid.empty()) {
|
||||
poco_trace(Logger_, fmt::format("STATE({}): UUID={} Updating.", CId_, UUID));
|
||||
} else {
|
||||
poco_trace(Logger_, fmt::format("STATE({}): UUID={} Updating for CMD={}.",
|
||||
CId_, UUID, request_uuid));
|
||||
poco_trace(Logger_, fmt::format("STATE({}): UUID={} Updating for CMD={}.", CId_,
|
||||
UUID, request_uuid));
|
||||
}
|
||||
|
||||
uint64_t UpgradedUUID;
|
||||
@@ -52,9 +53,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
StateUtils::ComputeAssociations(StateObj, State_.Associations_2G,
|
||||
State_.Associations_5G,
|
||||
State_.Associations_6G
|
||||
);
|
||||
State_.Associations_5G, State_.Associations_6G);
|
||||
|
||||
if (KafkaManager()->Enabled()) {
|
||||
Poco::JSON::Stringifier Stringify;
|
||||
@@ -68,7 +67,9 @@ namespace OpenWifi {
|
||||
GWWebSocketNotifications::DeviceStatistics(N);
|
||||
|
||||
} else {
|
||||
poco_warning(Logger_, fmt::format("STATE({}): Invalid request. Missing serial, uuid, or state", CId_));
|
||||
}
|
||||
poco_warning(
|
||||
Logger_,
|
||||
fmt::format("STATE({}): Invalid request. Missing serial, uuid, or state", CId_));
|
||||
}
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -3,18 +3,19 @@
|
||||
//
|
||||
|
||||
#include "AP_WS_Connection.h"
|
||||
#include "TelemetryStream.h"
|
||||
#include "CommandManager.h"
|
||||
#include "TelemetryStream.h"
|
||||
|
||||
#include "fmt/format.h"
|
||||
#include "framework/KafkaManager.h"
|
||||
#include "framework/utils.h"
|
||||
#include "fmt/format.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
void AP_WS_Connection::Process_telemetry(Poco::JSON::Object::Ptr ParamsObj) {
|
||||
if (!State_.Connected) {
|
||||
poco_warning(Logger_, fmt::format(
|
||||
"INVALID-PROTOCOL({}): Device '{}' is not following protocol", CId_, CN_));
|
||||
poco_warning(Logger_,
|
||||
fmt::format("INVALID-PROTOCOL({}): Device '{}' is not following protocol",
|
||||
CId_, CN_));
|
||||
Errors_++;
|
||||
return;
|
||||
}
|
||||
@@ -33,7 +34,8 @@ namespace OpenWifi {
|
||||
}
|
||||
if (TelemetryWebSocketRefCount_) {
|
||||
if (now < TelemetryWebSocketTimer_) {
|
||||
// std::cout << SerialNumber_ << ": Updating WebSocket telemetry" << std::endl;
|
||||
// std::cout << SerialNumber_ << ": Updating WebSocket telemetry" <<
|
||||
// std::endl;
|
||||
TelemetryWebSocketPackets_++;
|
||||
State_.websocketPackets = TelemetryWebSocketPackets_;
|
||||
TelemetryStream()->NotifyEndPoint(SerialNumberInt_, SS.str());
|
||||
@@ -53,12 +55,14 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
poco_debug(Logger_,fmt::format("TELEMETRY({}): Invalid telemetry packet.",SerialNumber_));
|
||||
poco_debug(Logger_,
|
||||
fmt::format("TELEMETRY({}): Invalid telemetry packet.", SerialNumber_));
|
||||
}
|
||||
} else {
|
||||
// if we are ignoring telemetry, then close it down on the device.
|
||||
poco_debug(Logger_,fmt::format("TELEMETRY({}): Stopping runaway telemetry.",SerialNumber_));
|
||||
poco_debug(Logger_,
|
||||
fmt::format("TELEMETRY({}): Stopping runaway telemetry.", SerialNumber_));
|
||||
StopTelemetry(CommandManager()->Next_RPC_ID());
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -8,10 +8,9 @@
|
||||
namespace OpenWifi {
|
||||
void AP_WS_Connection::Process_venuebroadcast(Poco::JSON::Object::Ptr ParamsObj) {
|
||||
if (ParamsObj->has("data") && ParamsObj->has("serial") && ParamsObj->has("timestamp")) {
|
||||
VenueBroadcaster()->Broadcast(
|
||||
ParamsObj->get("serial").toString(),
|
||||
VenueBroadcaster()->Broadcast(ParamsObj->get("serial").toString(),
|
||||
ParamsObj->get("data").toString(),
|
||||
ParamsObj->get("timestamp"));
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -4,16 +4,16 @@
|
||||
#include "AP_WS_Connection.h"
|
||||
#include "StorageService.h"
|
||||
|
||||
#include "framework/ow_constants.h"
|
||||
#include "fmt/format.h"
|
||||
#include "framework/KafkaManager.h"
|
||||
#include "framework/ow_constants.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
void AP_WS_Connection::Process_wifiscan(Poco::JSON::Object::Ptr ParamsObj) {
|
||||
if (!State_.Connected) {
|
||||
poco_warning(
|
||||
Logger_,
|
||||
fmt::format("INVALID-PROTOCOL({}): Device '{}' is not following protocol", CId_, CN_));
|
||||
poco_warning(Logger_,
|
||||
fmt::format("INVALID-PROTOCOL({}): Device '{}' is not following protocol",
|
||||
CId_, CN_));
|
||||
Errors_++;
|
||||
return;
|
||||
}
|
||||
@@ -29,4 +29,4 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -4,11 +4,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <shared_mutex>
|
||||
#include <string>
|
||||
|
||||
#include "Poco/Net/SocketAcceptor.h"
|
||||
#include "Poco/Environment.h"
|
||||
#include "Poco/Net/SocketAcceptor.h"
|
||||
|
||||
#include "framework/utils.h"
|
||||
|
||||
@@ -21,9 +21,7 @@ namespace OpenWifi {
|
||||
NumberOfThreads_ = 4;
|
||||
}
|
||||
|
||||
~ AP_WS_ReactorThreadPool() {
|
||||
Stop();
|
||||
}
|
||||
~AP_WS_ReactorThreadPool() { Stop(); }
|
||||
|
||||
void Start() {
|
||||
for (uint64_t i = 0; i < NumberOfThreads_; ++i) {
|
||||
@@ -61,4 +59,4 @@ namespace OpenWifi {
|
||||
std::vector<std::unique_ptr<Poco::Net::SocketReactor>> Reactors_;
|
||||
std::vector<std::unique_ptr<Poco::Thread>> Threads_;
|
||||
};
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -6,35 +6,41 @@
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
#include "Poco/Net/HTTPHeaderStream.h"
|
||||
#include "Poco/Net/Context.h"
|
||||
#include "Poco/Net/HTTPHeaderStream.h"
|
||||
#include "Poco/Net/HTTPServerRequest.h"
|
||||
|
||||
#include "AP_WS_Server.h"
|
||||
#include "AP_WS_Connection.h"
|
||||
#include "AP_WS_Server.h"
|
||||
#include "ConfigurationCache.h"
|
||||
#include "TelemetryStream.h"
|
||||
|
||||
#include "framework/MicroServiceFuncs.h"
|
||||
#include "framework/utils.h"
|
||||
#include "UI_GW_WebSocketNotifications.h"
|
||||
#include "fmt/format.h"
|
||||
#include "framework/MicroServiceFuncs.h"
|
||||
#include "framework/utils.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
void AP_WS_RequestHandler::handleRequest(Poco::Net::HTTPServerRequest &request,
|
||||
Poco::Net::HTTPServerResponse &response) {
|
||||
try {
|
||||
AP_WS_Server()->AddConnection(id_,std::make_shared<AP_WS_Connection>(request,response,id_, Logger_, AP_WS_Server()->NextReactor()));
|
||||
AP_WS_Server()->AddConnection(
|
||||
id_, std::make_shared<AP_WS_Connection>(request, response, id_, Logger_,
|
||||
AP_WS_Server()->NextReactor()));
|
||||
} catch (...) {
|
||||
poco_warning(Logger_, "Exception during WS creation");
|
||||
}
|
||||
};
|
||||
|
||||
bool AP_WS_Server::ValidateCertificate(const std::string & ConnectionId, const Poco::Crypto::X509Certificate & Certificate) {
|
||||
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()));
|
||||
poco_warning(
|
||||
Logger(),
|
||||
fmt::format("CERTIFICATE({}): issuer mismatch. Local='{}' Incoming='{}'",
|
||||
ConnectionId, IssuerCert_->issuerName(), Certificate.issuerName()));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -44,7 +50,8 @@ namespace OpenWifi {
|
||||
|
||||
int AP_WS_Server::Start() {
|
||||
|
||||
AllowSerialNumberMismatch_ = MicroServiceConfigGetBool("openwifi.certificates.allowmismatch",true);
|
||||
AllowSerialNumberMismatch_ =
|
||||
MicroServiceConfigGetBool("openwifi.certificates.allowmismatch", true);
|
||||
MismatchDepth_ = MicroServiceConfigGetInt("openwifi.certificates.mismatchdepth", 2);
|
||||
|
||||
Reactor_pool_ = std::make_unique<AP_WS_ReactorThreadPool>();
|
||||
@@ -52,7 +59,8 @@ namespace OpenWifi {
|
||||
|
||||
for (const auto &Svr : ConfigServersList_) {
|
||||
|
||||
poco_notice(Logger(),fmt::format("Starting: {}:{} Keyfile:{} CertFile: {}", Svr.Address(),
|
||||
poco_notice(Logger(),
|
||||
fmt::format("Starting: {}:{} Keyfile:{} CertFile: {}", Svr.Address(),
|
||||
Svr.Port(), Svr.KeyFile(), Svr.CertFile()));
|
||||
|
||||
Svr.LogCert(Logger());
|
||||
@@ -61,8 +69,8 @@ namespace OpenWifi {
|
||||
|
||||
if (!IsCertOk()) {
|
||||
IssuerCert_ = std::make_unique<Poco::Crypto::X509Certificate>(Svr.IssuerCertFile());
|
||||
poco_information(Logger(),
|
||||
fmt::format("Certificate Issuer Name:{}", IssuerCert_->issuerName()));
|
||||
poco_information(
|
||||
Logger(), fmt::format("Certificate Issuer Name:{}", IssuerCert_->issuerName()));
|
||||
}
|
||||
|
||||
Poco::Net::Context::Params P;
|
||||
@@ -74,7 +82,8 @@ namespace OpenWifi {
|
||||
P.dhUse2048Bits = true;
|
||||
P.caLocation = Svr.Cas();
|
||||
|
||||
auto Context = Poco::AutoPtr<Poco::Net::Context>(new Poco::Net::Context(Poco::Net::Context::TLS_SERVER_USE, P));
|
||||
auto Context = Poco::AutoPtr<Poco::Net::Context>(
|
||||
new Poco::Net::Context(Poco::Net::Context::TLS_SERVER_USE, P));
|
||||
|
||||
Poco::Crypto::X509Certificate Cert(Svr.CertFile());
|
||||
Poco::Crypto::X509Certificate Root(Svr.RootCA());
|
||||
@@ -96,7 +105,8 @@ namespace OpenWifi {
|
||||
Context->enableSessionCache(true);
|
||||
Context->enableExtendedCertificateVerification(false);
|
||||
// Context->disableStatelessSessionResumption();
|
||||
Context->disableProtocols(Poco::Net::Context::PROTO_TLSV1 | Poco::Net::Context::PROTO_TLSV1_1);
|
||||
Context->disableProtocols(Poco::Net::Context::PROTO_TLSV1 |
|
||||
Poco::Net::Context::PROTO_TLSV1_1);
|
||||
|
||||
auto WebServerHttpParams = new Poco::Net::HTTPServerParams;
|
||||
WebServerHttpParams->setMaxThreads(50);
|
||||
@@ -110,13 +120,17 @@ namespace OpenWifi {
|
||||
: Poco::Net::AddressFamily::IPv4));
|
||||
Poco::Net::SocketAddress SockAddr(Addr, Svr.Port());
|
||||
auto NewWebServer = std::make_unique<Poco::Net::HTTPServer>(
|
||||
new AP_WS_RequestHandlerFactory(Logger()), DeviceConnectionPool_, Poco::Net::SecureServerSocket(SockAddr, Svr.Backlog(), Context), WebServerHttpParams);
|
||||
new AP_WS_RequestHandlerFactory(Logger()), DeviceConnectionPool_,
|
||||
Poco::Net::SecureServerSocket(SockAddr, Svr.Backlog(), Context),
|
||||
WebServerHttpParams);
|
||||
WebServers_.push_back(std::move(NewWebServer));
|
||||
} else {
|
||||
Poco::Net::IPAddress Addr(Svr.Address());
|
||||
Poco::Net::SocketAddress SockAddr(Addr, Svr.Port());
|
||||
auto NewWebServer = std::make_unique<Poco::Net::HTTPServer>(
|
||||
new AP_WS_RequestHandlerFactory(Logger()), DeviceConnectionPool_, Poco::Net::SecureServerSocket(SockAddr, Svr.Backlog(), Context), WebServerHttpParams);
|
||||
new AP_WS_RequestHandlerFactory(Logger()), DeviceConnectionPool_,
|
||||
Poco::Net::SecureServerSocket(SockAddr, Svr.Backlog(), Context),
|
||||
WebServerHttpParams);
|
||||
WebServers_.push_back(std::move(NewWebServer));
|
||||
}
|
||||
}
|
||||
@@ -144,7 +158,8 @@ namespace OpenWifi {
|
||||
SimulatorEnabled_ = !SimulatorId_.empty();
|
||||
Utils::SetThreadName(ReactorThread_, "dev:react:head");
|
||||
|
||||
GarbageCollectorCallback_ = std::make_unique<Poco::TimerCallback<AP_WS_Server>>(*this,&AP_WS_Server::onGarbageCollecting);
|
||||
GarbageCollectorCallback_ = std::make_unique<Poco::TimerCallback<AP_WS_Server>>(
|
||||
*this, &AP_WS_Server::onGarbageCollecting);
|
||||
Timer_.setStartInterval(10 * 1000);
|
||||
Timer_.setPeriodicInterval(5 * 1000); // every minute
|
||||
Timer_.start(*GarbageCollectorCallback_, MicroServiceTimerPool());
|
||||
@@ -179,12 +194,16 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
|
||||
AverageDeviceConnectionTime_ = (NumberOfConnectedDevices_!=0) ? total_connected_time/NumberOfConnectedDevices_ : 0;
|
||||
AverageDeviceConnectionTime_ =
|
||||
(NumberOfConnectedDevices_ != 0) ? total_connected_time / NumberOfConnectedDevices_ : 0;
|
||||
if ((now - last_log) > 120) {
|
||||
last_log = now;
|
||||
poco_information(Logger(),
|
||||
fmt::format("Active AP connections: {} Connecting: {} Average connection time: {} seconds",
|
||||
NumberOfConnectedDevices_, NumberOfConnectingDevices_, AverageDeviceConnectionTime_));
|
||||
poco_information(
|
||||
Logger(),
|
||||
fmt::format(
|
||||
"Active AP connections: {} Connecting: {} Average connection time: {} seconds",
|
||||
NumberOfConnectedDevices_, NumberOfConnectingDevices_,
|
||||
AverageDeviceConnectionTime_));
|
||||
}
|
||||
|
||||
GWWebSocketNotifications::NumberOfConnection_t Notification;
|
||||
@@ -237,7 +256,8 @@ namespace OpenWifi {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AP_WS_Server::GetHealthcheck(uint64_t SerialNumber, GWObjects::HealthCheck & CheckData) const {
|
||||
bool AP_WS_Server::GetHealthcheck(uint64_t SerialNumber,
|
||||
GWObjects::HealthCheck &CheckData) const {
|
||||
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||
{
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
@@ -291,7 +311,8 @@ namespace OpenWifi {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AP_WS_Server::Connected(uint64_t SerialNumber, GWObjects::DeviceRestrictions & Restrictions) const {
|
||||
bool AP_WS_Server::Connected(uint64_t SerialNumber,
|
||||
GWObjects::DeviceRestrictions &Restrictions) const {
|
||||
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||
{
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
@@ -331,7 +352,8 @@ namespace OpenWifi {
|
||||
try {
|
||||
return DevicePtr->Send(Payload);
|
||||
} catch (...) {
|
||||
poco_debug(Logger(),fmt::format(": SendFrame: Could not send data to device '{}'", Utils::IntToSerialNumber(SerialNumber)));
|
||||
poco_debug(Logger(), fmt::format(": SendFrame: Could not send data to device '{}'",
|
||||
Utils::IntToSerialNumber(SerialNumber)));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -350,7 +372,10 @@ namespace OpenWifi {
|
||||
DevicePtr->StopWebSocketTelemetry(RPCID);
|
||||
}
|
||||
|
||||
void AP_WS_Server::SetWebSocketTelemetryReporting(uint64_t RPCID, uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime, const std::vector<std::string> & TelemetryTypes) {
|
||||
void
|
||||
AP_WS_Server::SetWebSocketTelemetryReporting(uint64_t RPCID, uint64_t SerialNumber,
|
||||
uint64_t Interval, uint64_t Lifetime,
|
||||
const std::vector<std::string> &TelemetryTypes) {
|
||||
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||
{
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
@@ -363,7 +388,9 @@ namespace OpenWifi {
|
||||
DevicePtr->SetWebSocketTelemetryReporting(RPCID, Interval, Lifetime, TelemetryTypes);
|
||||
}
|
||||
|
||||
void AP_WS_Server::SetKafkaTelemetryReporting(uint64_t RPCID, uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime, const std::vector<std::string> & TelemetryTypes) {
|
||||
void AP_WS_Server::SetKafkaTelemetryReporting(uint64_t RPCID, uint64_t SerialNumber,
|
||||
uint64_t Interval, uint64_t Lifetime,
|
||||
const std::vector<std::string> &TelemetryTypes) {
|
||||
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||
{
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
@@ -389,14 +416,11 @@ namespace OpenWifi {
|
||||
DevicePtr->StopKafkaTelemetry(RPCID);
|
||||
}
|
||||
|
||||
void AP_WS_Server::GetTelemetryParameters(uint64_t SerialNumber , bool & TelemetryRunning,
|
||||
uint64_t & TelemetryInterval,
|
||||
uint64_t & TelemetryWebSocketTimer,
|
||||
uint64_t & TelemetryKafkaTimer,
|
||||
uint64_t & TelemetryWebSocketCount,
|
||||
uint64_t & TelemetryKafkaCount,
|
||||
uint64_t & TelemetryWebSocketPackets,
|
||||
uint64_t & TelemetryKafkaPackets) {
|
||||
void AP_WS_Server::GetTelemetryParameters(
|
||||
uint64_t SerialNumber, bool &TelemetryRunning, uint64_t &TelemetryInterval,
|
||||
uint64_t &TelemetryWebSocketTimer, uint64_t &TelemetryKafkaTimer,
|
||||
uint64_t &TelemetryWebSocketCount, uint64_t &TelemetryKafkaCount,
|
||||
uint64_t &TelemetryWebSocketPackets, uint64_t &TelemetryKafkaPackets) {
|
||||
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||
{
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
@@ -406,13 +430,14 @@ namespace OpenWifi {
|
||||
}
|
||||
DevicePtr = Device->second.second;
|
||||
}
|
||||
DevicePtr->GetTelemetryParameters(
|
||||
TelemetryRunning, TelemetryInterval, TelemetryWebSocketTimer, TelemetryKafkaTimer,
|
||||
TelemetryWebSocketCount, TelemetryKafkaCount, TelemetryWebSocketPackets,
|
||||
TelemetryKafkaPackets);
|
||||
DevicePtr->GetTelemetryParameters(TelemetryRunning, TelemetryInterval,
|
||||
TelemetryWebSocketTimer, TelemetryKafkaTimer,
|
||||
TelemetryWebSocketCount, TelemetryKafkaCount,
|
||||
TelemetryWebSocketPackets, TelemetryKafkaPackets);
|
||||
}
|
||||
|
||||
bool AP_WS_Server::SendRadiusAccountingData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size) {
|
||||
bool AP_WS_Server::SendRadiusAccountingData(const std::string &SerialNumber,
|
||||
const unsigned char *buffer, std::size_t size) {
|
||||
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||
{
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
@@ -426,12 +451,16 @@ namespace OpenWifi {
|
||||
try {
|
||||
return DevicePtr->SendRadiusAccountingData(buffer, size);
|
||||
} catch (...) {
|
||||
poco_debug(Logger(),fmt::format(": SendRadiusAuthenticationData: Could not send data to device '{}'", SerialNumber));
|
||||
poco_debug(
|
||||
Logger(),
|
||||
fmt::format(": SendRadiusAuthenticationData: Could not send data to device '{}'",
|
||||
SerialNumber));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AP_WS_Server::SendRadiusAuthenticationData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size) {
|
||||
bool AP_WS_Server::SendRadiusAuthenticationData(const std::string &SerialNumber,
|
||||
const unsigned char *buffer, std::size_t size) {
|
||||
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||
{
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
@@ -445,12 +474,16 @@ namespace OpenWifi {
|
||||
try {
|
||||
return DevicePtr->SendRadiusAuthenticationData(buffer, size);
|
||||
} catch (...) {
|
||||
poco_debug(Logger(),fmt::format(": SendRadiusAuthenticationData: Could not send data to device '{}'", SerialNumber));
|
||||
poco_debug(
|
||||
Logger(),
|
||||
fmt::format(": SendRadiusAuthenticationData: Could not send data to device '{}'",
|
||||
SerialNumber));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AP_WS_Server::SendRadiusCoAData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size) {
|
||||
bool AP_WS_Server::SendRadiusCoAData(const std::string &SerialNumber,
|
||||
const unsigned char *buffer, std::size_t size) {
|
||||
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||
{
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
@@ -464,9 +497,11 @@ namespace OpenWifi {
|
||||
try {
|
||||
return DevicePtr->SendRadiusCoAData(buffer, size);
|
||||
} catch (...) {
|
||||
poco_debug(Logger(),fmt::format(": SendRadiusCoAData: Could not send data to device '{}'", SerialNumber));
|
||||
poco_debug(Logger(),
|
||||
fmt::format(": SendRadiusCoAData: Could not send data to device '{}'",
|
||||
SerialNumber));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} //namespace
|
||||
} // namespace OpenWifi
|
||||
@@ -8,38 +8,36 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <array>
|
||||
#include <ctime>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
|
||||
#include "Poco/AutoPtr.h"
|
||||
#include "Poco/Net/SocketReactor.h"
|
||||
#include "Poco/Net/ParallelSocketAcceptor.h"
|
||||
#include "Poco/Net/SocketAcceptor.h"
|
||||
#include "Poco/Timer.h"
|
||||
#include "Poco/Net/HTTPRequestHandler.h"
|
||||
#include "Poco/Net/HTTPRequestHandlerFactory.h"
|
||||
#include "Poco/Net/HTTPServer.h"
|
||||
#include "Poco/Net/HTTPServerRequest.h"
|
||||
#include "Poco/Net/ParallelSocketAcceptor.h"
|
||||
#include "Poco/Net/SocketAcceptor.h"
|
||||
#include "Poco/Net/SocketReactor.h"
|
||||
#include "Poco/Timer.h"
|
||||
|
||||
#include "AP_WS_Connection.h"
|
||||
#include "AP_WS_ReactorPool.h"
|
||||
|
||||
#include "framework/utils.h"
|
||||
#include "framework/SubSystemServer.h"
|
||||
#include "framework/utils.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class AP_WS_RequestHandler : public Poco::Net::HTTPRequestHandler {
|
||||
public:
|
||||
explicit AP_WS_RequestHandler(Poco::Logger &L, uint64_t id)
|
||||
: Logger_(L),
|
||||
id_(id){
|
||||
};
|
||||
explicit AP_WS_RequestHandler(Poco::Logger &L, uint64_t id) : Logger_(L), id_(id){};
|
||||
|
||||
void handleRequest(Poco::Net::HTTPServerRequest &request,
|
||||
Poco::Net::HTTPServerResponse &response) override;
|
||||
|
||||
private:
|
||||
Poco::Logger &Logger_;
|
||||
uint64_t id_ = 0;
|
||||
@@ -47,9 +45,7 @@ namespace OpenWifi {
|
||||
|
||||
class AP_WS_RequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
|
||||
public:
|
||||
inline explicit AP_WS_RequestHandlerFactory(Poco::Logger &L)
|
||||
: Logger_(L) {
|
||||
}
|
||||
inline explicit AP_WS_RequestHandlerFactory(Poco::Logger &L) : Logger_(L) {}
|
||||
|
||||
inline Poco::Net::HTTPRequestHandler *
|
||||
createRequestHandler(const Poco::Net::HTTPServerRequest &request) override {
|
||||
@@ -61,6 +57,7 @@ namespace OpenWifi {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Poco::Logger &Logger_;
|
||||
inline static uint64_t id_ = 1;
|
||||
@@ -76,36 +73,35 @@ namespace OpenWifi {
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
bool IsCertOk() { return IssuerCert_ != nullptr; }
|
||||
bool ValidateCertificate(const std::string & ConnectionId, const Poco::Crypto::X509Certificate & Certificate);
|
||||
bool ValidateCertificate(const std::string &ConnectionId,
|
||||
const Poco::Crypto::X509Certificate &Certificate);
|
||||
// Poco::Net::SocketReactor & GetNextReactor() { return ReactorPool_.NextReactor(); }
|
||||
|
||||
inline bool IsSimSerialNumber(const std::string &SerialNumber) const {
|
||||
return IsSim(Poco::toLower(SerialNumber)) && Poco::toLower(SerialNumber) == Poco::toLower(SimulatorId_);
|
||||
return IsSim(Poco::toLower(SerialNumber)) &&
|
||||
Poco::toLower(SerialNumber) == Poco::toLower(SimulatorId_);
|
||||
}
|
||||
|
||||
inline static bool IsSim(const std::string &SerialNumber) {
|
||||
return SerialNumber.substr(0, 6) == "53494d";
|
||||
}
|
||||
|
||||
inline bool IsSimEnabled() const {
|
||||
return SimulatorEnabled_;
|
||||
}
|
||||
inline bool IsSimEnabled() const { return SimulatorEnabled_; }
|
||||
|
||||
inline bool AllowSerialNumberMismatch() const {
|
||||
return AllowSerialNumberMismatch_;
|
||||
}
|
||||
inline bool AllowSerialNumberMismatch() const { return AllowSerialNumberMismatch_; }
|
||||
|
||||
inline uint64_t MismatchDepth() const {
|
||||
return MismatchDepth_;
|
||||
}
|
||||
inline uint64_t MismatchDepth() const { return MismatchDepth_; }
|
||||
|
||||
inline bool UseProvisioning() const { return LookAtProvisioning_; }
|
||||
inline bool UseDefaults() const { return UseDefaultConfig_; }
|
||||
|
||||
[[nodiscard]] inline Poco::Net::SocketReactor & NextReactor() { return Reactor_pool_->NextReactor(); }
|
||||
[[nodiscard]] inline Poco::Net::SocketReactor &NextReactor() {
|
||||
return Reactor_pool_->NextReactor();
|
||||
}
|
||||
[[nodiscard]] inline bool Running() const { return Running_; }
|
||||
|
||||
inline void AddConnection(uint64_t session_id, std::shared_ptr<AP_WS_Connection> Connection ) {
|
||||
inline void AddConnection(uint64_t session_id,
|
||||
std::shared_ptr<AP_WS_Connection> Connection) {
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
Sessions_[session_id] = std::move(Connection);
|
||||
}
|
||||
@@ -124,12 +120,14 @@ namespace OpenWifi {
|
||||
}
|
||||
bool GetStatistics(uint64_t SerialNumber, std::string &Statistics) const;
|
||||
|
||||
inline bool GetState(const std::string & SerialNumber, GWObjects::ConnectionState & State) const {
|
||||
inline bool GetState(const std::string &SerialNumber,
|
||||
GWObjects::ConnectionState &State) const {
|
||||
return GetState(Utils::SerialNumberToInt(SerialNumber), State);
|
||||
}
|
||||
bool GetState(uint64_t SerialNumber, GWObjects::ConnectionState &State) const;
|
||||
|
||||
inline bool GetHealthcheck(const std::string &SerialNumber, GWObjects::HealthCheck & CheckData) const {
|
||||
inline bool GetHealthcheck(const std::string &SerialNumber,
|
||||
GWObjects::HealthCheck &CheckData) const {
|
||||
return GetHealthcheck(Utils::SerialNumberToInt(SerialNumber), CheckData);
|
||||
}
|
||||
bool GetHealthcheck(uint64_t SerialNumber, GWObjects::HealthCheck &CheckData) const;
|
||||
@@ -143,20 +141,26 @@ namespace OpenWifi {
|
||||
|
||||
bool SendFrame(uint64_t SerialNumber, const std::string &Payload) const;
|
||||
|
||||
bool SendRadiusAuthenticationData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size);
|
||||
bool SendRadiusAccountingData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size);
|
||||
bool SendRadiusCoAData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size);
|
||||
bool SendRadiusAuthenticationData(const std::string &SerialNumber,
|
||||
const unsigned char *buffer, std::size_t size);
|
||||
bool SendRadiusAccountingData(const std::string &SerialNumber, const unsigned char *buffer,
|
||||
std::size_t size);
|
||||
bool SendRadiusCoAData(const std::string &SerialNumber, const unsigned char *buffer,
|
||||
std::size_t size);
|
||||
|
||||
void SetSessionDetails(uint64_t connection_id, uint64_t SerialNumber);
|
||||
bool EndSession(uint64_t connection_id, uint64_t serial_number);
|
||||
|
||||
void SetWebSocketTelemetryReporting(uint64_t RPCID, uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime, const std::vector<std::string> & TelemetryTypes);
|
||||
void SetWebSocketTelemetryReporting(uint64_t RPCID, uint64_t SerialNumber,
|
||||
uint64_t Interval, uint64_t Lifetime,
|
||||
const std::vector<std::string> &TelemetryTypes);
|
||||
void StopWebSocketTelemetry(uint64_t RPCID, uint64_t SerialNumber);
|
||||
void SetKafkaTelemetryReporting(uint64_t RPCID, uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime, const std::vector<std::string> & TelemetryTypes);
|
||||
void SetKafkaTelemetryReporting(uint64_t RPCID, uint64_t SerialNumber, uint64_t Interval,
|
||||
uint64_t Lifetime,
|
||||
const std::vector<std::string> &TelemetryTypes);
|
||||
void StopKafkaTelemetry(uint64_t RPCID, uint64_t SerialNumber);
|
||||
void GetTelemetryParameters(uint64_t SerialNumber, bool &TelemetryRunning,
|
||||
uint64_t & TelemetryInterval,
|
||||
uint64_t & TelemetryWebSocketTimer,
|
||||
uint64_t &TelemetryInterval, uint64_t &TelemetryWebSocketTimer,
|
||||
uint64_t &TelemetryKafkaTimer,
|
||||
uint64_t &TelemetryWebSocketCount,
|
||||
uint64_t &TelemetryKafkaCount,
|
||||
@@ -165,7 +169,8 @@ namespace OpenWifi {
|
||||
|
||||
void onGarbageCollecting(Poco::Timer &timer);
|
||||
|
||||
inline void AverageDeviceStatistics( uint64_t & Connections, uint64_t & AverageConnectionTime, uint64_t & NumberOfConnectingDevices) const {
|
||||
inline void AverageDeviceStatistics(uint64_t &Connections, uint64_t &AverageConnectionTime,
|
||||
uint64_t &NumberOfConnectingDevices) const {
|
||||
Connections = NumberOfConnectedDevices_;
|
||||
AverageConnectionTime = AverageDeviceConnectionTime_;
|
||||
NumberOfConnectingDevices = NumberOfConnectingDevices_;
|
||||
@@ -200,11 +205,10 @@ namespace OpenWifi {
|
||||
Poco::Timer Timer_;
|
||||
Poco::Thread GarbageCollector_;
|
||||
|
||||
AP_WS_Server() noexcept:
|
||||
SubSystemServer("WebSocketServer", "WS-SVR", "ucentral.websocket") {
|
||||
}
|
||||
AP_WS_Server() noexcept
|
||||
: SubSystemServer("WebSocketServer", "WS-SVR", "ucentral.websocket") {}
|
||||
};
|
||||
|
||||
inline auto AP_WS_Server() { return AP_WS_Server::instance(); }
|
||||
|
||||
} //namespace
|
||||
} // namespace OpenWifi
|
||||
@@ -4,15 +4,15 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
#include "framework/MicroServiceFuncs.h"
|
||||
|
||||
#include "nlohmann/json.hpp"
|
||||
#include "CentralConfig.h"
|
||||
#include "nlohmann/json.hpp"
|
||||
|
||||
namespace OpenWifi {
|
||||
const std::string PlatformCacheFileName{"/plat_cache.json"};
|
||||
@@ -22,7 +22,6 @@ namespace OpenWifi {
|
||||
|
||||
class CapabilitiesCache {
|
||||
public:
|
||||
|
||||
static auto instance() {
|
||||
static auto instance = new CapabilitiesCache;
|
||||
return instance;
|
||||
@@ -101,7 +100,8 @@ namespace OpenWifi {
|
||||
std::map<std::string, std::string> Platforms_;
|
||||
CapabilitiesCache_t Capabilities_;
|
||||
std::string PlatformCacheFileName_{MicroServiceDataDirectory() + PlatformCacheFileName};
|
||||
std::string CapabilitiesCacheFileName_{ MicroServiceDataDirectory()+CapabilitiesCacheFileName };
|
||||
std::string CapabilitiesCacheFileName_{MicroServiceDataDirectory() +
|
||||
CapabilitiesCacheFileName};
|
||||
|
||||
inline void LoadPlatforms() {
|
||||
try {
|
||||
@@ -113,7 +113,6 @@ namespace OpenWifi {
|
||||
Platforms_[Type] = Platform;
|
||||
}
|
||||
} catch (...) {
|
||||
|
||||
}
|
||||
PlatformsLoaded_ = true;
|
||||
}
|
||||
@@ -124,13 +123,13 @@ namespace OpenWifi {
|
||||
nlohmann::json cache(Platforms_);
|
||||
i << cache;
|
||||
} catch (...) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
inline void LoadCapabilities() {
|
||||
try {
|
||||
std::ifstream i(CapabilitiesCacheFileName_, std::ios_base::binary|std::ios_base::in);
|
||||
std::ifstream i(CapabilitiesCacheFileName_,
|
||||
std::ios_base::binary | std::ios_base::in);
|
||||
nlohmann::json cache;
|
||||
i >> cache;
|
||||
|
||||
@@ -138,22 +137,21 @@ namespace OpenWifi {
|
||||
Capabilities_[Type] = Caps;
|
||||
}
|
||||
} catch (...) {
|
||||
|
||||
}
|
||||
CapabilitiesLoaded_ = true;
|
||||
}
|
||||
|
||||
inline void SaveCapabilities() {
|
||||
try {
|
||||
std::ofstream i(CapabilitiesCacheFileName_, std::ios_base::trunc | std::ios_base::out | std::ios_base::binary );
|
||||
std::ofstream i(CapabilitiesCacheFileName_,
|
||||
std::ios_base::trunc | std::ios_base::out | std::ios_base::binary);
|
||||
nlohmann::json cache(Capabilities_);
|
||||
i << cache;
|
||||
} catch (...) {
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
inline auto CapabilitiesCache() { return CapabilitiesCache::instance(); };
|
||||
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -7,9 +7,9 @@
|
||||
//
|
||||
#include <fstream>
|
||||
|
||||
#include "Poco/File.h"
|
||||
#include "Poco/JSON/Object.h"
|
||||
#include "Poco/JSON/Parser.h"
|
||||
#include "Poco/File.h"
|
||||
|
||||
#include "CentralConfig.h"
|
||||
#include "Daemon.h"
|
||||
@@ -150,7 +150,8 @@ R"lit(
|
||||
|
||||
void Config::SetBasicConfigFile() {
|
||||
try {
|
||||
Poco::File DefaultConfigFileName{MicroService::instance().DataDir() + "/default_config.json"};
|
||||
Poco::File DefaultConfigFileName{MicroService::instance().DataDir() +
|
||||
"/default_config.json"};
|
||||
DefaultConfiguration_ = BasicConfig;
|
||||
std::ofstream OS(DefaultConfigFileName.path(), std::ios::binary | std::ios::trunc);
|
||||
std::istringstream IS(DefaultConfiguration_);
|
||||
@@ -170,7 +171,8 @@ R"lit(
|
||||
if (DefaultConfiguration_.empty()) {
|
||||
// open the file
|
||||
try {
|
||||
Poco::File DefaultConfigFileName{MicroService::instance().DataDir()+"/default_config.json"};
|
||||
Poco::File DefaultConfigFileName{MicroService::instance().DataDir() +
|
||||
"/default_config.json"};
|
||||
if (!DefaultConfigFileName.exists()) {
|
||||
SetBasicConfigFile();
|
||||
} else {
|
||||
@@ -195,10 +197,9 @@ R"lit(
|
||||
Stringifier.condense(Object, NewConfig);
|
||||
Config_ = NewConfig.str();
|
||||
return true;
|
||||
}
|
||||
catch(const Poco::Exception &E)
|
||||
{
|
||||
std::cout << __func__ << ": new Configuration failed with " << E.displayText() << std::endl;
|
||||
} catch (const Poco::Exception &E) {
|
||||
std::cout << __func__ << ": new Configuration failed with " << E.displayText()
|
||||
<< std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -210,9 +211,7 @@ R"lit(
|
||||
if (object->has("uuid"))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
} catch (...) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -229,7 +228,8 @@ R"lit(
|
||||
}
|
||||
|
||||
/* std::string Capabilities::Default() {
|
||||
return std::string(R"lit({"model":{"id":"linksys,ea8300","name":"Linksys EA8300 (Dallas)"},
|
||||
return std::string(R"lit({"model":{"id":"linksys,ea8300","name":"Linksys EA8300
|
||||
(Dallas)"},
|
||||
"network":{"lan":{"ifname":"eth0","protocol":"static"},"wan":{"ifname":"eth1","protocol":"dhcp"}},
|
||||
"switch":{"switch0":{"enable":true,"reset":true,"ports":[{"num":0,"device":"eth0","need_tag":false,
|
||||
"want_untag":true},{"num":1,"role":"lan"},{"num":2,"role":"lan"},{"num":3,"role":"lan"},{"num":4,"role":"lan"}],
|
||||
@@ -259,27 +259,17 @@ R"lit(
|
||||
std::ostringstream OS;
|
||||
Caps->stringify(OS);
|
||||
AsString_ = OS.str();
|
||||
}
|
||||
catch ( const Poco::Exception & E )
|
||||
{
|
||||
} catch (const Poco::Exception &E) {
|
||||
Daemon()->logger().log(E);
|
||||
}
|
||||
}
|
||||
|
||||
const std::string & Capabilities::Compatible() const {
|
||||
return Compatible_;
|
||||
}
|
||||
const std::string &Capabilities::Compatible() const { return Compatible_; }
|
||||
|
||||
const std::string & Capabilities::Model() const {
|
||||
return Model_;
|
||||
}
|
||||
const std::string &Capabilities::Model() const { return Model_; }
|
||||
|
||||
const std::string & Capabilities::Platform() const {
|
||||
return Platform_;
|
||||
}
|
||||
const std::string &Capabilities::Platform() const { return Platform_; }
|
||||
|
||||
const std::string & Capabilities::AsString() const {
|
||||
return AsString_;
|
||||
}
|
||||
const std::string &Capabilities::AsString() const { return AsString_; }
|
||||
|
||||
} // namespace
|
||||
} // namespace OpenWifi::Config
|
||||
|
||||
@@ -8,16 +8,14 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "Poco/JSON/Object.h"
|
||||
#include <string>
|
||||
|
||||
namespace OpenWifi::Config {
|
||||
|
||||
class Config {
|
||||
public:
|
||||
explicit Config(const std::string &Config)
|
||||
:Config_(Config) {
|
||||
}
|
||||
explicit Config(const std::string &Config) : Config_(Config) {}
|
||||
|
||||
Config();
|
||||
bool SetUUID(uint64_t UUID);
|
||||
@@ -61,5 +59,4 @@ namespace OpenWifi::Config {
|
||||
void Parse();
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace OpenWifi::Config
|
||||
|
||||
@@ -10,11 +10,11 @@
|
||||
|
||||
#include "Poco/JSON/Parser.h"
|
||||
|
||||
#include "CommandManager.h"
|
||||
#include "AP_WS_Server.h"
|
||||
#include "CommandManager.h"
|
||||
#include "StorageService.h"
|
||||
#include "framework/ow_constants.h"
|
||||
#include "framework/MicroServiceFuncs.h"
|
||||
#include "framework/ow_constants.h"
|
||||
#include "framework/utils.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
@@ -35,21 +35,26 @@ namespace OpenWifi {
|
||||
std::string SerialNumberStr = Utils::IntToSerialNumber(Resp->SerialNumber_);
|
||||
|
||||
if (!Payload->has(uCentralProtocol::ID)) {
|
||||
poco_error(Logger(), fmt::format("({}): Invalid RPC response.", SerialNumberStr));
|
||||
poco_error(Logger(),
|
||||
fmt::format("({}): Invalid RPC response.", SerialNumberStr));
|
||||
} else {
|
||||
uint64_t ID = Payload->get(uCentralProtocol::ID);
|
||||
poco_debug(Logger(),fmt::format("({}): Processing {} response.", SerialNumberStr, ID));
|
||||
poco_debug(Logger(), fmt::format("({}): Processing {} response.",
|
||||
SerialNumberStr, ID));
|
||||
if (ID > 1) {
|
||||
std::lock_guard Lock(LocalMutex_);
|
||||
auto RPC = OutStandingRequests_.find(ID);
|
||||
if (RPC == OutStandingRequests_.end()) {
|
||||
// std::cout << __LINE__ << std::endl;
|
||||
poco_debug(Logger(),
|
||||
fmt::format("({}): RPC {} cannot be found.", SerialNumberStr, ID));
|
||||
poco_debug(Logger(), fmt::format("({}): RPC {} cannot be found.",
|
||||
SerialNumberStr, ID));
|
||||
} else if (RPC->second.SerialNumber != Resp->SerialNumber_) {
|
||||
// std::cout << __LINE__ << std::endl;
|
||||
poco_debug(Logger(),
|
||||
fmt::format("({}): RPC {} serial number mismatch {}!={}.", SerialNumberStr, ID, RPC->second.SerialNumber, Resp->SerialNumber_));
|
||||
poco_debug(
|
||||
Logger(),
|
||||
fmt::format("({}): RPC {} serial number mismatch {}!={}.",
|
||||
SerialNumberStr, ID, RPC->second.SerialNumber,
|
||||
Resp->SerialNumber_));
|
||||
} else {
|
||||
std::shared_ptr<promise_type_t> TmpRpcEntry;
|
||||
std::chrono::duration<double, std::milli> rpc_execution_time =
|
||||
@@ -58,14 +63,16 @@ namespace OpenWifi {
|
||||
// std::cout << __LINE__ << std::endl;
|
||||
poco_debug(Logger(),
|
||||
fmt::format("({}): Received RPC answer {}. Command={}",
|
||||
SerialNumberStr, ID, APCommands::to_string(RPC->second.Command)));
|
||||
SerialNumberStr, ID,
|
||||
APCommands::to_string(RPC->second.Command)));
|
||||
if (RPC->second.Command == APCommands::Commands::script) {
|
||||
CompleteScriptCommand(RPC->second, Payload, rpc_execution_time);
|
||||
} else if (RPC->second.Command != APCommands::Commands::telemetry) {
|
||||
CompleteTelemetryCommand(RPC->second, Payload, rpc_execution_time);
|
||||
CompleteTelemetryCommand(RPC->second, Payload,
|
||||
rpc_execution_time);
|
||||
} else {
|
||||
StorageService()->CommandCompleted(
|
||||
RPC->second.UUID, Payload, rpc_execution_time, true);
|
||||
StorageService()->CommandCompleted(RPC->second.UUID, Payload,
|
||||
rpc_execution_time, true);
|
||||
if (RPC->second.rpc_entry) {
|
||||
TmpRpcEntry = RPC->second.rpc_entry;
|
||||
}
|
||||
@@ -88,7 +95,9 @@ namespace OpenWifi {
|
||||
poco_information(Logger(), "RPC Command processor stopping.");
|
||||
}
|
||||
|
||||
bool CommandManager::CompleteTelemetryCommand(CommandInfo &Command, [[maybe_unused]] const Poco::JSON::Object::Ptr &Payload, std::chrono::duration<double, std::milli> rpc_execution_time ) {
|
||||
bool CommandManager::CompleteTelemetryCommand(
|
||||
CommandInfo &Command, [[maybe_unused]] const Poco::JSON::Object::Ptr &Payload,
|
||||
std::chrono::duration<double, std::milli> rpc_execution_time) {
|
||||
std::shared_ptr<promise_type_t> TmpRpcEntry;
|
||||
|
||||
StorageService()->CommandCompleted(Command.UUID, Payload, rpc_execution_time, true);
|
||||
@@ -104,7 +113,9 @@ namespace OpenWifi {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CommandManager::CompleteScriptCommand(CommandInfo &Command, const Poco::JSON::Object::Ptr &Payload, std::chrono::duration<double, std::milli> rpc_execution_time) {
|
||||
bool CommandManager::CompleteScriptCommand(
|
||||
CommandInfo &Command, const Poco::JSON::Object::Ptr &Payload,
|
||||
std::chrono::duration<double, std::milli> rpc_execution_time) {
|
||||
bool Reply = true;
|
||||
std::shared_ptr<promise_type_t> TmpRpcEntry;
|
||||
|
||||
@@ -122,11 +133,13 @@ namespace OpenWifi {
|
||||
std::uint64_t Error = Status->get("error");
|
||||
if (Error == 0) {
|
||||
// std::cout << __LINE__ << std::endl;
|
||||
StorageService()->CommandCompleted(Command.UUID, Payload, rpc_execution_time, true);
|
||||
StorageService()->CommandCompleted(Command.UUID, Payload,
|
||||
rpc_execution_time, true);
|
||||
Command.State = 1;
|
||||
} else {
|
||||
// std::cout << __LINE__ << std::endl;
|
||||
StorageService()->CommandCompleted(Command.UUID, Payload, rpc_execution_time, true);
|
||||
StorageService()->CommandCompleted(Command.UUID, Payload,
|
||||
rpc_execution_time, true);
|
||||
std::string ErrorTxt = Status->get("result");
|
||||
StorageService()->CancelWaitFile(Command.UUID, ErrorTxt);
|
||||
Command.State = 0;
|
||||
@@ -167,12 +180,14 @@ namespace OpenWifi {
|
||||
|
||||
ManagerThread.start(*this);
|
||||
|
||||
JanitorCallback_ = std::make_unique<Poco::TimerCallback<CommandManager>>(*this,&CommandManager::onJanitorTimer);
|
||||
JanitorCallback_ = std::make_unique<Poco::TimerCallback<CommandManager>>(
|
||||
*this, &CommandManager::onJanitorTimer);
|
||||
JanitorTimer_.setStartInterval(10000);
|
||||
JanitorTimer_.setPeriodicInterval(janitorInterval_ * 1000); // 1 hours
|
||||
JanitorTimer_.start(*JanitorCallback_, MicroServiceTimerPool());
|
||||
|
||||
CommandRunnerCallback_ = std::make_unique<Poco::TimerCallback<CommandManager>>(*this,&CommandManager::onCommandRunnerTimer);
|
||||
CommandRunnerCallback_ = std::make_unique<Poco::TimerCallback<CommandManager>>(
|
||||
*this, &CommandManager::onCommandRunnerTimer);
|
||||
CommandRunnerTimer_.setStartInterval(10000);
|
||||
CommandRunnerTimer_.setPeriodicInterval(queueInterval_ * 1000); // 1 hours
|
||||
CommandRunnerTimer_.start(*CommandRunnerCallback_, MicroServiceTimerPool());
|
||||
@@ -206,19 +221,21 @@ namespace OpenWifi {
|
||||
for (auto request = OutStandingRequests_.begin(); request != OutStandingRequests_.end();) {
|
||||
std::chrono::duration<double, std::milli> delta = now - request->second.submitted;
|
||||
if (delta > 10min) {
|
||||
// std::cout << __LINE__ << " -->> " << request->second.Id << std::endl;
|
||||
MyLogger.debug(fmt::format("{}: Command={} for {} Timed out.",
|
||||
request->second.UUID,
|
||||
// std::cout << __LINE__ << " -->> " << request->second.Id <<
|
||||
//std::endl;
|
||||
MyLogger.debug(fmt::format("{}: Command={} for {} Timed out.", request->second.UUID,
|
||||
APCommands::to_string(request->second.Command),
|
||||
Utils::IntToSerialNumber(request->second.SerialNumber)));
|
||||
if( (request->second.Command == APCommands::Commands::script && request->second.Deferred) ||
|
||||
if ((request->second.Command == APCommands::Commands::script &&
|
||||
request->second.Deferred) ||
|
||||
(request->second.Command == APCommands::Commands::trace)) {
|
||||
StorageService()->CancelWaitFile(request->second.UUID, TimeOutError);
|
||||
}
|
||||
StorageService()->SetCommandTimedOut(request->second.UUID);
|
||||
request = OutStandingRequests_.erase(request);
|
||||
} else {
|
||||
// std::cout << __LINE__ << " -->> " << request->second.Id << std::endl;
|
||||
// std::cout << __LINE__ << " -->> " << request->second.Id <<
|
||||
//std::endl;
|
||||
++request;
|
||||
}
|
||||
}
|
||||
@@ -228,7 +245,8 @@ namespace OpenWifi {
|
||||
|
||||
bool CommandManager::IsCommandRunning(const std::string &C) {
|
||||
std::lock_guard Lock(LocalMutex_);
|
||||
return std::any_of(OutStandingRequests_.begin(),OutStandingRequests_.end(),
|
||||
return std::any_of(
|
||||
OutStandingRequests_.begin(), OutStandingRequests_.end(),
|
||||
[C](const std::pair<std::uint64_t, CommandInfo> &r) { return r.second.UUID == C; });
|
||||
}
|
||||
|
||||
@@ -245,14 +263,15 @@ namespace OpenWifi {
|
||||
|
||||
std::vector<GWObjects::CommandDetails> Commands;
|
||||
if (StorageService()->GetReadyToExecuteCommands(0, 200, Commands)) {
|
||||
poco_trace(MyLogger,fmt::format("Scheduler about to process {} commands.", Commands.size()));
|
||||
poco_trace(MyLogger,
|
||||
fmt::format("Scheduler about to process {} commands.", Commands.size()));
|
||||
for (auto &Cmd : Commands) {
|
||||
if (!Running_) {
|
||||
poco_warning(MyLogger, "Scheduler quitting because service is stopping.");
|
||||
break;
|
||||
}
|
||||
poco_trace(
|
||||
MyLogger, fmt::format("{}: Serial={} Command={} Starting processing.",
|
||||
poco_trace(MyLogger,
|
||||
fmt::format("{}: Serial={} Command={} Starting processing.",
|
||||
Cmd.UUID, Cmd.SerialNumber, Cmd.Command));
|
||||
try {
|
||||
|
||||
@@ -264,8 +283,8 @@ namespace OpenWifi {
|
||||
auto now = Utils::Now();
|
||||
// 2 hour timeout for commands
|
||||
if ((now - Cmd.Submitted) > commandTimeOut_) {
|
||||
poco_information(
|
||||
MyLogger, fmt::format("{}: Serial={} Command={} has expired.",
|
||||
poco_information(MyLogger,
|
||||
fmt::format("{}: Serial={} Command={} has expired.",
|
||||
Cmd.UUID, Cmd.SerialNumber, Cmd.Command));
|
||||
StorageService()->SetCommandTimedOut(Cmd.UUID);
|
||||
continue;
|
||||
@@ -275,8 +294,7 @@ namespace OpenWifi {
|
||||
if (!AP_WS_Server()->Connected(SerialNumberInt)) {
|
||||
poco_trace(
|
||||
MyLogger,
|
||||
fmt::format(
|
||||
"{}: Serial={} Command={} Device is not connected.",
|
||||
fmt::format("{}: Serial={} Command={} Device is not connected.",
|
||||
Cmd.UUID, Cmd.SerialNumber, Cmd.Command));
|
||||
StorageService()->SetCommandLastTry(Cmd.UUID);
|
||||
continue;
|
||||
@@ -284,28 +302,31 @@ namespace OpenWifi {
|
||||
|
||||
std::string ExecutingUUID;
|
||||
APCommands::Commands ExecutingCommand = APCommands::Commands::unknown;
|
||||
if (CommandRunningForDevice(SerialNumberInt,
|
||||
ExecutingUUID, ExecutingCommand)) {
|
||||
if (CommandRunningForDevice(SerialNumberInt, ExecutingUUID,
|
||||
ExecutingCommand)) {
|
||||
poco_trace(
|
||||
MyLogger,
|
||||
fmt::format(
|
||||
"{}: Serial={} Command={} Device is already busy with command {} (Command={})."
|
||||
, Cmd.UUID, Cmd.SerialNumber, Cmd.Command, ExecutingUUID, APCommands::to_string(ExecutingCommand)));
|
||||
fmt::format("{}: Serial={} Command={} Device is already busy "
|
||||
"with command {} (Command={}).",
|
||||
Cmd.UUID, Cmd.SerialNumber, Cmd.Command, ExecutingUUID,
|
||||
APCommands::to_string(ExecutingCommand)));
|
||||
continue;
|
||||
}
|
||||
|
||||
Poco::JSON::Parser P;
|
||||
bool Sent;
|
||||
poco_information(MyLogger, fmt::format("{}: Serial={} Command={} Preparing execution.",
|
||||
poco_information(
|
||||
MyLogger, fmt::format("{}: Serial={} Command={} Preparing execution.",
|
||||
Cmd.UUID, Cmd.SerialNumber, Cmd.Command));
|
||||
auto Params = P.parse(Cmd.Details).extract<Poco::JSON::Object::Ptr>();
|
||||
auto Result = PostCommandDisk(Next_RPC_ID(), APCommands::to_apcommand(Cmd.Command.c_str()), Cmd.SerialNumber, Cmd.Command,
|
||||
*Params, Cmd.UUID, Sent);
|
||||
auto Result = PostCommandDisk(
|
||||
Next_RPC_ID(), APCommands::to_apcommand(Cmd.Command.c_str()),
|
||||
Cmd.SerialNumber, Cmd.Command, *Params, Cmd.UUID, Sent);
|
||||
if (Sent) {
|
||||
StorageService()->SetCommandExecuted(Cmd.UUID);
|
||||
poco_debug(MyLogger,
|
||||
fmt::format("{}: Serial={} Command={} Sent.",
|
||||
Cmd.UUID, Cmd.SerialNumber, Cmd.Command));
|
||||
fmt::format("{}: Serial={} Command={} Sent.", Cmd.UUID,
|
||||
Cmd.SerialNumber, Cmd.Command));
|
||||
} else {
|
||||
poco_debug(MyLogger,
|
||||
fmt::format("{}: Serial={} Command={} Re-queued command.",
|
||||
@@ -313,14 +334,16 @@ namespace OpenWifi {
|
||||
StorageService()->SetCommandLastTry(Cmd.UUID);
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
poco_debug(MyLogger,
|
||||
fmt::format("{}: Serial={} Command={} Failed. Command marked as completed.",
|
||||
poco_debug(
|
||||
MyLogger,
|
||||
fmt::format(
|
||||
"{}: Serial={} Command={} Failed. Command marked as completed.",
|
||||
Cmd.UUID, Cmd.SerialNumber, Cmd.Command));
|
||||
MyLogger.log(E);
|
||||
StorageService()->SetCommandExecuted(Cmd.UUID);
|
||||
} catch (...) {
|
||||
poco_debug(MyLogger,
|
||||
fmt::format("{}: Serial={} Command={} Hard failure. Command marked as completed.",
|
||||
poco_debug(MyLogger, fmt::format("{}: Serial={} Command={} Hard failure. "
|
||||
"Command marked as completed.",
|
||||
Cmd.UUID, Cmd.SerialNumber, Cmd.Command));
|
||||
StorageService()->SetCommandExecuted(Cmd.UUID);
|
||||
}
|
||||
@@ -335,17 +358,9 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
std::shared_ptr<CommandManager::promise_type_t> CommandManager::PostCommand(
|
||||
uint64_t RPC_ID,
|
||||
APCommands::Commands Command,
|
||||
const std::string &SerialNumber,
|
||||
const std::string &CommandStr,
|
||||
const Poco::JSON::Object &Params,
|
||||
const std::string &UUID,
|
||||
bool oneway_rpc,
|
||||
[[maybe_unused]] bool disk_only,
|
||||
bool & Sent,
|
||||
bool rpc,
|
||||
bool Deferred) {
|
||||
uint64_t RPC_ID, APCommands::Commands Command, const std::string &SerialNumber,
|
||||
const std::string &CommandStr, const Poco::JSON::Object &Params, const std::string &UUID,
|
||||
bool oneway_rpc, [[maybe_unused]] bool disk_only, bool &Sent, bool rpc, bool Deferred) {
|
||||
|
||||
auto SerialNumberInt = Utils::SerialNumberToInt(SerialNumber);
|
||||
Sent = false;
|
||||
@@ -372,9 +387,10 @@ namespace OpenWifi {
|
||||
Poco::JSON::Stringifier::stringify(CompleteRPC, ToSend);
|
||||
CInfo.rpc_entry = rpc ? std::make_shared<CommandManager::promise_type_t>() : nullptr;
|
||||
|
||||
poco_debug(Logger(), fmt::format("{}: Sending command {} to {}. ID: {}", UUID, CommandStr, SerialNumber, RPC_ID));
|
||||
// Do not change the order. It is possible that an RPC completes before it is entered in the map. So we insert it
|
||||
// first, even if we may need to remove it later upon failure.
|
||||
poco_debug(Logger(), fmt::format("{}: Sending command {} to {}. ID: {}", UUID, CommandStr,
|
||||
SerialNumber, RPC_ID));
|
||||
// Do not change the order. It is possible that an RPC completes before it is entered in
|
||||
//the map. So we insert it first, even if we may need to remove it later upon failure.
|
||||
if (!oneway_rpc) {
|
||||
std::lock_guard M(Mutex_);
|
||||
OutStandingRequests_[RPC_ID] = CInfo;
|
||||
@@ -391,4 +407,4 @@ namespace OpenWifi {
|
||||
poco_warning(Logger(), fmt::format("{}: Failed to send command. ID: {}", UUID, RPC_ID));
|
||||
return nullptr;
|
||||
}
|
||||
} // namespace
|
||||
} // namespace OpenWifi
|
||||
@@ -9,21 +9,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
#include <future>
|
||||
#include <map>
|
||||
#include <utility>
|
||||
#include <functional>
|
||||
#include <shared_mutex>
|
||||
#include <utility>
|
||||
|
||||
#include "Poco/JSON/Object.h"
|
||||
#include "Poco/Net/HTTPServerRequest.h"
|
||||
#include "Poco/Net/HTTPServerResponse.h"
|
||||
#include "Poco/Timer.h"
|
||||
#include "Poco/Notification.h"
|
||||
#include "Poco/NotificationQueue.h"
|
||||
#include "Poco/Timer.h"
|
||||
|
||||
#include "framework/SubSystemServer.h"
|
||||
#include "fmt/format.h"
|
||||
#include "framework/SubSystemServer.h"
|
||||
|
||||
#include "RESTObjects/RESTAPI_GWobjects.h"
|
||||
|
||||
@@ -31,18 +31,12 @@ namespace OpenWifi {
|
||||
|
||||
class RPCResponseNotification : public Poco::Notification {
|
||||
public:
|
||||
RPCResponseNotification(std::uint64_t ser,
|
||||
Poco::JSON::Object::Ptr pl) :
|
||||
SerialNumber_(ser),
|
||||
Payload_(std::move(pl))
|
||||
{
|
||||
|
||||
}
|
||||
RPCResponseNotification(std::uint64_t ser, Poco::JSON::Object::Ptr pl)
|
||||
: SerialNumber_(ser), Payload_(std::move(pl)) {}
|
||||
std::uint64_t SerialNumber_;
|
||||
Poco::JSON::Object::Ptr Payload_;
|
||||
};
|
||||
|
||||
|
||||
class CommandManager : public SubSystemServer, Poco::Runnable {
|
||||
public:
|
||||
using objtype_t = Poco::JSON::Object::Ptr;
|
||||
@@ -54,7 +48,8 @@ namespace OpenWifi {
|
||||
APCommands::Commands Command;
|
||||
std::string UUID;
|
||||
std::uint64_t State = 1;
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> submitted = std::chrono::high_resolution_clock::now();
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> submitted =
|
||||
std::chrono::high_resolution_clock::now();
|
||||
std::shared_ptr<promise_type_t> rpc_entry;
|
||||
bool Deferred = false;
|
||||
};
|
||||
@@ -64,17 +59,16 @@ namespace OpenWifi {
|
||||
Poco::JSON::Object::Ptr payload;
|
||||
|
||||
explicit RPCResponse(std::uint64_t ser, Poco::JSON::Object::Ptr pl)
|
||||
:
|
||||
serialNumber(ser),
|
||||
payload(std::move(pl)) {
|
||||
}
|
||||
: serialNumber(ser), payload(std::move(pl)) {}
|
||||
};
|
||||
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
void WakeUp();
|
||||
inline void PostCommandResult(const std::string &SerialNumber, Poco::JSON::Object::Ptr Obj) {
|
||||
ResponseQueue_.enqueueNotification(new RPCResponseNotification(Utils::SerialNumberToInt(SerialNumber),std::move(Obj)));
|
||||
inline void PostCommandResult(const std::string &SerialNumber,
|
||||
Poco::JSON::Object::Ptr Obj) {
|
||||
ResponseQueue_.enqueueNotification(new RPCResponseNotification(
|
||||
Utils::SerialNumberToInt(SerialNumber), std::move(Obj)));
|
||||
}
|
||||
|
||||
std::shared_ptr<promise_type_t> PostCommandOneWayDisk(uint64_t RPC_ID,
|
||||
@@ -82,74 +76,33 @@ namespace OpenWifi {
|
||||
const std::string &SerialNumber,
|
||||
const std::string &Method,
|
||||
const Poco::JSON::Object &Params,
|
||||
const std::string &UUID,
|
||||
bool & Sent) {
|
||||
return PostCommand(RPC_ID,
|
||||
Command,
|
||||
SerialNumber,
|
||||
Method,
|
||||
Params,
|
||||
UUID,
|
||||
true, true, Sent , false);
|
||||
const std::string &UUID, bool &Sent) {
|
||||
return PostCommand(RPC_ID, Command, SerialNumber, Method, Params, UUID, true, true,
|
||||
Sent, false);
|
||||
}
|
||||
|
||||
std::shared_ptr<promise_type_t> PostCommandDisk(
|
||||
uint64_t RPC_ID,
|
||||
APCommands::Commands Command,
|
||||
const std::string &SerialNumber,
|
||||
const std::string &Method,
|
||||
const Poco::JSON::Object &Params,
|
||||
const std::string &UUID,
|
||||
bool & Sent) {
|
||||
return PostCommand(RPC_ID,
|
||||
Command,
|
||||
SerialNumber,
|
||||
Method,
|
||||
Params,
|
||||
UUID,
|
||||
false, true, Sent,
|
||||
false );
|
||||
std::shared_ptr<promise_type_t>
|
||||
PostCommandDisk(uint64_t RPC_ID, APCommands::Commands Command,
|
||||
const std::string &SerialNumber, const std::string &Method,
|
||||
const Poco::JSON::Object &Params, const std::string &UUID, bool &Sent) {
|
||||
return PostCommand(RPC_ID, Command, SerialNumber, Method, Params, UUID, false, true,
|
||||
Sent, false);
|
||||
}
|
||||
|
||||
std::shared_ptr<promise_type_t> PostCommand(
|
||||
uint64_t RPC_ID,
|
||||
APCommands::Commands Command,
|
||||
const std::string &SerialNumber,
|
||||
const std::string &Method,
|
||||
const Poco::JSON::Object &Params,
|
||||
const std::string &UUID,
|
||||
bool & Sent,
|
||||
bool rpc,
|
||||
bool Deferred) {
|
||||
return PostCommand(RPC_ID,
|
||||
Command,
|
||||
SerialNumber,
|
||||
Method,
|
||||
Params,
|
||||
UUID,
|
||||
false,
|
||||
false, Sent,
|
||||
rpc,
|
||||
Deferred);
|
||||
std::shared_ptr<promise_type_t>
|
||||
PostCommand(uint64_t RPC_ID, APCommands::Commands Command, const std::string &SerialNumber,
|
||||
const std::string &Method, const Poco::JSON::Object &Params,
|
||||
const std::string &UUID, bool &Sent, bool rpc, bool Deferred) {
|
||||
return PostCommand(RPC_ID, Command, SerialNumber, Method, Params, UUID, false, false,
|
||||
Sent, rpc, Deferred);
|
||||
}
|
||||
|
||||
std::shared_ptr<promise_type_t> PostCommandOneWay(
|
||||
uint64_t RPC_ID,
|
||||
APCommands::Commands Command,
|
||||
const std::string &SerialNumber,
|
||||
const std::string &Method,
|
||||
const Poco::JSON::Object &Params,
|
||||
const std::string &UUID,
|
||||
bool & Sent) {
|
||||
return PostCommand(RPC_ID,
|
||||
Command,
|
||||
SerialNumber,
|
||||
Method,
|
||||
Params,
|
||||
UUID,
|
||||
true,
|
||||
false, Sent,
|
||||
false);
|
||||
std::shared_ptr<promise_type_t>
|
||||
PostCommandOneWay(uint64_t RPC_ID, APCommands::Commands Command,
|
||||
const std::string &SerialNumber, const std::string &Method,
|
||||
const Poco::JSON::Object &Params, const std::string &UUID, bool &Sent) {
|
||||
return PostCommand(RPC_ID, Command, SerialNumber, Method, Params, UUID, true, false,
|
||||
Sent, false);
|
||||
}
|
||||
|
||||
bool IsCommandRunning(const std::string &C);
|
||||
@@ -171,7 +124,8 @@ namespace OpenWifi {
|
||||
OutStandingRequests_.erase(Id);
|
||||
}
|
||||
|
||||
inline bool CommandRunningForDevice(std::uint64_t SerialNumber, std::string & uuid, APCommands::Commands &command) {
|
||||
inline bool CommandRunningForDevice(std::uint64_t SerialNumber, std::string &uuid,
|
||||
APCommands::Commands &command) {
|
||||
std::lock_guard Lock(LocalMutex_);
|
||||
|
||||
for (const auto &[Request, Command] : OutStandingRequests_) {
|
||||
@@ -186,7 +140,8 @@ namespace OpenWifi {
|
||||
|
||||
inline void ClearQueue(std::uint64_t SerialNumber) {
|
||||
std::lock_guard Lock(LocalMutex_);
|
||||
for(auto Request = OutStandingRequests_.begin(); Request != OutStandingRequests_.end() ; ) {
|
||||
for (auto Request = OutStandingRequests_.begin();
|
||||
Request != OutStandingRequests_.end();) {
|
||||
if (Request->second.SerialNumber == SerialNumber)
|
||||
Request = OutStandingRequests_.erase(Request);
|
||||
else
|
||||
@@ -223,28 +178,21 @@ namespace OpenWifi {
|
||||
std::uint64_t janitorInterval_ = 0;
|
||||
std::uint64_t queueInterval_ = 0;
|
||||
|
||||
std::shared_ptr<promise_type_t> PostCommand(
|
||||
uint64_t RPCID,
|
||||
APCommands::Commands Command,
|
||||
const std::string &SerialNumber,
|
||||
const std::string &Method,
|
||||
const Poco::JSON::Object &Params,
|
||||
const std::string &UUID,
|
||||
bool oneway_rpc,
|
||||
bool disk_only,
|
||||
bool & Sent,
|
||||
bool rpc_call,
|
||||
bool Deferred=false);
|
||||
std::shared_ptr<promise_type_t>
|
||||
PostCommand(uint64_t RPCID, APCommands::Commands Command, const std::string &SerialNumber,
|
||||
const std::string &Method, const Poco::JSON::Object &Params,
|
||||
const std::string &UUID, bool oneway_rpc, bool disk_only, bool &Sent,
|
||||
bool rpc_call, bool Deferred = false);
|
||||
|
||||
bool CompleteScriptCommand(CommandInfo &Command, const Poco::JSON::Object::Ptr &Payload, std::chrono::duration<double, std::milli> rpc_execution_time);
|
||||
bool CompleteTelemetryCommand(CommandInfo &Command, const Poco::JSON::Object::Ptr &Payload, std::chrono::duration<double, std::milli> rpc_execution_time);
|
||||
bool CompleteScriptCommand(CommandInfo &Command, const Poco::JSON::Object::Ptr &Payload,
|
||||
std::chrono::duration<double, std::milli> rpc_execution_time);
|
||||
bool CompleteTelemetryCommand(CommandInfo &Command, const Poco::JSON::Object::Ptr &Payload,
|
||||
std::chrono::duration<double, std::milli> rpc_execution_time);
|
||||
|
||||
CommandManager() noexcept:
|
||||
SubSystemServer("CommandManager", "CMD-MGR", "command.manager") {
|
||||
}
|
||||
CommandManager() noexcept
|
||||
: SubSystemServer("CommandManager", "CMD-MGR", "command.manager") {}
|
||||
};
|
||||
|
||||
inline auto CommandManager() { return CommandManager::instance(); }
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -5,13 +5,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
namespace OpenWifi {
|
||||
class ConfigurationCache {
|
||||
public:
|
||||
|
||||
static ConfigurationCache &instance() {
|
||||
static ConfigurationCache instance;
|
||||
return instance;
|
||||
@@ -46,4 +45,4 @@ namespace OpenWifi {
|
||||
inline void SetCurrentConfigurationID(uint64_t SerialNumber, uint64_t ID) {
|
||||
return ConfigurationCache::instance().Add(SerialNumber, ID);
|
||||
}
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -6,11 +6,10 @@
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
#include "Poco/Util/Application.h"
|
||||
#include "Poco/Util/Option.h"
|
||||
#include "Poco/Environment.h"
|
||||
#include "Poco/Net/SSLManager.h"
|
||||
|
||||
#include "Poco/Util/Application.h"
|
||||
#include "Poco/Util/Option.h"
|
||||
|
||||
#include "AP_WS_Server.h"
|
||||
#include "CommandManager.h"
|
||||
@@ -19,43 +18,28 @@
|
||||
#include "FindCountry.h"
|
||||
#include "OUIServer.h"
|
||||
#include "RADIUS_proxy_server.h"
|
||||
#include "ScriptManager.h"
|
||||
#include "SerialNumberCache.h"
|
||||
#include "SignatureMgr.h"
|
||||
#include "StorageArchiver.h"
|
||||
#include "StorageService.h"
|
||||
#include "TelemetryStream.h"
|
||||
#include "UI_GW_WebSocketNotifications.h"
|
||||
#include "VenueBroadcaster.h"
|
||||
#include "framework/ConfigurationValidator.h"
|
||||
#include "rttys/RTTYS_server.h"
|
||||
#include "framework/UI_WebSocketClientServer.h"
|
||||
#include "UI_GW_WebSocketNotifications.h"
|
||||
#include "ScriptManager.h"
|
||||
#include "SignatureMgr.h"
|
||||
#include "rttys/RTTYS_server.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class Daemon *Daemon::instance() {
|
||||
static Daemon instance(vDAEMON_PROPERTIES_FILENAME,
|
||||
vDAEMON_ROOT_ENV_VAR,
|
||||
vDAEMON_CONFIG_ENV_VAR,
|
||||
vDAEMON_APP_NAME,
|
||||
vDAEMON_BUS_TIMER,
|
||||
SubSystemVec{
|
||||
StorageService(),
|
||||
SerialNumberCache(),
|
||||
ConfigurationValidator(),
|
||||
UI_WebSocketClientServer(),
|
||||
OUIServer(),
|
||||
FindCountryFromIP(),
|
||||
CommandManager(),
|
||||
FileUploader(),
|
||||
StorageArchiver(),
|
||||
TelemetryStream(),
|
||||
RTTYS_server(),
|
||||
RADIUS_proxy_server(),
|
||||
VenueBroadcaster(),
|
||||
ScriptManager(),
|
||||
SignatureManager(),
|
||||
AP_WS_Server()
|
||||
});
|
||||
static Daemon instance(
|
||||
vDAEMON_PROPERTIES_FILENAME, vDAEMON_ROOT_ENV_VAR, vDAEMON_CONFIG_ENV_VAR,
|
||||
vDAEMON_APP_NAME, vDAEMON_BUS_TIMER,
|
||||
SubSystemVec{StorageService(), SerialNumberCache(), ConfigurationValidator(),
|
||||
UI_WebSocketClientServer(), OUIServer(), FindCountryFromIP(),
|
||||
CommandManager(), FileUploader(), StorageArchiver(), TelemetryStream(),
|
||||
RTTYS_server(), RADIUS_proxy_server(), VenueBroadcaster(), ScriptManager(),
|
||||
SignatureManager(), AP_WS_Server()});
|
||||
return &instance;
|
||||
}
|
||||
|
||||
@@ -89,8 +73,7 @@ namespace OpenWifi {
|
||||
{"tplink_ex227", "AP"},
|
||||
{"tplink_ex228", "AP"},
|
||||
{"tplink_ex447", "AP"},
|
||||
{"wallys_dr40x9","AP"}
|
||||
};
|
||||
{"wallys_dr40x9", "AP"}};
|
||||
|
||||
void Daemon::PostInitialization([[maybe_unused]] Poco::Util::Application &self) {
|
||||
AutoProvisioning_ = config().getBool("openwifi.autoprovisioning", false);
|
||||
@@ -100,8 +83,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string Daemon::IdentifyDevice(const std::string &Id) const {
|
||||
for(const auto &[DeviceType,Type]:DeviceTypes_)
|
||||
{
|
||||
for (const auto &[DeviceType, Type] : DeviceTypes_) {
|
||||
if (Id == DeviceType)
|
||||
return Type;
|
||||
}
|
||||
@@ -112,7 +94,7 @@ namespace OpenWifi {
|
||||
Daemon()->PostInitialization(self);
|
||||
GWWebSocketNotifications::Register();
|
||||
}
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int ExitCode;
|
||||
|
||||
23
src/Daemon.h
23
src/Daemon.h
@@ -9,17 +9,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "framework/MicroServiceNames.h"
|
||||
#include "framework/MicroService.h"
|
||||
#include "framework/MicroServiceNames.h"
|
||||
|
||||
#include "Dashboard.h"
|
||||
#include "framework/OpenWifiTypes.h"
|
||||
#include "GwWebSocketClient.h"
|
||||
#include "framework/OpenWifiTypes.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
@@ -31,13 +31,10 @@ namespace OpenWifi {
|
||||
|
||||
class Daemon : public MicroService {
|
||||
public:
|
||||
explicit Daemon(const std::string & PropFile,
|
||||
const std::string & RootEnv,
|
||||
const std::string & ConfigEnv,
|
||||
const std::string & AppName,
|
||||
uint64_t BusTimer,
|
||||
const SubSystemVec & SubSystems) :
|
||||
MicroService( PropFile, RootEnv, ConfigEnv, AppName, BusTimer, SubSystems) {};
|
||||
explicit Daemon(const std::string &PropFile, const std::string &RootEnv,
|
||||
const std::string &ConfigEnv, const std::string &AppName, uint64_t BusTimer,
|
||||
const SubSystemVec &SubSystems)
|
||||
: MicroService(PropFile, RootEnv, ConfigEnv, AppName, BusTimer, SubSystems){};
|
||||
|
||||
bool AutoProvisioning() const { return AutoProvisioning_; }
|
||||
[[nodiscard]] std::string IdentifyDevice(const std::string &Compatible) const;
|
||||
@@ -45,6 +42,7 @@ namespace OpenWifi {
|
||||
inline DeviceDashboard &GetDashboard() { return DB_; }
|
||||
Poco::Logger &Log() { return Poco::Logger::get(AppName()); }
|
||||
void PostInitialization(Poco::Util::Application &self);
|
||||
|
||||
private:
|
||||
bool AutoProvisioning_ = false;
|
||||
std::vector<std::pair<std::string, std::string>> DeviceTypes_;
|
||||
@@ -54,5 +52,4 @@ namespace OpenWifi {
|
||||
|
||||
inline Daemon *Daemon() { return Daemon::instance(); }
|
||||
void DaemonPostInitialization(Poco::Util::Application &self);
|
||||
}
|
||||
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -43,9 +43,8 @@ namespace OpenWifi {
|
||||
DB_ = NewData;
|
||||
ValidDashboard_ = true;
|
||||
} catch (...) {
|
||||
|
||||
}
|
||||
GeneratingDashboard_ = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -6,14 +6,15 @@
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include "Poco/Logger.h"
|
||||
#include "RESTObjects//RESTAPI_GWobjects.h"
|
||||
#include "framework/OpenWifiTypes.h"
|
||||
#include "Poco/Logger.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class DeviceDashboard {
|
||||
public:
|
||||
bool Get(GWObjects::Dashboard &D, Poco::Logger &Logger);
|
||||
|
||||
private:
|
||||
std::mutex DataMutex_;
|
||||
volatile std::atomic_bool GeneratingDashboard_ = false;
|
||||
@@ -23,5 +24,4 @@ namespace OpenWifi {
|
||||
|
||||
void Generate(GWObjects::Dashboard &D, Poco::Logger &Logger);
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -8,16 +8,16 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "Poco/Net/HTTPServerParams.h"
|
||||
#include "Poco/Net/HTTPServerResponse.h"
|
||||
#include "Poco/DynamicAny.h"
|
||||
#include "Poco/Net/PartHandler.h"
|
||||
#include "Poco/Net/MessageHeader.h"
|
||||
#include "Poco/Net/MultipartReader.h"
|
||||
#include "Poco/CountingStream.h"
|
||||
#include "Poco/StreamCopier.h"
|
||||
#include "Poco/DynamicAny.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/File.h"
|
||||
#include "Poco/Net/HTTPServerParams.h"
|
||||
#include "Poco/Net/HTTPServerResponse.h"
|
||||
#include "Poco/Net/MessageHeader.h"
|
||||
#include "Poco/Net/MultipartReader.h"
|
||||
#include "Poco/Net/PartHandler.h"
|
||||
#include "Poco/StreamCopier.h"
|
||||
#include "Poco/StringTokenizer.h"
|
||||
|
||||
#include "framework/MicroServiceFuncs.h"
|
||||
@@ -121,52 +121,48 @@ namespace OpenWifi {
|
||||
Start();
|
||||
}
|
||||
|
||||
const std::string & FileUploader::FullName() {
|
||||
return FullName_;
|
||||
}
|
||||
const std::string &FileUploader::FullName() { return FullName_; }
|
||||
|
||||
// if you pass in an empty UUID, it will just clean the list and not add it.
|
||||
bool FileUploader::AddUUID( const std::string & UUID, std::chrono::seconds WaitTimeInSeconds, const std::string &Type) {
|
||||
bool FileUploader::AddUUID(const std::string &UUID, std::chrono::seconds WaitTimeInSeconds,
|
||||
const std::string &Type) {
|
||||
std::lock_guard Guard(Mutex_);
|
||||
|
||||
uint64_t now = Utils::Now();
|
||||
auto Func=[now](const UploadId &I) -> bool {
|
||||
return (now > I.Expires);
|
||||
};
|
||||
OutStandingUploads_.erase(std::remove_if(OutStandingUploads_.begin(),OutStandingUploads_.end(),Func),OutStandingUploads_.end());
|
||||
auto Func = [now](const UploadId &I) -> bool { return (now > I.Expires); };
|
||||
OutStandingUploads_.erase(
|
||||
std::remove_if(OutStandingUploads_.begin(), OutStandingUploads_.end(), Func),
|
||||
OutStandingUploads_.end());
|
||||
OutStandingUploads_.emplace_back(UploadId{UUID, now + WaitTimeInSeconds.count(), Type});
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FileUploader::ValidRequest(const std::string &UUID) {
|
||||
std::lock_guard Guard(Mutex_);
|
||||
auto Func = [UUID](const UploadId &P) -> bool {
|
||||
return (P.UUID==UUID);
|
||||
};
|
||||
return std::find_if(OutStandingUploads_.begin(), OutStandingUploads_.end(), Func) != end(OutStandingUploads_);
|
||||
auto Func = [UUID](const UploadId &P) -> bool { return (P.UUID == UUID); };
|
||||
return std::find_if(OutStandingUploads_.begin(), OutStandingUploads_.end(), Func) !=
|
||||
end(OutStandingUploads_);
|
||||
}
|
||||
|
||||
void FileUploader::RemoveRequest(const std::string &UUID) {
|
||||
std::lock_guard Guard(Mutex_);
|
||||
auto Func = [UUID](const UploadId &P) -> bool {
|
||||
return (P.UUID==UUID);
|
||||
};
|
||||
OutStandingUploads_.erase(std::remove_if(OutStandingUploads_.begin(),OutStandingUploads_.end(),Func),OutStandingUploads_.end());
|
||||
auto Func = [UUID](const UploadId &P) -> bool { return (P.UUID == UUID); };
|
||||
OutStandingUploads_.erase(
|
||||
std::remove_if(OutStandingUploads_.begin(), OutStandingUploads_.end(), Func),
|
||||
OutStandingUploads_.end());
|
||||
}
|
||||
|
||||
class FileUploaderPartHandler2 : public Poco::Net::PartHandler {
|
||||
public:
|
||||
FileUploaderPartHandler2(std::string Id, Poco::Logger &Logger, std::stringstream & ofs) :
|
||||
Id_(std::move(Id)),
|
||||
Logger_(Logger),
|
||||
OutputStream_(ofs){
|
||||
}
|
||||
FileUploaderPartHandler2(std::string Id, Poco::Logger &Logger, std::stringstream &ofs)
|
||||
: Id_(std::move(Id)), Logger_(Logger), OutputStream_(ofs) {}
|
||||
void handlePart(const Poco::Net::MessageHeader &Header, std::istream &Stream) {
|
||||
FileType_ = Header.get(RESTAPI::Protocol::CONTENTTYPE, RESTAPI::Protocol::UNSPECIFIED);
|
||||
if (Header.has(RESTAPI::Protocol::CONTENTDISPOSITION)) {
|
||||
std::string Disposition;
|
||||
Poco::Net::NameValueCollection Parameters;
|
||||
Poco::Net::MessageHeader::splitParameters(Header[RESTAPI::Protocol::CONTENTDISPOSITION], Disposition, Parameters);
|
||||
Poco::Net::MessageHeader::splitParameters(
|
||||
Header[RESTAPI::Protocol::CONTENTDISPOSITION], Disposition, Parameters);
|
||||
Name_ = Parameters.get(RESTAPI::Protocol::NAME, RESTAPI::Protocol::UNNAMED);
|
||||
}
|
||||
Poco::CountingInputStream InputStream(Stream);
|
||||
@@ -188,21 +184,18 @@ namespace OpenWifi {
|
||||
inline Poco::Logger &Logger() { return Logger_; };
|
||||
};
|
||||
|
||||
class FormRequestHandler: public Poco::Net::HTTPRequestHandler
|
||||
{
|
||||
class FormRequestHandler : public Poco::Net::HTTPRequestHandler {
|
||||
public:
|
||||
explicit FormRequestHandler(std::string UUID, Poco::Logger & L, const std::string &Type):
|
||||
UUID_(std::move(UUID)),
|
||||
Logger_(L),
|
||||
Type_(Type)
|
||||
{
|
||||
}
|
||||
explicit FormRequestHandler(std::string UUID, Poco::Logger &L, const std::string &Type)
|
||||
: UUID_(std::move(UUID)), Logger_(L), Type_(Type) {}
|
||||
|
||||
void handleRequest(Poco::Net::HTTPServerRequest& Request, Poco::Net::HTTPServerResponse& Response) final {
|
||||
void handleRequest(Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response) final {
|
||||
|
||||
Utils::SetThreadName("FileUploader");
|
||||
const auto ContentType = Request.getContentType();
|
||||
const auto Tokens = Poco::StringTokenizer(ContentType,";",Poco::StringTokenizer::TOK_TRIM);
|
||||
const auto Tokens =
|
||||
Poco::StringTokenizer(ContentType, ";", Poco::StringTokenizer::TOK_TRIM);
|
||||
|
||||
poco_debug(Logger(), fmt::format("{}: Preparing to upload trace file.", UUID_));
|
||||
Poco::JSON::Object Answer;
|
||||
@@ -230,7 +223,8 @@ namespace OpenWifi {
|
||||
Answer.set("filename", UUID_);
|
||||
Answer.set("error", 0);
|
||||
poco_debug(Logger(), fmt::format("{}: File uploaded.", UUID_));
|
||||
StorageService()->AttachFileDataToCommand(UUID_, FileContent, Type_);
|
||||
StorageService()->AttachFileDataToCommand(UUID_, FileContent,
|
||||
Type_);
|
||||
std::ostream &ResponseStream = Response.send();
|
||||
Poco::JSON::Stringifier::stringify(Answer, ResponseStream);
|
||||
return;
|
||||
@@ -269,31 +263,33 @@ namespace OpenWifi {
|
||||
std::string Type_;
|
||||
};
|
||||
|
||||
Poco::Net::HTTPRequestHandler *FileUpLoaderRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest & Request) {
|
||||
Poco::Net::HTTPRequestHandler *FileUpLoaderRequestHandlerFactory::createRequestHandler(
|
||||
const Poco::Net::HTTPServerRequest &Request) {
|
||||
|
||||
poco_debug(Logger(),fmt::format("REQUEST({}): {} {}", Utils::FormatIPv6(Request.clientAddress().toString()), Request.getMethod(), Request.getURI()));
|
||||
poco_debug(Logger(), fmt::format("REQUEST({}): {} {}",
|
||||
Utils::FormatIPv6(Request.clientAddress().toString()),
|
||||
Request.getMethod(), Request.getURI()));
|
||||
|
||||
if (Request.getMethod() != Poco::Net::HTTPRequest::HTTP_POST ||
|
||||
Request.getURI().size() < (URI_BASE.size() + 36)) {
|
||||
poco_warning(Logger(),fmt::format("ILLEGAL-REQUEST({}): {} {}. Dropped.", Utils::FormatIPv6(Request.clientAddress().toString()), Request.getMethod(), Request.getURI()));
|
||||
poco_warning(Logger(),
|
||||
fmt::format("ILLEGAL-REQUEST({}): {} {}. Dropped.",
|
||||
Utils::FormatIPv6(Request.clientAddress().toString()),
|
||||
Request.getMethod(), Request.getURI()));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// The UUID should be after the /v1/upload/ part...
|
||||
auto UUIDLocation = Request.getURI().find_first_of(URI_BASE);
|
||||
|
||||
if( UUIDLocation != std::string::npos )
|
||||
{
|
||||
if (UUIDLocation != std::string::npos) {
|
||||
auto UUID = Request.getURI().substr(UUIDLocation + URI_BASE.size());
|
||||
|
||||
FileUploader::UploadId E;
|
||||
if(FileUploader()->Find(UUID,E))
|
||||
{
|
||||
if (FileUploader()->Find(UUID, E)) {
|
||||
FileUploader()->RemoveRequest(UUID);
|
||||
return new FormRequestHandler(UUID, Logger(), E.Type);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
poco_warning(Logger(), fmt::format("Unknown UUID={}", UUID));
|
||||
}
|
||||
}
|
||||
@@ -319,4 +315,4 @@ namespace OpenWifi {
|
||||
poco_notice(Logger(), "Stopped...");
|
||||
}
|
||||
|
||||
} // Namespace
|
||||
} // namespace OpenWifi
|
||||
@@ -19,7 +19,6 @@ namespace OpenWifi {
|
||||
|
||||
class FileUploader : public SubSystemServer {
|
||||
public:
|
||||
|
||||
struct UploadId {
|
||||
std::string UUID;
|
||||
std::uint64_t Expires;
|
||||
@@ -30,7 +29,8 @@ namespace OpenWifi {
|
||||
void Stop() override;
|
||||
void reinitialize(Poco::Util::Application &self) override;
|
||||
const std::string &FullName();
|
||||
bool AddUUID( const std::string & UUID, std::chrono::seconds WaitTimeInSecond, const std::string &Type);
|
||||
bool AddUUID(const std::string &UUID, std::chrono::seconds WaitTimeInSecond,
|
||||
const std::string &Type);
|
||||
bool ValidRequest(const std::string &UUID);
|
||||
void RemoveRequest(const std::string &UUID);
|
||||
const std::string &Path() { return Path_; };
|
||||
@@ -43,6 +43,7 @@ namespace OpenWifi {
|
||||
[[nodiscard]] inline uint64_t MaxSize() const { return MaxSize_; }
|
||||
|
||||
bool Find(const std::string &UUID, UploadId &V);
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<Poco::Net::HTTPServer>> Servers_;
|
||||
std::string FullName_;
|
||||
@@ -50,26 +51,21 @@ namespace OpenWifi {
|
||||
std::string Path_;
|
||||
uint64_t MaxSize_ = 10000000;
|
||||
|
||||
explicit FileUploader() noexcept:
|
||||
SubSystemServer("FileUploader", "FILE-UPLOAD", "openwifi.fileuploader")
|
||||
{
|
||||
}
|
||||
explicit FileUploader() noexcept
|
||||
: SubSystemServer("FileUploader", "FILE-UPLOAD", "openwifi.fileuploader") {}
|
||||
};
|
||||
|
||||
class FileUpLoaderRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
|
||||
public:
|
||||
explicit FileUpLoaderRequestHandlerFactory(Poco::Logger &L) :
|
||||
Logger_(L) {
|
||||
}
|
||||
explicit FileUpLoaderRequestHandlerFactory(Poco::Logger &L) : Logger_(L) {}
|
||||
|
||||
Poco::Net::HTTPRequestHandler *
|
||||
createRequestHandler(const Poco::Net::HTTPServerRequest &request) override;
|
||||
inline Poco::Logger &Logger() { return Logger_; }
|
||||
|
||||
Poco::Net::HTTPRequestHandler *createRequestHandler(const Poco::Net::HTTPServerRequest &request) override;
|
||||
inline Poco::Logger & Logger() {
|
||||
return Logger_;
|
||||
}
|
||||
private:
|
||||
Poco::Logger &Logger_;
|
||||
};
|
||||
|
||||
inline auto FileUploader() { return FileUploader::instance(); }
|
||||
} // namespace
|
||||
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
|
||||
#include "Poco/Net/IPAddress.h"
|
||||
|
||||
#include "framework/SubSystemServer.h"
|
||||
#include "framework/MicroServiceFuncs.h"
|
||||
#include "framework/SubSystemServer.h"
|
||||
|
||||
#include "nlohmann/json.hpp"
|
||||
|
||||
@@ -18,8 +18,7 @@ namespace OpenWifi {
|
||||
virtual bool Init() = 0;
|
||||
virtual Poco::URI URI(const std::string &IPAddress) = 0;
|
||||
virtual std::string Country(const std::string &Response) = 0;
|
||||
virtual ~IPToCountryProvider() {
|
||||
};
|
||||
virtual ~IPToCountryProvider(){};
|
||||
};
|
||||
|
||||
class IPInfo : public IPToCountryProvider {
|
||||
@@ -44,14 +43,12 @@ namespace OpenWifi {
|
||||
return IPInfo["country"];
|
||||
}
|
||||
} catch (...) {
|
||||
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private:
|
||||
std::string Key_;
|
||||
|
||||
};
|
||||
|
||||
class IPData : public IPToCountryProvider {
|
||||
@@ -76,10 +73,10 @@ namespace OpenWifi {
|
||||
return IPInfo["country_code"];
|
||||
}
|
||||
} catch (...) {
|
||||
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private:
|
||||
std::string Key_;
|
||||
};
|
||||
@@ -108,10 +105,10 @@ namespace OpenWifi {
|
||||
return IPInfo["country_code"];
|
||||
}
|
||||
} catch (...) {
|
||||
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private:
|
||||
std::string Key_;
|
||||
};
|
||||
@@ -139,7 +136,8 @@ namespace OpenWifi {
|
||||
poco_notice(Logger(), "Starting...");
|
||||
ProviderName_ = MicroServiceConfigGetString("iptocountry.provider", "");
|
||||
if (!ProviderName_.empty()) {
|
||||
Provider_ = IPLocationProvider<IPToCountryProvider, IPInfo, IPData, IP2Location>(ProviderName_);
|
||||
Provider_ = IPLocationProvider<IPToCountryProvider, IPInfo, IPData, IP2Location>(
|
||||
ProviderName_);
|
||||
if (Provider_ != nullptr) {
|
||||
Enabled_ = Provider_->Init();
|
||||
}
|
||||
@@ -154,10 +152,8 @@ namespace OpenWifi {
|
||||
poco_notice(Logger(), "Stopped...");
|
||||
}
|
||||
|
||||
[[nodiscard]] static inline std::string ReformatAddress(const std::string & I )
|
||||
{
|
||||
if(I.substr(0,7) == "::ffff:")
|
||||
{
|
||||
[[nodiscard]] static inline std::string ReformatAddress(const std::string &I) {
|
||||
if (I.substr(0, 7) == "::ffff:") {
|
||||
std::string ip = I.substr(7);
|
||||
return ip;
|
||||
}
|
||||
@@ -194,12 +190,9 @@ namespace OpenWifi {
|
||||
std::unique_ptr<IPToCountryProvider> Provider_;
|
||||
std::string ProviderName_;
|
||||
|
||||
FindCountryFromIP() noexcept:
|
||||
SubSystemServer("IpToCountry", "IPTOC-SVR", "iptocountry")
|
||||
{
|
||||
}
|
||||
FindCountryFromIP() noexcept : SubSystemServer("IpToCountry", "IPTOC-SVR", "iptocountry") {}
|
||||
};
|
||||
|
||||
inline auto FindCountryFromIP() { return FindCountryFromIP::instance(); }
|
||||
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -4,23 +4,19 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <Poco/JSON/Object.h>
|
||||
#include <framework/KafkaManager.h>
|
||||
#include <string>
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class GWKafkaEvents {
|
||||
public:
|
||||
GWKafkaEvents(const std::string &serialNumber, const std::string &type, std::uint64_t timestamp) :
|
||||
serialNumber_(serialNumber),
|
||||
type_(type),
|
||||
timestamp_(timestamp) {
|
||||
}
|
||||
GWKafkaEvents(const std::string &serialNumber, const std::string &type,
|
||||
std::uint64_t timestamp)
|
||||
: serialNumber_(serialNumber), type_(type), timestamp_(timestamp) {}
|
||||
|
||||
inline void SetPayload(Poco::JSON::Object::Ptr payload) {
|
||||
payload_ = std::move(payload);
|
||||
}
|
||||
inline void SetPayload(Poco::JSON::Object::Ptr payload) { payload_ = std::move(payload); }
|
||||
void Send();
|
||||
|
||||
private:
|
||||
@@ -32,11 +28,11 @@ namespace OpenWifi {
|
||||
|
||||
class DeviceFirmwareChangeKafkaEvent : public GWKafkaEvents {
|
||||
public:
|
||||
DeviceFirmwareChangeKafkaEvent( const std::string &serialNumber, std::uint64_t timestamp, const std::string &oldFirmware, const std::string &newFirmware) :
|
||||
GWKafkaEvents(serialNumber,"unit.firmware_change", timestamp),
|
||||
oldFirmware_(oldFirmware),
|
||||
newFirmware_(newFirmware) {
|
||||
}
|
||||
DeviceFirmwareChangeKafkaEvent(const std::string &serialNumber, std::uint64_t timestamp,
|
||||
const std::string &oldFirmware,
|
||||
const std::string &newFirmware)
|
||||
: GWKafkaEvents(serialNumber, "unit.firmware_change", timestamp),
|
||||
oldFirmware_(oldFirmware), newFirmware_(newFirmware) {}
|
||||
|
||||
~DeviceFirmwareChangeKafkaEvent() {
|
||||
Poco::JSON::Object::Ptr payload = new Poco::JSON::Object;
|
||||
@@ -52,9 +48,9 @@ namespace OpenWifi {
|
||||
|
||||
class DeviceConfigurationChangeKafkaEvent : public GWKafkaEvents {
|
||||
public:
|
||||
DeviceConfigurationChangeKafkaEvent( const std::string &serialNumber, std::uint64_t timestamp, const std::string config) :
|
||||
GWKafkaEvents(serialNumber,"unit.configuration_change", timestamp),
|
||||
config_(config) {
|
||||
DeviceConfigurationChangeKafkaEvent(const std::string &serialNumber,
|
||||
std::uint64_t timestamp, const std::string config)
|
||||
: GWKafkaEvents(serialNumber, "unit.configuration_change", timestamp), config_(config) {
|
||||
}
|
||||
|
||||
~DeviceConfigurationChangeKafkaEvent() {
|
||||
@@ -70,11 +66,12 @@ namespace OpenWifi {
|
||||
|
||||
class DeviceBlacklistedKafkaEvent : public GWKafkaEvents {
|
||||
public:
|
||||
explicit DeviceBlacklistedKafkaEvent( const std::string &serialNumber, std::uint64_t timestamp, const std::string &reason, const std::string &author, std::uint64_t created, std::string &IP) :
|
||||
GWKafkaEvents(serialNumber,"blacklisted_device", timestamp),
|
||||
reason_(reason), author_(author), created_(created), IP_(IP)
|
||||
{
|
||||
}
|
||||
explicit DeviceBlacklistedKafkaEvent(const std::string &serialNumber,
|
||||
std::uint64_t timestamp, const std::string &reason,
|
||||
const std::string &author, std::uint64_t created,
|
||||
std::string &IP)
|
||||
: GWKafkaEvents(serialNumber, "blacklisted_device", timestamp), reason_(reason),
|
||||
author_(author), created_(created), IP_(IP) {}
|
||||
|
||||
~DeviceBlacklistedKafkaEvent() {
|
||||
Poco::JSON::Object::Ptr payload = new Poco::JSON::Object;
|
||||
@@ -93,5 +90,3 @@ namespace OpenWifi {
|
||||
};
|
||||
|
||||
} // namespace OpenWifi
|
||||
|
||||
|
||||
|
||||
@@ -7,16 +7,15 @@
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
GwWebSocketClient::GwWebSocketClient(Poco::Logger &Logger):
|
||||
Logger_(Logger){
|
||||
GwWebSocketClient::GwWebSocketClient(Poco::Logger &Logger) : Logger_(Logger) {
|
||||
UI_WebSocketClientServer()->SetProcessor(this);
|
||||
}
|
||||
|
||||
GwWebSocketClient::~GwWebSocketClient() {
|
||||
UI_WebSocketClientServer()->SetProcessor(nullptr);
|
||||
}
|
||||
GwWebSocketClient::~GwWebSocketClient() { UI_WebSocketClientServer()->SetProcessor(nullptr); }
|
||||
|
||||
void GwWebSocketClient::Processor(const Poco::JSON::Object::Ptr &O, std::string &Answer, bool &Done, [[maybe_unused]] const SecurityObjects::UserInfo &UserInfo) {
|
||||
void GwWebSocketClient::Processor(const Poco::JSON::Object::Ptr &O, std::string &Answer,
|
||||
bool &Done,
|
||||
[[maybe_unused]] const SecurityObjects::UserInfo &UserInfo) {
|
||||
try {
|
||||
if (O->has("command")) {
|
||||
auto Command = O->get("command").toString();
|
||||
@@ -51,13 +50,15 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
|
||||
void GwWebSocketClient::ws_command_exit([[maybe_unused]] const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer) {
|
||||
void GwWebSocketClient::ws_command_exit([[maybe_unused]] const Poco::JSON::Object::Ptr &O,
|
||||
bool &Done, std::string &Answer) {
|
||||
Done = true;
|
||||
Answer = R"lit({ "closing" : "Goodbye! Aurevoir! Hasta la vista!" })lit";
|
||||
}
|
||||
|
||||
void GwWebSocketClient::ws_command_invalid([[maybe_unused]] const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer) {
|
||||
void GwWebSocketClient::ws_command_invalid([[maybe_unused]] const Poco::JSON::Object::Ptr &O,
|
||||
bool &Done, std::string &Answer) {
|
||||
Done = false;
|
||||
Answer = std::string{R"lit({ "error" : "invalid command" })lit"};
|
||||
}
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -11,8 +11,10 @@ namespace OpenWifi {
|
||||
public:
|
||||
explicit GwWebSocketClient(Poco::Logger &Logger);
|
||||
virtual ~GwWebSocketClient();
|
||||
virtual void Processor(const Poco::JSON::Object::Ptr &O, std::string &Answer, bool &Done, const SecurityObjects::UserInfo &UserInfo);
|
||||
void ws_command_serial_number_search( const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer);
|
||||
virtual void Processor(const Poco::JSON::Object::Ptr &O, std::string &Answer, bool &Done,
|
||||
const SecurityObjects::UserInfo &UserInfo);
|
||||
void ws_command_serial_number_search(const Poco::JSON::Object::Ptr &O, bool &Done,
|
||||
std::string &Answer);
|
||||
void ws_command_exit(const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer);
|
||||
void ws_command_invalid(const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer);
|
||||
|
||||
@@ -20,4 +22,4 @@ namespace OpenWifi {
|
||||
Poco::Logger &Logger_;
|
||||
inline Poco::Logger &Logger() { return Logger_; }
|
||||
};
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-06-17.
|
||||
//
|
||||
#include <thread>
|
||||
#include <fstream>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
#include "Poco/File.h"
|
||||
#include "Poco/StreamCopier.h"
|
||||
#include "Poco/String.h"
|
||||
#include "Poco/StringTokenizer.h"
|
||||
#include "Poco/URIStreamOpener.h"
|
||||
#include "Poco/StreamCopier.h"
|
||||
#include "Poco/File.h"
|
||||
|
||||
#include "framework/MicroServiceFuncs.h"
|
||||
#include "framework/utils.h"
|
||||
@@ -35,11 +35,11 @@ namespace OpenWifi {
|
||||
fmt::format("Recovered last OUI file - {}", CurrentOUIFileName_));
|
||||
}
|
||||
} else {
|
||||
poco_notice(Logger(),
|
||||
fmt::format("No existing OUIFile.", CurrentOUIFileName_));
|
||||
poco_notice(Logger(), fmt::format("No existing OUIFile.", CurrentOUIFileName_));
|
||||
}
|
||||
|
||||
UpdaterCallBack_ = std::make_unique<Poco::TimerCallback<OUIServer>>(*this, &OUIServer::onTimer);
|
||||
UpdaterCallBack_ =
|
||||
std::make_unique<Poco::TimerCallback<OUIServer>>(*this, &OUIServer::onTimer);
|
||||
if (Recovered) {
|
||||
Timer_.setStartInterval(60 * 60 * 1000); // first run in 1 hour
|
||||
} else {
|
||||
@@ -67,14 +67,18 @@ namespace OpenWifi {
|
||||
bool OUIServer::GetFile(const std::string &FileName) {
|
||||
try {
|
||||
LastUpdate_ = Utils::Now();
|
||||
poco_information(Logger(), fmt::format("Start: Retrieving OUI file: {}",MicroServiceConfigGetString("oui.download.uri","")));
|
||||
std::unique_ptr<std::istream> pStr(
|
||||
Poco::URIStreamOpener::defaultOpener().open(MicroServiceConfigGetString("oui.download.uri","")));
|
||||
poco_information(Logger(),
|
||||
fmt::format("Start: Retrieving OUI file: {}",
|
||||
MicroServiceConfigGetString("oui.download.uri", "")));
|
||||
std::unique_ptr<std::istream> pStr(Poco::URIStreamOpener::defaultOpener().open(
|
||||
MicroServiceConfigGetString("oui.download.uri", "")));
|
||||
std::ofstream OS;
|
||||
OS.open(FileName);
|
||||
Poco::StreamCopier::copyStream(*pStr, OS);
|
||||
OS.close();
|
||||
poco_information(Logger(), fmt::format("Done: Retrieving OUI file: {}",MicroServiceConfigGetString("oui.download.uri","")));
|
||||
poco_information(Logger(),
|
||||
fmt::format("Done: Retrieving OUI file: {}",
|
||||
MicroServiceConfigGetString("oui.download.uri", "")));
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger().log(E);
|
||||
@@ -154,7 +158,8 @@ namespace OpenWifi {
|
||||
F1.remove();
|
||||
Poco::File F2(LatestOUIFileName_);
|
||||
F2.renameTo(CurrentOUIFileName_);
|
||||
poco_information(Logger(), fmt::format("New OUI file {} downloaded.",LatestOUIFileName_));
|
||||
poco_information(Logger(),
|
||||
fmt::format("New OUI file {} downloaded.", LatestOUIFileName_));
|
||||
} else if (OUIs_.empty()) {
|
||||
if (ProcessFile(CurrentOUIFileName_, TmpOUIs)) {
|
||||
LastUpdate_ = Utils::Now();
|
||||
@@ -175,4 +180,4 @@ namespace OpenWifi {
|
||||
return Manufacturer->second;
|
||||
return "";
|
||||
}
|
||||
};
|
||||
}; // namespace OpenWifi
|
||||
|
||||
@@ -14,7 +14,6 @@ namespace OpenWifi {
|
||||
|
||||
class OUIServer : public SubSystemServer {
|
||||
public:
|
||||
|
||||
typedef std::map<uint64_t, std::string> OUIMap;
|
||||
|
||||
static auto instance() {
|
||||
@@ -43,13 +42,9 @@ namespace OpenWifi {
|
||||
std::unique_ptr<Poco::TimerCallback<OUIServer>> UpdaterCallBack_;
|
||||
std::string LatestOUIFileName_, CurrentOUIFileName_;
|
||||
|
||||
OUIServer() noexcept:
|
||||
SubSystemServer("OUIServer", "OUI-SVR", "ouiserver")
|
||||
{
|
||||
}
|
||||
OUIServer() noexcept : SubSystemServer("OUIServer", "OUI-SVR", "ouiserver") {}
|
||||
};
|
||||
|
||||
inline auto OUIServer() { return OUIServer::instance(); }
|
||||
|
||||
}
|
||||
|
||||
} // namespace OpenWifi
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,15 +4,15 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
#include "Poco/HMACEngine.h"
|
||||
#include "Poco/MD5Engine.h"
|
||||
#include "Poco/StringTokenizer.h"
|
||||
#include "Poco/Net/SocketAddress.h"
|
||||
#include "Poco/StringTokenizer.h"
|
||||
|
||||
namespace OpenWifi::RADIUS {
|
||||
|
||||
@@ -170,11 +170,9 @@ static const struct tok radius_command_values[] = {
|
||||
{RADCMD_RES_QUERY_REQ, "Resource-Query-Request"},
|
||||
{RADCMD_RES_QUERY_RES, "Resource-Query-Response"},
|
||||
{RADCMD_RES_ALT_RECLAIM_REQ, "Alternate-Resource-Reclaim-Request"},
|
||||
{ 0, nullptr}
|
||||
};
|
||||
{0, nullptr}};
|
||||
|
||||
static const struct tok radius_attribute_names[] = {
|
||||
{1,"User-Name"},
|
||||
static const struct tok radius_attribute_names[] = {{1, "User-Name"},
|
||||
{2, "User-Password"},
|
||||
{3, "CHAP-Password"},
|
||||
{4, "NAS-IP Address"},
|
||||
@@ -257,8 +255,7 @@ static const struct tok radius_attribute_names[] = {
|
||||
{88, "Framed-Pool"},
|
||||
{90, "Tunnel-Client-Auth-ID"},
|
||||
{91, "Tunnel-Server-Auth-ID"},
|
||||
{0, nullptr}
|
||||
};
|
||||
{0, nullptr}};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct RadiusAttribute {
|
||||
@@ -295,25 +292,18 @@ static const struct tok radius_attribute_names[] = {
|
||||
constexpr unsigned char ATTR_MessageAuthenticator = 80;
|
||||
|
||||
inline bool IsAuthentication(unsigned char t) {
|
||||
return (t == RADIUS::Access_Request ||
|
||||
t == RADIUS::Access_Accept ||
|
||||
t == RADIUS::Access_Challenge ||
|
||||
t == RADIUS::Access_Reject);
|
||||
return (t == RADIUS::Access_Request || t == RADIUS::Access_Accept ||
|
||||
t == RADIUS::Access_Challenge || t == RADIUS::Access_Reject);
|
||||
}
|
||||
|
||||
inline bool IsAccounting(unsigned char t) {
|
||||
return (t == RADIUS::Accounting_Request ||
|
||||
t == RADIUS::Accounting_Response ||
|
||||
t == RADIUS::Accounting_Status ||
|
||||
t == RADIUS::Accounting_Message);
|
||||
return (t == RADIUS::Accounting_Request || t == RADIUS::Accounting_Response ||
|
||||
t == RADIUS::Accounting_Status || t == RADIUS::Accounting_Message);
|
||||
}
|
||||
|
||||
inline bool IsAuthority(unsigned char t) {
|
||||
return (t == RADIUS::Disconnect_Request ||
|
||||
t == RADIUS::Disconnect_ACK ||
|
||||
t == RADIUS::Disconnect_NAK ||
|
||||
t == RADIUS::CoA_Request ||
|
||||
t == RADIUS::CoA_ACK ||
|
||||
return (t == RADIUS::Disconnect_Request || t == RADIUS::Disconnect_ACK ||
|
||||
t == RADIUS::Disconnect_NAK || t == RADIUS::CoA_Request || t == RADIUS::CoA_ACK ||
|
||||
t == RADIUS::CoA_NAK);
|
||||
}
|
||||
|
||||
@@ -321,7 +311,8 @@ static const struct tok radius_attribute_names[] = {
|
||||
auto cmds = radius_command_values;
|
||||
while (cmds->cmd && (cmds->cmd != cmd))
|
||||
cmds++;
|
||||
if(cmds->cmd==cmd) return cmds->name;
|
||||
if (cmds->cmd == cmd)
|
||||
return cmds->name;
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
@@ -329,7 +320,8 @@ static const struct tok radius_attribute_names[] = {
|
||||
auto cmds = radius_attribute_names;
|
||||
while (cmds->cmd && (cmds->cmd != cmd))
|
||||
cmds++;
|
||||
if(cmds->cmd==cmd) return cmds->name;
|
||||
if (cmds->cmd == cmd)
|
||||
return cmds->name;
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
@@ -350,25 +342,31 @@ static const struct tok radius_attribute_names[] = {
|
||||
|
||||
inline std::ostream &operator<<(std::ostream &os, AttributeList const &P) {
|
||||
for (const auto &attr : P) {
|
||||
os << "\tAttr: " << (uint16_t) attr.type << " Size: " << (uint16_t) attr.len << std::endl;
|
||||
os << "\tAttr: " << (uint16_t)attr.type << " Size: " << (uint16_t)attr.len
|
||||
<< std::endl;
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
inline bool ParseRadius(uint32_t offset, const unsigned char *Buffer, uint16_t Size, AttributeList &Attrs) {
|
||||
inline bool ParseRadius(uint32_t offset, const unsigned char *Buffer, uint16_t Size,
|
||||
AttributeList &Attrs) {
|
||||
Attrs.clear();
|
||||
uint16_t pos = 0;
|
||||
auto x = 25;
|
||||
while (pos < Size && x) {
|
||||
RadiusAttribute Attr{ .type=Buffer[pos], .pos=(uint16_t)(pos+2+offset), .len=(unsigned int)(Buffer[pos+1]-2)};
|
||||
RadiusAttribute Attr{.type = Buffer[pos],
|
||||
.pos = (uint16_t)(pos + 2 + offset),
|
||||
.len = (unsigned int)(Buffer[pos + 1] - 2)};
|
||||
if (pos + Attr.len <= Size) {
|
||||
Attrs.emplace_back(Attr);
|
||||
} else {
|
||||
std::cout << "Bad parse1: " << (uint32_t) (pos+Attr.len) << " S:" << Size << std::endl;
|
||||
std::cout << "Bad parse1: " << (uint32_t)(pos + Attr.len) << " S:" << Size
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
if (Buffer[pos + 1] == 0) {
|
||||
std::cout << "Bad parse2: " << (uint32_t) (pos+Attr.len) << " S:" << Size << std::endl;
|
||||
std::cout << "Bad parse2: " << (uint32_t)(pos + Attr.len) << " S:" << Size
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
pos += Buffer[pos + 1];
|
||||
@@ -438,31 +436,23 @@ static const struct tok radius_attribute_names[] = {
|
||||
friend std::ostream &operator<<(std::ostream &os, RadiusPacket const &P);
|
||||
|
||||
inline bool IsAuthentication() {
|
||||
return (P_.code == RADIUS::Access_Request ||
|
||||
P_.code == RADIUS::Access_Accept ||
|
||||
P_.code == RADIUS::Access_Challenge ||
|
||||
P_.code == RADIUS::Access_Reject ||
|
||||
P_.code == RADCMD_RES_FREE_REQ ||
|
||||
P_.code == RADCMD_RES_FREE_RES ||
|
||||
P_.code == RADCMD_RES_QUERY_REQ ||
|
||||
P_.code == RADCMD_RES_QUERY_RES ||
|
||||
return (P_.code == RADIUS::Access_Request || P_.code == RADIUS::Access_Accept ||
|
||||
P_.code == RADIUS::Access_Challenge || P_.code == RADIUS::Access_Reject ||
|
||||
P_.code == RADCMD_RES_FREE_REQ || P_.code == RADCMD_RES_FREE_RES ||
|
||||
P_.code == RADCMD_RES_QUERY_REQ || P_.code == RADCMD_RES_QUERY_RES ||
|
||||
P_.code == RADCMD_RES_ALT_RECLAIM_REQ);
|
||||
}
|
||||
|
||||
inline bool IsAccounting() {
|
||||
return (P_.code == RADIUS::Accounting_Request ||
|
||||
P_.code == RADIUS::Accounting_Response ||
|
||||
P_.code == RADIUS::Accounting_Status ||
|
||||
P_.code == RADIUS::Accounting_Message);
|
||||
P_.code == RADIUS::Accounting_Status || P_.code == RADIUS::Accounting_Message);
|
||||
}
|
||||
|
||||
inline bool IsAuthority() {
|
||||
return (P_.code == RADIUS::Disconnect_Request ||
|
||||
P_.code == RADIUS::Disconnect_ACK ||
|
||||
P_.code == RADIUS::Disconnect_NAK ||
|
||||
P_.code == RADIUS::CoA_Request ||
|
||||
P_.code == RADIUS::CoA_ACK ||
|
||||
P_.code == RADIUS::CoA_NAK);
|
||||
return (P_.code == RADIUS::Disconnect_Request || P_.code == RADIUS::Disconnect_ACK ||
|
||||
P_.code == RADIUS::Disconnect_NAK || P_.code == RADIUS::CoA_Request ||
|
||||
P_.code == RADIUS::CoA_ACK || P_.code == RADIUS::CoA_NAK);
|
||||
}
|
||||
|
||||
void Log(std::ostream &os) {
|
||||
@@ -472,7 +462,8 @@ static const struct tok radius_attribute_names[] = {
|
||||
os << std::setfill('0') << std::setw(4) << p << ": ";
|
||||
uint16_t v = 0;
|
||||
while (v < 16 && p + v < Size_) {
|
||||
os << std::setfill('0') << std::setw(2) << std::right << std::hex << (uint16_t )((const unsigned char *)&P_)[p+v] << " ";
|
||||
os << std::setfill('0') << std::setw(2) << std::right << std::hex
|
||||
<< (uint16_t)((const unsigned char *)&P_)[p + v] << " ";
|
||||
v++;
|
||||
}
|
||||
os << std::endl;
|
||||
@@ -482,13 +473,9 @@ static const struct tok radius_attribute_names[] = {
|
||||
Print(os);
|
||||
}
|
||||
|
||||
inline const char * PacketType() {
|
||||
return CommandName(P_.code);
|
||||
}
|
||||
inline const char *PacketType() { return CommandName(P_.code); }
|
||||
|
||||
inline int PacketTypeInt() {
|
||||
return (int)(P_.code);
|
||||
}
|
||||
inline int PacketTypeInt() { return (int)(P_.code); }
|
||||
|
||||
void ComputeMessageAuthenticator(const std::string &secret) {
|
||||
RawRadiusPacket P = P_;
|
||||
@@ -551,7 +538,8 @@ static const struct tok radius_attribute_names[] = {
|
||||
os << pre << std::setfill('0') << std::setw(4) << p << ": ";
|
||||
uint16_t v = 0;
|
||||
while (v < 16 && p + v < s) {
|
||||
os << std::setfill('0') << std::setw(2) << std::right << std::hex << (uint16_t )b[p+v] << " ";
|
||||
os << std::setfill('0') << std::setw(2) << std::right << std::hex
|
||||
<< (uint16_t)b[p + v] << " ";
|
||||
v++;
|
||||
}
|
||||
os << std::endl;
|
||||
@@ -568,7 +556,8 @@ static const struct tok radius_attribute_names[] = {
|
||||
BufLog(os, "", P_.authenticator, sizeof(P_.authenticator));
|
||||
os << " Attributes: " << std::endl;
|
||||
for (const auto &attr : Attrs_) {
|
||||
os << " " << std::setfill(' ') << "(" << std::setw(4) << (uint) attr.type << ") " << AttributeName(attr.type) << " Len:" << attr.len << std::endl;
|
||||
os << " " << std::setfill(' ') << "(" << std::setw(4) << (uint)attr.type << ") "
|
||||
<< AttributeName(attr.type) << " Len:" << attr.len << std::endl;
|
||||
BufLog(os, " ", &P_.attributes[attr.pos], attr.len);
|
||||
}
|
||||
os << std::dec << std::endl << std::endl;
|
||||
@@ -583,8 +572,8 @@ static const struct tok radius_attribute_names[] = {
|
||||
uint32_t VendorId = htonl(*(const uint32_t *)&(P_.attributes[attribute.pos]));
|
||||
// std::cout << VendorId << std::endl;
|
||||
if (VendorId == TIP_vendor_id && attribute.len > (4 + 2)) {
|
||||
if (ParseRadius(attribute.pos + 4, &P_.attributes[attribute.pos + 4], attribute.len - 4 - 2,
|
||||
VendorAttributes)) {
|
||||
if (ParseRadius(attribute.pos + 4, &P_.attributes[attribute.pos + 4],
|
||||
attribute.len - 4 - 2, VendorAttributes)) {
|
||||
// std::cout << VendorAttributes << std::endl;
|
||||
for (const auto &vendorAttr : VendorAttributes) {
|
||||
if (vendorAttr.type == TIP_serial) {
|
||||
@@ -609,7 +598,8 @@ static const struct tok radius_attribute_names[] = {
|
||||
if (attribute.type == 33) {
|
||||
std::string Attr33;
|
||||
// format is serial:IP:port:interface
|
||||
Attr33.assign((const char *)(const char *)&P_.attributes[attribute.pos],attribute.len-2);
|
||||
Attr33.assign((const char *)(const char *)&P_.attributes[attribute.pos],
|
||||
attribute.len - 2);
|
||||
auto Parts = Poco::StringTokenizer(Attr33, "|");
|
||||
if (Parts.count() == 4) {
|
||||
return Parts[0];
|
||||
@@ -630,7 +620,8 @@ static const struct tok radius_attribute_names[] = {
|
||||
if (attribute.type == 33 && attribute.len > 2) {
|
||||
std::string Attr33;
|
||||
// format is serial:IP:port:interface
|
||||
Attr33.assign((const char *)(const char *)&P_.attributes[attribute.pos],attribute.len-2);
|
||||
Attr33.assign((const char *)(const char *)&P_.attributes[attribute.pos],
|
||||
attribute.len - 2);
|
||||
auto Parts = Poco::StringTokenizer(Attr33, "|");
|
||||
if (Parts.count() == 4) {
|
||||
Poco::Net::SocketAddress D(Parts[1], Parts[2]);
|
||||
@@ -651,7 +642,8 @@ static const struct tok radius_attribute_names[] = {
|
||||
std::string Result;
|
||||
for (const auto &attribute : Attrs_) {
|
||||
if (attribute.type == 31 && attribute.len > 2) {
|
||||
Result.assign((const char *)(const char *)&P_.attributes[attribute.pos],attribute.len-2);
|
||||
Result.assign((const char *)(const char *)&P_.attributes[attribute.pos],
|
||||
attribute.len - 2);
|
||||
return Result;
|
||||
}
|
||||
}
|
||||
@@ -662,7 +654,8 @@ static const struct tok radius_attribute_names[] = {
|
||||
std::string Result;
|
||||
for (const auto &attribute : Attrs_) {
|
||||
if (attribute.type == 30 && attribute.len > 2) {
|
||||
Result.assign((const char *)(const char *)&P_.attributes[attribute.pos],attribute.len-2);
|
||||
Result.assign((const char *)(const char *)&P_.attributes[attribute.pos],
|
||||
attribute.len - 2);
|
||||
return Result;
|
||||
}
|
||||
}
|
||||
@@ -688,16 +681,15 @@ static const struct tok radius_attribute_names[] = {
|
||||
|
||||
class RadiusOutputPacket {
|
||||
public:
|
||||
explicit RadiusOutputPacket(const std::string &Secret)
|
||||
: Secret_(Secret) {
|
||||
}
|
||||
explicit RadiusOutputPacket(const std::string &Secret) : Secret_(Secret) {}
|
||||
|
||||
inline void MakeStatusMessage() {
|
||||
P_.code = RADCMD_STATUS_SER;
|
||||
P_.identifier = std::rand() & 0x00ff;
|
||||
MakeRadiusAuthenticator(P_.authenticator);
|
||||
unsigned char MessageAuthenticator[16]{0};
|
||||
AddAttribute(ATTR_MessageAuthenticator,sizeof(MessageAuthenticator),MessageAuthenticator);
|
||||
AddAttribute(ATTR_MessageAuthenticator, sizeof(MessageAuthenticator),
|
||||
MessageAuthenticator);
|
||||
P_.rawlen = 1 + 1 + 2 + 16 + 1 + 1 + 16;
|
||||
|
||||
Poco::HMACEngine<Poco::MD5Engine> H(Secret_);
|
||||
@@ -715,7 +707,9 @@ static const struct tok radius_attribute_names[] = {
|
||||
AttributesLen_ += len;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline const unsigned char * Data() const { return (const unsigned char *) &P_;}
|
||||
[[nodiscard]] inline const unsigned char *Data() const {
|
||||
return (const unsigned char *)&P_;
|
||||
}
|
||||
[[nodiscard]] inline std::uint16_t Len() const { return P_.rawlen; }
|
||||
|
||||
private:
|
||||
@@ -728,4 +722,4 @@ static const struct tok radius_attribute_names[] = {
|
||||
os << P.Attrs_;
|
||||
return os;
|
||||
}
|
||||
}
|
||||
} // namespace OpenWifi::RADIUS
|
||||
@@ -4,9 +4,9 @@
|
||||
|
||||
#include "Poco/JSON/Parser.h"
|
||||
|
||||
#include "RADIUS_proxy_server.h"
|
||||
#include "RADIUS_helpers.h"
|
||||
#include "AP_WS_Server.h"
|
||||
#include "RADIUS_helpers.h"
|
||||
#include "RADIUS_proxy_server.h"
|
||||
|
||||
#include "framework/MicroServiceFuncs.h"
|
||||
|
||||
@@ -32,43 +32,66 @@ namespace OpenWifi {
|
||||
|
||||
Enabled_ = true;
|
||||
|
||||
Poco::Net::SocketAddress AuthSockAddrV4(Poco::Net::AddressFamily::IPv4,
|
||||
MicroServiceConfigGetInt("radius.proxy.authentication.port",DEFAULT_RADIUS_AUTHENTICATION_PORT));
|
||||
AuthenticationSocketV4_ = std::make_unique<Poco::Net::DatagramSocket>(AuthSockAddrV4,true,true);
|
||||
Poco::Net::SocketAddress AuthSockAddrV6(Poco::Net::AddressFamily::IPv6,
|
||||
MicroServiceConfigGetInt("radius.proxy.authentication.port",DEFAULT_RADIUS_AUTHENTICATION_PORT));
|
||||
AuthenticationSocketV6_ = std::make_unique<Poco::Net::DatagramSocket>(AuthSockAddrV6,true,true);
|
||||
Poco::Net::SocketAddress AuthSockAddrV4(
|
||||
Poco::Net::AddressFamily::IPv4,
|
||||
MicroServiceConfigGetInt("radius.proxy.authentication.port",
|
||||
DEFAULT_RADIUS_AUTHENTICATION_PORT));
|
||||
AuthenticationSocketV4_ =
|
||||
std::make_unique<Poco::Net::DatagramSocket>(AuthSockAddrV4, true, true);
|
||||
Poco::Net::SocketAddress AuthSockAddrV6(
|
||||
Poco::Net::AddressFamily::IPv6,
|
||||
MicroServiceConfigGetInt("radius.proxy.authentication.port",
|
||||
DEFAULT_RADIUS_AUTHENTICATION_PORT));
|
||||
AuthenticationSocketV6_ =
|
||||
std::make_unique<Poco::Net::DatagramSocket>(AuthSockAddrV6, true, true);
|
||||
|
||||
Poco::Net::SocketAddress AcctSockAddrV4(Poco::Net::AddressFamily::IPv4,
|
||||
MicroServiceConfigGetInt("radius.proxy.accounting.port",DEFAULT_RADIUS_ACCOUNTING_PORT));
|
||||
AccountingSocketV4_ = std::make_unique<Poco::Net::DatagramSocket>(AcctSockAddrV4,true,true);
|
||||
Poco::Net::SocketAddress AcctSockAddrV6(Poco::Net::AddressFamily::IPv6,
|
||||
MicroServiceConfigGetInt("radius.proxy.accounting.port",DEFAULT_RADIUS_ACCOUNTING_PORT));
|
||||
AccountingSocketV6_ = std::make_unique<Poco::Net::DatagramSocket>(AcctSockAddrV6,true,true);
|
||||
Poco::Net::SocketAddress AcctSockAddrV4(
|
||||
Poco::Net::AddressFamily::IPv4,
|
||||
MicroServiceConfigGetInt("radius.proxy.accounting.port",
|
||||
DEFAULT_RADIUS_ACCOUNTING_PORT));
|
||||
AccountingSocketV4_ =
|
||||
std::make_unique<Poco::Net::DatagramSocket>(AcctSockAddrV4, true, true);
|
||||
Poco::Net::SocketAddress AcctSockAddrV6(
|
||||
Poco::Net::AddressFamily::IPv6,
|
||||
MicroServiceConfigGetInt("radius.proxy.accounting.port",
|
||||
DEFAULT_RADIUS_ACCOUNTING_PORT));
|
||||
AccountingSocketV6_ =
|
||||
std::make_unique<Poco::Net::DatagramSocket>(AcctSockAddrV6, true, true);
|
||||
|
||||
Poco::Net::SocketAddress CoASockAddrV4(Poco::Net::AddressFamily::IPv4,
|
||||
Poco::Net::SocketAddress CoASockAddrV4(
|
||||
Poco::Net::AddressFamily::IPv4,
|
||||
MicroServiceConfigGetInt("radius.proxy.coa.port", DEFAULT_RADIUS_CoA_PORT));
|
||||
CoASocketV4_ = std::make_unique<Poco::Net::DatagramSocket>(CoASockAddrV4, true, true);
|
||||
Poco::Net::SocketAddress CoASockAddrV6(Poco::Net::AddressFamily::IPv6,
|
||||
Poco::Net::SocketAddress CoASockAddrV6(
|
||||
Poco::Net::AddressFamily::IPv6,
|
||||
MicroServiceConfigGetInt("radius.proxy.coa.port", DEFAULT_RADIUS_CoA_PORT));
|
||||
CoASocketV6_ = std::make_unique<Poco::Net::DatagramSocket>(CoASockAddrV6, true, true);
|
||||
|
||||
RadiusReactor_.reset();
|
||||
RadiusReactor_ = std::make_unique<Poco::Net::SocketReactor>();
|
||||
RadiusReactor_->addEventHandler(*AuthenticationSocketV4_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
RadiusReactor_->addEventHandler(
|
||||
*AuthenticationSocketV4_,
|
||||
Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnAuthenticationSocketReadable));
|
||||
RadiusReactor_->addEventHandler(*AuthenticationSocketV6_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
RadiusReactor_->addEventHandler(
|
||||
*AuthenticationSocketV6_,
|
||||
Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnAuthenticationSocketReadable));
|
||||
|
||||
RadiusReactor_->addEventHandler(*AccountingSocketV4_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
RadiusReactor_->addEventHandler(
|
||||
*AccountingSocketV4_,
|
||||
Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnAccountingSocketReadable));
|
||||
RadiusReactor_->addEventHandler(*AccountingSocketV6_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
RadiusReactor_->addEventHandler(
|
||||
*AccountingSocketV6_,
|
||||
Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnAccountingSocketReadable));
|
||||
|
||||
|
||||
RadiusReactor_->addEventHandler(*CoASocketV4_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
RadiusReactor_->addEventHandler(
|
||||
*CoASocketV4_, Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnCoASocketReadable));
|
||||
RadiusReactor_->addEventHandler(*CoASocketV6_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
RadiusReactor_->addEventHandler(
|
||||
*CoASocketV6_, Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnCoASocketReadable));
|
||||
|
||||
ParseConfig();
|
||||
@@ -137,7 +160,8 @@ namespace OpenWifi {
|
||||
for (const auto &pool : PoolList_.pools) {
|
||||
for (const auto &entry : pool.authConfig.servers) {
|
||||
if (entry.radsec) {
|
||||
RADSECservers_[ Poco::Net::SocketAddress(entry.ip,0) ] = std::make_unique<RADSEC_server>(*RadiusReactor_,entry);
|
||||
RADSECservers_[Poco::Net::SocketAddress(entry.ip, 0)] =
|
||||
std::make_unique<RADSEC_server>(*RadiusReactor_, entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -148,7 +172,8 @@ namespace OpenWifi {
|
||||
RADSECservers_.clear();
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::OnAccountingSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf) {
|
||||
void RADIUS_proxy_server::OnAccountingSocketReadable(
|
||||
const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) {
|
||||
Poco::Net::SocketAddress Sender;
|
||||
RADIUS::RadiusPacket P;
|
||||
|
||||
@@ -166,11 +191,16 @@ namespace OpenWifi {
|
||||
auto CallingStationID = P.ExtractCallingStationID();
|
||||
auto CalledStationID = P.ExtractCalledStationID();
|
||||
|
||||
poco_debug(Logger(), fmt::format("Accounting Packet received for {}, CalledStationID: {}, CallingStationID:{}",SerialNumber, CalledStationID, CallingStationID));
|
||||
poco_debug(
|
||||
Logger(),
|
||||
fmt::format(
|
||||
"Accounting Packet received for {}, CalledStationID: {}, CallingStationID:{}",
|
||||
SerialNumber, CalledStationID, CallingStationID));
|
||||
AP_WS_Server()->SendRadiusAccountingData(SerialNumber, P.Buffer(), P.Size());
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::OnAuthenticationSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf) {
|
||||
void RADIUS_proxy_server::OnAuthenticationSocketReadable(
|
||||
const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) {
|
||||
Poco::Net::SocketAddress Sender;
|
||||
RADIUS::RadiusPacket P;
|
||||
|
||||
@@ -188,11 +218,16 @@ namespace OpenWifi {
|
||||
auto CallingStationID = P.ExtractCallingStationID();
|
||||
auto CalledStationID = P.ExtractCalledStationID();
|
||||
|
||||
poco_debug(Logger(), fmt::format("Authentication Packet received for {}, CalledStationID: {}, CallingStationID:{}",SerialNumber, CalledStationID, CallingStationID));
|
||||
poco_debug(
|
||||
Logger(),
|
||||
fmt::format(
|
||||
"Authentication Packet received for {}, CalledStationID: {}, CallingStationID:{}",
|
||||
SerialNumber, CalledStationID, CallingStationID));
|
||||
AP_WS_Server()->SendRadiusAuthenticationData(SerialNumber, P.Buffer(), P.Size());
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::OnCoASocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf) {
|
||||
void RADIUS_proxy_server::OnCoASocketReadable(
|
||||
const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) {
|
||||
Poco::Net::SocketAddress Sender;
|
||||
RADIUS::RadiusPacket P;
|
||||
|
||||
@@ -210,11 +245,15 @@ namespace OpenWifi {
|
||||
auto CallingStationID = P.ExtractCallingStationID();
|
||||
auto CalledStationID = P.ExtractCalledStationID();
|
||||
|
||||
poco_debug(Logger(), fmt::format("CoA Packet received for {}, CalledStationID: {}, CallingStationID:{}",SerialNumber, CalledStationID, CallingStationID));
|
||||
poco_debug(
|
||||
Logger(),
|
||||
fmt::format("CoA Packet received for {}, CalledStationID: {}, CallingStationID:{}",
|
||||
SerialNumber, CalledStationID, CallingStationID));
|
||||
AP_WS_Server()->SendRadiusCoAData(SerialNumber, P.Buffer(), P.Size());
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::SendAccountingData(const std::string &serialNumber, const char *buffer, std::size_t size) {
|
||||
void RADIUS_proxy_server::SendAccountingData(const std::string &serialNumber,
|
||||
const char *buffer, std::size_t size) {
|
||||
|
||||
if (!Continue())
|
||||
return;
|
||||
@@ -257,22 +296,26 @@ namespace OpenWifi {
|
||||
fmt::format("{}: Could not send Accounting packet packet to {}.",
|
||||
serialNumber, Destination));
|
||||
else
|
||||
poco_debug(Logger(), fmt::format("{}: Sending Accounting Packet to {}, CalledStationID: {}, CallingStationID:{}",
|
||||
poco_debug(Logger(), fmt::format("{}: Sending Accounting Packet to {}, "
|
||||
"CalledStationID: {}, CallingStationID:{}",
|
||||
serialNumber, FinalDestination.toString(),
|
||||
CalledStationID, CallingStationID));
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger().log(E);
|
||||
} catch (...) {
|
||||
poco_warning(Logger(),fmt::format("Bad RADIUS ACCT Packet from {}. Dropped.",serialNumber));
|
||||
poco_warning(Logger(),
|
||||
fmt::format("Bad RADIUS ACCT Packet from {}. Dropped.", serialNumber));
|
||||
}
|
||||
}
|
||||
|
||||
bool RADIUS_proxy_server::SendData( Poco::Net::DatagramSocket & Sock, const unsigned char *buf , std::size_t size, const Poco::Net::SocketAddress &S) {
|
||||
bool RADIUS_proxy_server::SendData(Poco::Net::DatagramSocket &Sock, const unsigned char *buf,
|
||||
std::size_t size, const Poco::Net::SocketAddress &S) {
|
||||
return Sock.sendTo(buf, size, S) == (int)size;
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::SendAuthenticationData(const std::string &serialNumber, const char *buffer, std::size_t size) {
|
||||
void RADIUS_proxy_server::SendAuthenticationData(const std::string &serialNumber,
|
||||
const char *buffer, std::size_t size) {
|
||||
|
||||
if (!Continue())
|
||||
return;
|
||||
@@ -291,7 +334,8 @@ namespace OpenWifi {
|
||||
Poco::Net::SocketAddress RSP(FinalDestination.host(), 0);
|
||||
auto DestinationServer = RADSECservers_.find(RSP);
|
||||
if (DestinationServer != end(RADSECservers_)) {
|
||||
DestinationServer->second->SendData(serialNumber, (const unsigned char *)buffer, size);
|
||||
DestinationServer->second->SendData(serialNumber, (const unsigned char *)buffer,
|
||||
size);
|
||||
}
|
||||
} else {
|
||||
if ((Dst.family() == Poco::Net::SocketAddress::IPv4 &&
|
||||
@@ -300,12 +344,13 @@ namespace OpenWifi {
|
||||
AuthenticationSocketV6_ == nullptr)) {
|
||||
poco_debug(
|
||||
Logger(),
|
||||
fmt::format("AUTH: Trying to use RADIUS GW PROXY but not configured. Device={}",
|
||||
fmt::format(
|
||||
"AUTH: Trying to use RADIUS GW PROXY but not configured. Device={}",
|
||||
serialNumber));
|
||||
return;
|
||||
}
|
||||
auto AllSent =
|
||||
SendData(Dst.family() == Poco::Net::SocketAddress::IPv4 ? *AuthenticationSocketV4_
|
||||
auto AllSent = SendData(Dst.family() == Poco::Net::SocketAddress::IPv4
|
||||
? *AuthenticationSocketV4_
|
||||
: *AuthenticationSocketV6_,
|
||||
(const unsigned char *)buffer, size, FinalDestination);
|
||||
if (!AllSent)
|
||||
@@ -313,19 +358,21 @@ namespace OpenWifi {
|
||||
fmt::format("{}: Could not send Authentication packet packet to {}.",
|
||||
serialNumber, Destination));
|
||||
else
|
||||
poco_debug(Logger(), fmt::format("{}: Sending Authentication Packet to {}, CalledStationID: {}, CallingStationID:{}",
|
||||
poco_debug(Logger(), fmt::format("{}: Sending Authentication Packet to {}, "
|
||||
"CalledStationID: {}, CallingStationID:{}",
|
||||
serialNumber, FinalDestination.toString(),
|
||||
CalledStationID, CallingStationID));
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger().log(E);
|
||||
} catch (...) {
|
||||
poco_warning(Logger(),fmt::format("Bad RADIUS AUTH Packet from {}. Dropped.",serialNumber));
|
||||
poco_warning(Logger(),
|
||||
fmt::format("Bad RADIUS AUTH Packet from {}. Dropped.", serialNumber));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::SendCoAData(const std::string &serialNumber, const char *buffer, std::size_t size) {
|
||||
void RADIUS_proxy_server::SendCoAData(const std::string &serialNumber, const char *buffer,
|
||||
std::size_t size) {
|
||||
|
||||
if (!Continue())
|
||||
return;
|
||||
@@ -346,16 +393,21 @@ namespace OpenWifi {
|
||||
Poco::Net::SocketAddress RSP(FinalDestination.host(), 0);
|
||||
auto DestinationServer = RADSECservers_.find(RSP);
|
||||
if (DestinationServer != end(RADSECservers_)) {
|
||||
DestinationServer->second->SendData(serialNumber, (const unsigned char *)buffer, size);
|
||||
DestinationServer->second->SendData(serialNumber, (const unsigned char *)buffer,
|
||||
size);
|
||||
}
|
||||
} else {
|
||||
if ((Dst.family() == Poco::Net::SocketAddress::IPv4 && CoASocketV4_ == nullptr) ||
|
||||
(Dst.family() == Poco::Net::SocketAddress::IPv6 && CoASocketV6_ == nullptr)) {
|
||||
poco_debug(Logger(),fmt::format("CoA: Trying to use RADIUS GW PROXY but not configured. Device={}",serialNumber));
|
||||
poco_debug(
|
||||
Logger(),
|
||||
fmt::format(
|
||||
"CoA: Trying to use RADIUS GW PROXY but not configured. Device={}",
|
||||
serialNumber));
|
||||
return;
|
||||
}
|
||||
auto AllSent = SendData(Dst.family() == Poco::Net::SocketAddress::IPv4 ? *CoASocketV4_
|
||||
: *CoASocketV6_,
|
||||
auto AllSent = SendData(
|
||||
Dst.family() == Poco::Net::SocketAddress::IPv4 ? *CoASocketV4_ : *CoASocketV6_,
|
||||
(const unsigned char *)buffer, size, FinalDestination);
|
||||
if (!AllSent)
|
||||
poco_error(Logger(), fmt::format("{}: Could not send CoA packet packet to {}.",
|
||||
@@ -367,22 +419,26 @@ namespace OpenWifi {
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger().log(E);
|
||||
} catch (...) {
|
||||
poco_warning(Logger(),fmt::format("Bad RADIUS CoA/DM Packet from {}. Dropped.",serialNumber));
|
||||
poco_warning(Logger(),
|
||||
fmt::format("Bad RADIUS CoA/DM Packet from {}. Dropped.", serialNumber));
|
||||
}
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::ParseServerList(const GWObjects::RadiusProxyServerConfig & Config, std::vector<Destination> &V4, std::vector<Destination> &V6, bool setAsDefault) {
|
||||
void RADIUS_proxy_server::ParseServerList(const GWObjects::RadiusProxyServerConfig &Config,
|
||||
std::vector<Destination> &V4,
|
||||
std::vector<Destination> &V6, bool setAsDefault) {
|
||||
uint64_t TotalV4 = 0, TotalV6 = 0;
|
||||
|
||||
for (const auto &server : Config.servers) {
|
||||
Poco::Net::IPAddress a;
|
||||
if (!Poco::Net::IPAddress::tryParse(server.ip, a)) {
|
||||
poco_error(Logger(),fmt::format("RADIUS-PARSE Config: server address {} is nto a valid address in v4 or v6. Entry skipped.",server.ip));
|
||||
poco_error(Logger(), fmt::format("RADIUS-PARSE Config: server address {} is nto a "
|
||||
"valid address in v4 or v6. Entry skipped.",
|
||||
server.ip));
|
||||
continue;
|
||||
}
|
||||
auto S = Poco::Net::SocketAddress(fmt::format("{}:{}", server.ip, server.port));
|
||||
Destination D{
|
||||
.Addr = S,
|
||||
Destination D{.Addr = S,
|
||||
.state = 0,
|
||||
.step = 0,
|
||||
.weight = server.weight,
|
||||
@@ -393,8 +449,7 @@ namespace OpenWifi {
|
||||
.methodParameters = Config.methodParameters,
|
||||
.useAsDefault = setAsDefault,
|
||||
.useRADSEC = server.radsec,
|
||||
.realms = server.radsecRealms
|
||||
};
|
||||
.realms = server.radsecRealms};
|
||||
|
||||
if (setAsDefault && D.useRADSEC)
|
||||
DefaultIsRADSEC_ = true;
|
||||
@@ -442,21 +497,27 @@ namespace OpenWifi {
|
||||
PoolList_ = RPC;
|
||||
for (const auto &pool : RPC.pools) {
|
||||
RadiusPool NewPool;
|
||||
ParseServerList(pool.authConfig, NewPool.AuthV4, NewPool.AuthV6, pool.useByDefault);
|
||||
ParseServerList(pool.acctConfig, NewPool.AcctV4, NewPool.AcctV6, pool.useByDefault);
|
||||
ParseServerList(pool.coaConfig, NewPool.CoaV4, NewPool.CoaV6, pool.useByDefault);
|
||||
ParseServerList(pool.authConfig, NewPool.AuthV4, NewPool.AuthV6,
|
||||
pool.useByDefault);
|
||||
ParseServerList(pool.acctConfig, NewPool.AcctV4, NewPool.AcctV6,
|
||||
pool.useByDefault);
|
||||
ParseServerList(pool.coaConfig, NewPool.CoaV4, NewPool.CoaV6,
|
||||
pool.useByDefault);
|
||||
Pools_.push_back(NewPool);
|
||||
}
|
||||
} else {
|
||||
poco_warning(Logger(),fmt::format("Configuration file '{}' is bad.",ConfigFilename_));
|
||||
poco_warning(Logger(),
|
||||
fmt::format("Configuration file '{}' is bad.", ConfigFilename_));
|
||||
}
|
||||
} else {
|
||||
poco_warning(Logger(),fmt::format("No configuration file '{}' exists.",ConfigFilename_));
|
||||
poco_warning(Logger(),
|
||||
fmt::format("No configuration file '{}' exists.", ConfigFilename_));
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger().log(E);
|
||||
} catch (...) {
|
||||
poco_error(Logger(),fmt::format("Error while parsing configuration file '{}'",ConfigFilename_));
|
||||
poco_error(Logger(),
|
||||
fmt::format("Error while parsing configuration file '{}'", ConfigFilename_));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -466,7 +527,10 @@ namespace OpenWifi {
|
||||
return realm.find(user_realm) != std::string::npos;
|
||||
}
|
||||
|
||||
Poco::Net::SocketAddress RADIUS_proxy_server::DefaultRoute(radius_type rtype, const Poco::Net::SocketAddress &RequestedAddress, const RADIUS::RadiusPacket &P, bool &UseRADSEC) {
|
||||
Poco::Net::SocketAddress
|
||||
RADIUS_proxy_server::DefaultRoute(radius_type rtype,
|
||||
const Poco::Net::SocketAddress &RequestedAddress,
|
||||
const RADIUS::RadiusPacket &P, bool &UseRADSEC) {
|
||||
bool IsV4 = RequestedAddress.family() == Poco::Net::SocketAddress::IPv4;
|
||||
|
||||
// find the realm...
|
||||
@@ -493,7 +557,8 @@ namespace OpenWifi {
|
||||
|
||||
if (DefaultIsRADSEC_) {
|
||||
UseRADSEC = true;
|
||||
return (IsV4 ? Pools_[DefaultPoolIndex_].AuthV4[0].Addr : Pools_[DefaultPoolIndex_].AuthV6[0].Addr );
|
||||
return (IsV4 ? Pools_[DefaultPoolIndex_].AuthV4[0].Addr
|
||||
: Pools_[DefaultPoolIndex_].AuthV6[0].Addr);
|
||||
}
|
||||
|
||||
switch (rtype) {
|
||||
@@ -516,7 +581,10 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
|
||||
Poco::Net::SocketAddress RADIUS_proxy_server::Route([[maybe_unused]] radius_type rtype, const Poco::Net::SocketAddress &RequestedAddress, const RADIUS::RadiusPacket &P, bool &UseRADSEC) {
|
||||
Poco::Net::SocketAddress
|
||||
RADIUS_proxy_server::Route([[maybe_unused]] radius_type rtype,
|
||||
const Poco::Net::SocketAddress &RequestedAddress,
|
||||
const RADIUS::RadiusPacket &P, bool &UseRADSEC) {
|
||||
std::lock_guard G(Mutex_);
|
||||
|
||||
if (Pools_.empty()) {
|
||||
@@ -526,7 +594,10 @@ namespace OpenWifi {
|
||||
|
||||
bool IsV4 = RequestedAddress.family() == Poco::Net::SocketAddress::IPv4;
|
||||
bool useDefault;
|
||||
useDefault = IsV4 ? RequestedAddress.host() == Poco::Net::IPAddress::wildcard(Poco::Net::IPAddress::IPv4) : RequestedAddress.host() == Poco::Net::IPAddress::wildcard(Poco::Net::IPAddress::IPv6) ;
|
||||
useDefault = IsV4 ? RequestedAddress.host() ==
|
||||
Poco::Net::IPAddress::wildcard(Poco::Net::IPAddress::IPv4)
|
||||
: RequestedAddress.host() ==
|
||||
Poco::Net::IPAddress::wildcard(Poco::Net::IPAddress::IPv6);
|
||||
|
||||
if (useDefault) {
|
||||
return DefaultRoute(rtype, RequestedAddress, P, UseRADSEC);
|
||||
@@ -565,7 +636,9 @@ namespace OpenWifi {
|
||||
return RequestedAddress;
|
||||
}
|
||||
|
||||
Poco::Net::SocketAddress RADIUS_proxy_server::ChooseAddress(std::vector<Destination> &Pool, const Poco::Net::SocketAddress & OriginalAddress) {
|
||||
Poco::Net::SocketAddress
|
||||
RADIUS_proxy_server::ChooseAddress(std::vector<Destination> &Pool,
|
||||
const Poco::Net::SocketAddress &OriginalAddress) {
|
||||
|
||||
if (Pool.size() == 1) {
|
||||
return Pool[0].Addr;
|
||||
@@ -658,7 +731,6 @@ namespace OpenWifi {
|
||||
if (F.exists())
|
||||
F.remove();
|
||||
} catch (...) {
|
||||
|
||||
}
|
||||
Stop();
|
||||
ResetConfig();
|
||||
@@ -669,4 +741,4 @@ namespace OpenWifi {
|
||||
C = PoolList_;
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -15,10 +15,7 @@
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
enum class radius_type {
|
||||
auth, acct, coa
|
||||
};
|
||||
|
||||
enum class radius_type { auth, acct, coa };
|
||||
|
||||
class RADIUS_proxy_server : public SubSystemServer {
|
||||
public:
|
||||
@@ -32,11 +29,14 @@ namespace OpenWifi {
|
||||
inline bool Enabled() const { return Enabled_; }
|
||||
|
||||
void OnAccountingSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf);
|
||||
void OnAuthenticationSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf);
|
||||
void
|
||||
OnAuthenticationSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf);
|
||||
void OnCoASocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf);
|
||||
|
||||
void SendAccountingData(const std::string &serialNumber, const char *buffer, std::size_t size);
|
||||
void SendAuthenticationData(const std::string &serialNumber, const char *buffer, std::size_t size);
|
||||
void SendAccountingData(const std::string &serialNumber, const char *buffer,
|
||||
std::size_t size);
|
||||
void SendAuthenticationData(const std::string &serialNumber, const char *buffer,
|
||||
std::size_t size);
|
||||
void SendCoAData(const std::string &serialNumber, const char *buffer, std::size_t size);
|
||||
|
||||
void SetConfig(const GWObjects::RadiusProxyPoolList &C);
|
||||
@@ -61,9 +61,7 @@ namespace OpenWifi {
|
||||
std::vector<std::string> realms;
|
||||
};
|
||||
|
||||
inline bool Continue() const {
|
||||
return Running_ && Enabled_ && !Pools_.empty();
|
||||
}
|
||||
inline bool Continue() const { return Running_ && Enabled_ && !Pools_.empty(); }
|
||||
|
||||
private:
|
||||
std::unique_ptr<Poco::Net::DatagramSocket> AccountingSocketV4_;
|
||||
@@ -95,22 +93,27 @@ namespace OpenWifi {
|
||||
bool DefaultIsRADSEC_ = false;
|
||||
std::atomic_bool Running_ = false;
|
||||
|
||||
RADIUS_proxy_server() noexcept:
|
||||
SubSystemServer("RADIUS-PROXY", "RADIUS-PROXY", "radius.proxy")
|
||||
{
|
||||
}
|
||||
RADIUS_proxy_server() noexcept
|
||||
: SubSystemServer("RADIUS-PROXY", "RADIUS-PROXY", "radius.proxy") {}
|
||||
|
||||
static bool SendData( Poco::Net::DatagramSocket & Sock, const unsigned char *buf , std::size_t size, const Poco::Net::SocketAddress &S);
|
||||
static bool SendData(Poco::Net::DatagramSocket &Sock, const unsigned char *buf,
|
||||
std::size_t size, const Poco::Net::SocketAddress &S);
|
||||
|
||||
void ParseConfig();
|
||||
void ResetConfig();
|
||||
Poco::Net::SocketAddress Route(radius_type rtype, const Poco::Net::SocketAddress &A, const RADIUS::RadiusPacket &P, bool &UseRADSEC);
|
||||
void ParseServerList(const GWObjects::RadiusProxyServerConfig & Config, std::vector<Destination> &V4, std::vector<Destination> &V6, bool setAsDefault);
|
||||
static Poco::Net::SocketAddress ChooseAddress(std::vector<Destination> &Pool, const Poco::Net::SocketAddress & OriginalAddress);
|
||||
Poco::Net::SocketAddress DefaultRoute([[maybe_unused]] radius_type rtype, const Poco::Net::SocketAddress &RequestedAddress, const RADIUS::RadiusPacket &P, bool &UseRADSEC);
|
||||
Poco::Net::SocketAddress Route(radius_type rtype, const Poco::Net::SocketAddress &A,
|
||||
const RADIUS::RadiusPacket &P, bool &UseRADSEC);
|
||||
void ParseServerList(const GWObjects::RadiusProxyServerConfig &Config,
|
||||
std::vector<Destination> &V4, std::vector<Destination> &V6,
|
||||
bool setAsDefault);
|
||||
static Poco::Net::SocketAddress
|
||||
ChooseAddress(std::vector<Destination> &Pool,
|
||||
const Poco::Net::SocketAddress &OriginalAddress);
|
||||
Poco::Net::SocketAddress DefaultRoute([[maybe_unused]] radius_type rtype,
|
||||
const Poco::Net::SocketAddress &RequestedAddress,
|
||||
const RADIUS::RadiusPacket &P, bool &UseRADSEC);
|
||||
};
|
||||
|
||||
inline auto RADIUS_proxy_server() { return RADIUS_proxy_server::instance(); }
|
||||
|
||||
}
|
||||
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -4,42 +4,37 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
#include "RESTObjects/RESTAPI_GWobjects.h"
|
||||
|
||||
#include "Poco/Net/SocketReactor.h"
|
||||
#include "Poco/Net/SecureStreamSocket.h"
|
||||
#include "Poco/Net/Context.h"
|
||||
#include "Poco/Crypto/X509Certificate.h"
|
||||
#include "Poco/Net/Context.h"
|
||||
#include "Poco/Net/NetException.h"
|
||||
#include "Poco/Net/SecureStreamSocket.h"
|
||||
#include "Poco/Net/SocketReactor.h"
|
||||
#include "Poco/TemporaryFile.h"
|
||||
|
||||
#include "framework/MicroServiceFuncs.h"
|
||||
|
||||
#include "fmt/format.h"
|
||||
|
||||
#include "RADIUS_helpers.h"
|
||||
#include "AP_WS_Server.h"
|
||||
#include "RADIUS_helpers.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class RADSEC_server : public Poco::Runnable {
|
||||
public:
|
||||
RADSEC_server(Poco::Net::SocketReactor & R, GWObjects::RadiusProxyServerEntry E) :
|
||||
Reactor_(R),
|
||||
Server_(std::move(E)),
|
||||
Logger_(Poco::Logger::get(fmt::format("RADSEC: {}@{}:{}",
|
||||
Server_.name ,
|
||||
Server_.ip,
|
||||
Server_.port))) {
|
||||
RADSEC_server(Poco::Net::SocketReactor &R, GWObjects::RadiusProxyServerEntry E)
|
||||
: Reactor_(R), Server_(std::move(E)),
|
||||
Logger_(Poco::Logger::get(
|
||||
fmt::format("RADSEC: {}@{}:{}", Server_.name, Server_.ip, Server_.port))) {
|
||||
Start();
|
||||
}
|
||||
|
||||
~RADSEC_server() {
|
||||
Stop();
|
||||
}
|
||||
~RADSEC_server() { Stop(); }
|
||||
|
||||
inline int Start() {
|
||||
ReconnectThread_.start(*this);
|
||||
@@ -73,7 +68,8 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
|
||||
inline bool SendData(const std::string &serial_number, const unsigned char *buffer, int length) {
|
||||
inline bool SendData(const std::string &serial_number, const unsigned char *buffer,
|
||||
int length) {
|
||||
try {
|
||||
if (Connected_) {
|
||||
RADIUS::RadiusPacket P(buffer, length);
|
||||
@@ -98,7 +94,8 @@ namespace OpenWifi {
|
||||
return false;
|
||||
}
|
||||
|
||||
inline void onData([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf) {
|
||||
inline void
|
||||
onData([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) {
|
||||
unsigned char Buffer[4096];
|
||||
|
||||
try {
|
||||
@@ -139,7 +136,9 @@ namespace OpenWifi {
|
||||
poco_debug(Logger_, "CoA/DM packet dropped.");
|
||||
}
|
||||
} else {
|
||||
poco_warning(Logger_,fmt::format("Unknown packet: Type: {} (type={}) Length={}", P.PacketType(), P.PacketTypeInt(), P.BufferLen()));
|
||||
poco_warning(Logger_,
|
||||
fmt::format("Unknown packet: Type: {} (type={}) Length={}",
|
||||
P.PacketType(), P.PacketTypeInt(), P.BufferLen()));
|
||||
}
|
||||
} else {
|
||||
poco_warning(Logger_, "Invalid packet received. Resetting the connection.");
|
||||
@@ -154,12 +153,14 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
|
||||
inline void onError([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ErrorNotification>& pNf) {
|
||||
inline void
|
||||
onError([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf) {
|
||||
poco_warning(Logger_, "Socker error. Terminating connection.");
|
||||
Disconnect();
|
||||
}
|
||||
|
||||
inline void onShutdown([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification>& pNf) {
|
||||
inline void
|
||||
onShutdown([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf) {
|
||||
poco_warning(Logger_, "Socker socket shutdown. Terminating connection.");
|
||||
Disconnect();
|
||||
}
|
||||
@@ -176,14 +177,14 @@ namespace OpenWifi {
|
||||
DecodeFile(KeyFile_.path(), Server_.radsecKey);
|
||||
|
||||
for (auto &cert : Server_.radsecCacerts) {
|
||||
CaCertFiles_.emplace_back(std::make_unique<Poco::TemporaryFile>(MicroServiceDataDirectory()));
|
||||
CaCertFiles_.emplace_back(
|
||||
std::make_unique<Poco::TemporaryFile>(MicroServiceDataDirectory()));
|
||||
DecodeFile(CaCertFiles_[CaCertFiles_.size() - 1]->path(), cert);
|
||||
}
|
||||
|
||||
Poco::Net::Context::Ptr SecureContext = Poco::AutoPtr<Poco::Net::Context>(
|
||||
new Poco::Net::Context(Poco::Net::Context::TLS_CLIENT_USE,
|
||||
KeyFile_.path(),
|
||||
CertFile_.path(),""));
|
||||
Poco::Net::Context::Ptr SecureContext =
|
||||
Poco::AutoPtr<Poco::Net::Context>(new Poco::Net::Context(
|
||||
Poco::Net::Context::TLS_CLIENT_USE, KeyFile_.path(), CertFile_.path(), ""));
|
||||
if (Server_.allowSelfSigned) {
|
||||
SecureContext->setSecurityLevel(Poco::Net::Context::SECURITY_LEVEL_NONE);
|
||||
SecureContext->enableExtendedCertificateVerification(false);
|
||||
@@ -208,7 +209,8 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
if (Socket_->havePeerCertificate()) {
|
||||
Peer_Cert_ = std::make_unique<Poco::Crypto::X509Certificate>(Socket_->peerCertificate());
|
||||
Peer_Cert_ = std::make_unique<Poco::Crypto::X509Certificate>(
|
||||
Socket_->peerCertificate());
|
||||
}
|
||||
|
||||
Socket_->setBlocking(false);
|
||||
@@ -217,15 +219,13 @@ namespace OpenWifi {
|
||||
Socket_->setReceiveTimeout(Poco::Timespan(1 * 60 * 60, 0));
|
||||
|
||||
Reactor_.addEventHandler(
|
||||
*Socket_,
|
||||
Poco::NObserver<RADSEC_server, Poco::Net::ReadableNotification>(
|
||||
*Socket_, Poco::NObserver<RADSEC_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADSEC_server::onData));
|
||||
Reactor_.addEventHandler(
|
||||
*Socket_, Poco::NObserver<RADSEC_server, Poco::Net::ErrorNotification>(
|
||||
*this, &RADSEC_server::onError));
|
||||
Reactor_.addEventHandler(
|
||||
*Socket_,
|
||||
Poco::NObserver<RADSEC_server, Poco::Net::ShutdownNotification>(
|
||||
*Socket_, Poco::NObserver<RADSEC_server, Poco::Net::ShutdownNotification>(
|
||||
*this, &RADSEC_server::onShutdown));
|
||||
|
||||
Connected_ = true;
|
||||
@@ -264,7 +264,8 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
static void DecodeFile(const std::string &filename, const std::string &s) {
|
||||
std::ofstream sec_file(filename,std::ios_base::out|std::ios_base::trunc|std::ios_base::binary);
|
||||
std::ofstream sec_file(filename, std::ios_base::out | std::ios_base::trunc |
|
||||
std::ios_base::binary);
|
||||
std::stringstream is(s);
|
||||
Poco::Base64Decoder ds(is);
|
||||
Poco::StreamCopier::copyStream(ds, sec_file);
|
||||
@@ -300,4 +301,4 @@ namespace OpenWifi {
|
||||
volatile bool Connected_ = false;
|
||||
volatile bool TryAgain_ = true;
|
||||
};
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -4,17 +4,17 @@
|
||||
|
||||
#include "SDKcalls.h"
|
||||
|
||||
#include "framework/OpenAPIRequests.h"
|
||||
#include "framework/MicroServiceNames.h"
|
||||
#include "framework/OpenAPIRequests.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
bool SDKCalls::GetProvisioningConfiguration(const std::string &SerialNumber, std::string & Config) {
|
||||
bool SDKCalls::GetProvisioningConfiguration(const std::string &SerialNumber,
|
||||
std::string &Config) {
|
||||
|
||||
Types::StringPairVec QD{{"config", "true"}};
|
||||
OpenAPIRequestGet API(uSERVICE_PROVISIONING,
|
||||
"/api/v1/inventory/" + SerialNumber,
|
||||
QD,20000);
|
||||
OpenAPIRequestGet API(uSERVICE_PROVISIONING, "/api/v1/inventory/" + SerialNumber, QD,
|
||||
20000);
|
||||
|
||||
Poco::JSON::Object::Ptr ResponseObject;
|
||||
|
||||
@@ -26,4 +26,4 @@ namespace OpenWifi {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -9,8 +9,9 @@
|
||||
namespace OpenWifi {
|
||||
class SDKCalls {
|
||||
public:
|
||||
static bool GetProvisioningConfiguration(const std::string & SerialNumber, std::string & Config);
|
||||
static bool GetProvisioningConfiguration(const std::string &SerialNumber,
|
||||
std::string &Config);
|
||||
|
||||
private:
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -3,15 +3,16 @@
|
||||
//
|
||||
|
||||
#include "ScriptManager.h"
|
||||
#include "Poco/JSON/Parser.h"
|
||||
#include "framework/MicroServiceFuncs.h"
|
||||
#include <fstream>
|
||||
#include "Poco/JSON/Parser.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
int ScriptManager::Start() {
|
||||
poco_notice(Logger(), "Starting...");
|
||||
ScriptDir_ = MicroServiceConfigPath("script.manager.directory", MicroServiceDataDirectory() + "/included_scripts" );
|
||||
ScriptDir_ = MicroServiceConfigPath("script.manager.directory",
|
||||
MicroServiceDataDirectory() + "/included_scripts");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,14 +21,10 @@ namespace OpenWifi {
|
||||
private:
|
||||
std::string ScriptDir_;
|
||||
|
||||
explicit ScriptManager() noexcept:
|
||||
SubSystemServer("ScriptManager", "SCRIPT-MGR", "script.manager")
|
||||
{
|
||||
}
|
||||
|
||||
explicit ScriptManager() noexcept
|
||||
: SubSystemServer("ScriptManager", "SCRIPT-MGR", "script.manager") {}
|
||||
};
|
||||
|
||||
inline auto ScriptManager() { return ScriptManager::instance(); }
|
||||
|
||||
} // namespace OpenWifi
|
||||
|
||||
|
||||
@@ -66,7 +66,9 @@ namespace OpenWifi {
|
||||
return Res;
|
||||
}
|
||||
|
||||
void SerialNumberCache::ReturnNumbers(const std::string &S, uint HowMany, const std::vector<uint64_t> &SNArr, std::vector<uint64_t> &A, bool ReverseResult) {
|
||||
void SerialNumberCache::ReturnNumbers(const std::string &S, uint HowMany,
|
||||
const std::vector<uint64_t> &SNArr,
|
||||
std::vector<uint64_t> &A, bool ReverseResult) {
|
||||
std::lock_guard G(Mutex_);
|
||||
|
||||
if (S.length() == 12) {
|
||||
@@ -83,7 +85,8 @@ namespace OpenWifi {
|
||||
if (LB != SNArr.end()) {
|
||||
for (; LB != SNArr.end() && HowMany; ++LB, --HowMany) {
|
||||
if (ReverseResult) {
|
||||
const auto TSN = ReverseSerialNumber(Utils::IntToSerialNumber(Reverse(*LB)));
|
||||
const auto TSN =
|
||||
ReverseSerialNumber(Utils::IntToSerialNumber(Reverse(*LB)));
|
||||
if (S == TSN.substr(0, S.size())) {
|
||||
A.emplace_back(Reverse(*LB));
|
||||
} else {
|
||||
@@ -102,7 +105,8 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
|
||||
void SerialNumberCache::FindNumbers(const std::string &S, uint HowMany, std::vector<uint64_t> &A) {
|
||||
void SerialNumberCache::FindNumbers(const std::string &S, uint HowMany,
|
||||
std::vector<uint64_t> &A) {
|
||||
if (S.empty())
|
||||
return;
|
||||
|
||||
@@ -116,4 +120,4 @@ namespace OpenWifi {
|
||||
return ReturnNumbers(S, HowMany, SNs_, A, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -9,7 +9,6 @@
|
||||
namespace OpenWifi {
|
||||
class SerialNumberCache : public SubSystemServer {
|
||||
public:
|
||||
|
||||
static auto instance() {
|
||||
static auto instance_ = new SerialNumberCache;
|
||||
return instance_;
|
||||
@@ -35,15 +34,15 @@ namespace OpenWifi {
|
||||
std::vector<uint64_t> SNs_;
|
||||
std::vector<uint64_t> Reverse_SNs_;
|
||||
|
||||
void ReturnNumbers(const std::string &S, uint HowMany, const std::vector<uint64_t> & SNArr, std::vector<uint64_t> &A, bool ReverseResult);
|
||||
void ReturnNumbers(const std::string &S, uint HowMany, const std::vector<uint64_t> &SNArr,
|
||||
std::vector<uint64_t> &A, bool ReverseResult);
|
||||
|
||||
SerialNumberCache() noexcept:
|
||||
SubSystemServer("SerialNumberCache", "SNCACHE-SVR", "serialcache")
|
||||
{
|
||||
SerialNumberCache() noexcept
|
||||
: SubSystemServer("SerialNumberCache", "SNCACHE-SVR", "serialcache") {
|
||||
SNs_.reserve(2000);
|
||||
}
|
||||
};
|
||||
|
||||
inline auto SerialNumberCache() { return SerialNumberCache::instance(); }
|
||||
|
||||
} // namespace OpenWiFi
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
//
|
||||
// Created by stephane bourque on 2022-11-22.
|
||||
//
|
||||
|
||||
#include "SignatureMgr.h"
|
||||
|
||||
namespace OpenWifi {} // namespace OpenWifi
|
||||
@@ -7,18 +7,18 @@
|
||||
#include <fstream>
|
||||
#include <shared_mutex>
|
||||
|
||||
#include "framework/SubSystemServer.h"
|
||||
#include "framework/MicroServiceFuncs.h"
|
||||
#include "framework/SubSystemServer.h"
|
||||
#include "framework/utils.h"
|
||||
|
||||
#include "RESTObjects/RESTAPI_GWobjects.h"
|
||||
#include "Poco/DigestStream.h"
|
||||
#include "Poco/DigestEngine.h"
|
||||
#include "Poco/Crypto/RSADigestEngine.h"
|
||||
#include "Poco/StreamCopier.h"
|
||||
#include "Poco/DigestEngine.h"
|
||||
#include "Poco/DigestStream.h"
|
||||
#include "Poco/File.h"
|
||||
#include "Poco/StreamCopier.h"
|
||||
#include "Poco/StringTokenizer.h"
|
||||
#include "Poco/TemporaryFile.h"
|
||||
#include "RESTObjects/RESTAPI_GWobjects.h"
|
||||
#include "fmt/format.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
@@ -53,7 +53,8 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
}
|
||||
poco_information(Logger(),fmt::format("Found {} entries in signature cache.", SignatureCache_.size()));
|
||||
poco_information(Logger(), fmt::format("Found {} entries in signature cache.",
|
||||
SignatureCache_.size()));
|
||||
|
||||
// read all the key vendors.
|
||||
// signature.manager.0.key.public
|
||||
@@ -61,9 +62,12 @@ namespace OpenWifi {
|
||||
// signature.manager.0.vendor
|
||||
int i = 0;
|
||||
while (true) {
|
||||
auto Vendor = MicroServiceConfigGetString("signature.manager." + std::to_string(i) + ".vendor","");
|
||||
auto PrivateKey = MicroServiceConfigPath("signature.manager." + std::to_string(i) + ".key.private","");
|
||||
auto PublicKey = MicroServiceConfigPath("signature.manager." + std::to_string(i) + ".key.public","");
|
||||
auto Vendor = MicroServiceConfigGetString(
|
||||
"signature.manager." + std::to_string(i) + ".vendor", "");
|
||||
auto PrivateKey = MicroServiceConfigPath(
|
||||
"signature.manager." + std::to_string(i) + ".key.private", "");
|
||||
auto PublicKey = MicroServiceConfigPath(
|
||||
"signature.manager." + std::to_string(i) + ".key.public", "");
|
||||
if (Vendor.empty() || PrivateKey.empty() || PublicKey.empty()) {
|
||||
break;
|
||||
}
|
||||
@@ -85,7 +89,8 @@ namespace OpenWifi {
|
||||
poco_notice(Logger(), "Stopped...");
|
||||
}
|
||||
|
||||
inline std::string Sign(const GWObjects::DeviceRestrictions &Restrictions, const std::string &Data) const {
|
||||
inline std::string Sign(const GWObjects::DeviceRestrictions &Restrictions,
|
||||
const std::string &Data) const {
|
||||
std::shared_lock L(KeyMutex_);
|
||||
try {
|
||||
if (Restrictions.key_info.algo == "static") {
|
||||
@@ -93,7 +98,8 @@ namespace OpenWifi {
|
||||
}
|
||||
auto Vendor = Keys_.find(Restrictions.key_info.vendor);
|
||||
if (Vendor == Keys_.end()) {
|
||||
poco_error( Logger(), fmt::format("{}: vendor unknown.", Restrictions.key_info.vendor));
|
||||
poco_error(Logger(),
|
||||
fmt::format("{}: vendor unknown.", Restrictions.key_info.vendor));
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -112,7 +118,8 @@ namespace OpenWifi {
|
||||
return "";
|
||||
}
|
||||
|
||||
inline std::string Sign(const GWObjects::DeviceRestrictions &Restrictions, const Poco::URI &uri) {
|
||||
inline std::string Sign(const GWObjects::DeviceRestrictions &Restrictions,
|
||||
const Poco::URI &uri) {
|
||||
std::shared_lock L(KeyMutex_);
|
||||
try {
|
||||
if (Restrictions.key_info.algo == "static") {
|
||||
@@ -121,13 +128,15 @@ namespace OpenWifi {
|
||||
|
||||
auto Vendor = Keys_.find(Restrictions.key_info.vendor);
|
||||
if (Vendor == Keys_.end()) {
|
||||
poco_error( Logger(), fmt::format("{}: vendor unknown.", Restrictions.key_info.vendor));
|
||||
poco_error(Logger(),
|
||||
fmt::format("{}: vendor unknown.", Restrictions.key_info.vendor));
|
||||
return "";
|
||||
}
|
||||
|
||||
if (Restrictions.key_info.algo == "dgst-sha256") {
|
||||
auto FileHash =
|
||||
Utils::ComputeHash(Restrictions.key_info.vendor, Restrictions.key_info.algo, uri.getPathAndQuery());
|
||||
Utils::ComputeHash(Restrictions.key_info.vendor, Restrictions.key_info.algo,
|
||||
uri.getPathAndQuery());
|
||||
auto CacheEntry = SignatureCache_.find(FileHash);
|
||||
if (CacheEntry != end(SignatureCache_)) {
|
||||
return CacheEntry->second;
|
||||
@@ -141,7 +150,8 @@ namespace OpenWifi {
|
||||
std::ios_base::in | std::ios_base::binary);
|
||||
Poco::StreamCopier::copyStream(ifs, ofs);
|
||||
ofs.flush();
|
||||
auto Signature = Utils::base64encode((const unsigned char *)R.signature().data(),R.signature().size());
|
||||
auto Signature = Utils::base64encode(
|
||||
(const unsigned char *)R.signature().data(), R.signature().size());
|
||||
SignatureCache_[FileHash] = Signature;
|
||||
SaveCache();
|
||||
return Signature;
|
||||
@@ -172,5 +182,4 @@ namespace OpenWifi {
|
||||
|
||||
inline auto SignatureManager() { return SignatureManager::instance(); }
|
||||
|
||||
}
|
||||
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -8,19 +8,22 @@
|
||||
namespace OpenWifi::StateUtils {
|
||||
|
||||
static int ChannelToBand(uint64_t C) {
|
||||
if(C>=1 && C<=16) return 2;
|
||||
if (C >= 1 && C <= 16)
|
||||
return 2;
|
||||
return 5;
|
||||
}
|
||||
|
||||
static int BandToInt(const std::string &band) {
|
||||
if(band=="2G") return 2;
|
||||
if(band=="5G") return 5;
|
||||
if(band=="6G") return 6;
|
||||
if (band == "2G")
|
||||
return 2;
|
||||
if (band == "5G")
|
||||
return 5;
|
||||
if (band == "6G")
|
||||
return 6;
|
||||
return 2;
|
||||
}
|
||||
|
||||
bool ComputeAssociations(const Poco::JSON::Object::Ptr RawObject,
|
||||
uint64_t &Radios_2G,
|
||||
bool ComputeAssociations(const Poco::JSON::Object::Ptr RawObject, uint64_t &Radios_2G,
|
||||
uint64_t &Radios_5G, uint64_t &Radios_6G) {
|
||||
Radios_2G = 0;
|
||||
Radios_5G = 0;
|
||||
@@ -46,8 +49,7 @@ namespace OpenWifi::StateUtils {
|
||||
ChannelToBand(ChannelArray->getElement<uint64_t>(0));
|
||||
}
|
||||
} else {
|
||||
RadioPHYs[RadioObj->get("phy")] =
|
||||
ChannelToBand(RadioObj->get("channel"));
|
||||
RadioPHYs[RadioObj->get("phy")] = ChannelToBand(RadioObj->get("channel"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -71,10 +73,18 @@ namespace OpenWifi::StateUtils {
|
||||
}
|
||||
auto AssocA = SSID_info->getArray("associations");
|
||||
switch (Radio) {
|
||||
case 2: Radios_2G += AssocA->size(); break;
|
||||
case 5: Radios_5G += AssocA->size(); break;
|
||||
case 6: Radios_6G += AssocA->size(); break;
|
||||
default: Radios_2G += AssocA->size(); break;
|
||||
case 2:
|
||||
Radios_2G += AssocA->size();
|
||||
break;
|
||||
case 5:
|
||||
Radios_5G += AssocA->size();
|
||||
break;
|
||||
case 6:
|
||||
Radios_6G += AssocA->size();
|
||||
break;
|
||||
default:
|
||||
Radios_2G += AssocA->size();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -85,4 +95,4 @@ namespace OpenWifi::StateUtils {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} // namespace OpenWifi::StateUtils
|
||||
@@ -8,8 +8,8 @@
|
||||
#include "StorageService.h"
|
||||
|
||||
#include "framework/AppServiceRegistry.h"
|
||||
#include "framework/utils.h"
|
||||
#include "framework/MicroServiceFuncs.h"
|
||||
#include "framework/utils.h"
|
||||
|
||||
#include "fmt/format.h"
|
||||
|
||||
@@ -21,24 +21,19 @@ namespace OpenWifi {
|
||||
for (const auto &[DBName, Keep] : DBs_) {
|
||||
if (!Poco::icompare(DBName, "healthchecks")) {
|
||||
poco_information(Logger(), "Archiving HealthChecks...");
|
||||
StorageService()->RemoveHealthChecksRecordsOlderThan(
|
||||
now - (Keep * 24 * 60 * 60));
|
||||
StorageService()->RemoveHealthChecksRecordsOlderThan(now - (Keep * 24 * 60 * 60));
|
||||
} else if (!Poco::icompare(DBName, "statistics")) {
|
||||
poco_information(Logger(), "Archiving Statistics...");
|
||||
StorageService()->RemoveStatisticsRecordsOlderThan(
|
||||
now - (Keep * 24 * 60 * 60));
|
||||
StorageService()->RemoveStatisticsRecordsOlderThan(now - (Keep * 24 * 60 * 60));
|
||||
} else if (!Poco::icompare(DBName, "devicelogs")) {
|
||||
poco_information(Logger(), "Archiving Device Logs...");
|
||||
StorageService()->RemoveDeviceLogsRecordsOlderThan(
|
||||
now - (Keep * 24 * 60 * 60));
|
||||
StorageService()->RemoveDeviceLogsRecordsOlderThan(now - (Keep * 24 * 60 * 60));
|
||||
} else if (!Poco::icompare(DBName, "commandlist")) {
|
||||
poco_information(Logger(), "Archiving Command History...");
|
||||
StorageService()->RemoveCommandListRecordsOlderThan(
|
||||
now - (Keep * 24 * 60 * 60));
|
||||
StorageService()->RemoveCommandListRecordsOlderThan(now - (Keep * 24 * 60 * 60));
|
||||
} else if (!Poco::icompare(DBName, "fileuploads")) {
|
||||
poco_information(Logger(), "Archiving Upload files...");
|
||||
StorageService()->RemoveUploadedFilesRecordsOlderThan(
|
||||
now - (Keep * 24 * 60 * 60));
|
||||
StorageService()->RemoveUploadedFilesRecordsOlderThan(now - (Keep * 24 * 60 * 60));
|
||||
} else {
|
||||
poco_information(Logger(), fmt::format("Cannot archive DB '{}'", DBName));
|
||||
}
|
||||
@@ -54,7 +49,8 @@ namespace OpenWifi {
|
||||
if ((dt.hour() < (int)H) || (dt.hour() == (int)H && dt.minute() < (int)M)) {
|
||||
delta = scheduled.timestamp().epochTime() - dt.timestamp().epochTime();
|
||||
} else {
|
||||
delta = (24*60*60) - (dt.timestamp().epochTime() - scheduled.timestamp().epochTime());
|
||||
delta =
|
||||
(24 * 60 * 60) - (dt.timestamp().epochTime() - scheduled.timestamp().epochTime());
|
||||
}
|
||||
return delta;
|
||||
}
|
||||
@@ -68,7 +64,8 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
Archiver_ = std::make_unique<Archiver>(Logger());
|
||||
ArchiverCallback_ = std::make_unique<Poco::TimerCallback<Archiver>>(*Archiver_,&Archiver::onTimer);
|
||||
ArchiverCallback_ =
|
||||
std::make_unique<Poco::TimerCallback<Archiver>>(*Archiver_, &Archiver::onTimer);
|
||||
|
||||
auto Schedule = MicroServiceConfigGetString("archiver.schedule", "03:00");
|
||||
auto S = Poco::StringTokenizer(Schedule, ":");
|
||||
@@ -115,4 +112,4 @@ namespace OpenWifi {
|
||||
poco_information(Logger(), "Stopped...");
|
||||
}
|
||||
|
||||
};
|
||||
}; // namespace OpenWifi
|
||||
|
||||
@@ -13,13 +13,12 @@
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
static const std::list<std::string> AllInternalDBNames{"healthchecks", "statistics", "devicelogs" , "commandlist", "fileuploads"};
|
||||
static const std::list<std::string> AllInternalDBNames{
|
||||
"healthchecks", "statistics", "devicelogs", "commandlist", "fileuploads"};
|
||||
|
||||
class Archiver {
|
||||
public:
|
||||
|
||||
explicit Archiver(Poco::Logger &Logger):
|
||||
Logger_(Logger) {
|
||||
explicit Archiver(Poco::Logger &Logger) : Logger_(Logger) {
|
||||
for (const auto &db : AllInternalDBNames) {
|
||||
DBs_[db] = 7;
|
||||
}
|
||||
@@ -30,6 +29,7 @@ namespace OpenWifi {
|
||||
DBs_[dbname] = retain;
|
||||
}
|
||||
inline Poco::Logger &Logger() { return Logger_; }
|
||||
|
||||
private:
|
||||
Poco::Logger &Logger_;
|
||||
std::map<std::string, std::uint64_t> DBs_;
|
||||
@@ -53,12 +53,10 @@ namespace OpenWifi {
|
||||
std::unique_ptr<Archiver> Archiver_;
|
||||
std::unique_ptr<Poco::TimerCallback<Archiver>> ArchiverCallback_;
|
||||
|
||||
StorageArchiver() noexcept:
|
||||
SubSystemServer("StorageArchiver", "STORAGE-ARCHIVE", "archiver")
|
||||
{
|
||||
}
|
||||
StorageArchiver() noexcept
|
||||
: SubSystemServer("StorageArchiver", "STORAGE-ARCHIVE", "archiver") {}
|
||||
};
|
||||
|
||||
inline auto StorageArchiver() { return StorageArchiver::instance(); }
|
||||
|
||||
} // namespace
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -17,7 +17,8 @@ namespace OpenWifi {
|
||||
Create_Tables();
|
||||
InitializeBlackListCache();
|
||||
|
||||
ScriptDB_ = std::make_unique<OpenWifi::ScriptDB>("Scripts", "scr", dbType_,*Pool_, Logger());
|
||||
ScriptDB_ =
|
||||
std::make_unique<OpenWifi::ScriptDB>("Scripts", "scr", dbType_, *Pool_, Logger());
|
||||
ScriptDB_->Create();
|
||||
ScriptDB_->Initialize();
|
||||
|
||||
@@ -30,5 +31,5 @@ namespace OpenWifi {
|
||||
StorageClass::Stop();
|
||||
poco_notice(Logger(), "Stopped...");
|
||||
}
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
// namespace
|
||||
@@ -8,10 +8,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "framework/StorageClass.h"
|
||||
#include "RESTObjects//RESTAPI_GWobjects.h"
|
||||
#include "Poco/Net/IPAddress.h"
|
||||
#include "CentralConfig.h"
|
||||
#include "Poco/Net/IPAddress.h"
|
||||
#include "RESTObjects//RESTAPI_GWobjects.h"
|
||||
#include "framework/StorageClass.h"
|
||||
#include "storage/storage_scripts.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
@@ -19,7 +19,6 @@ namespace OpenWifi {
|
||||
class Storage : public StorageClass {
|
||||
|
||||
public:
|
||||
|
||||
enum class CommandExecutionType {
|
||||
COMMAND_PENDING,
|
||||
COMMAND_EXECUTED,
|
||||
@@ -34,12 +33,18 @@ namespace OpenWifi {
|
||||
|
||||
inline std::string to_string(const CommandExecutionType &C) {
|
||||
switch (C) {
|
||||
case CommandExecutionType::COMMAND_PENDING: return "pending";
|
||||
case CommandExecutionType::COMMAND_EXECUTED: return "executed";
|
||||
case CommandExecutionType::COMMAND_COMPLETED: return "completed";
|
||||
case CommandExecutionType::COMMAND_TIMEDOUT: return "timedout";
|
||||
case CommandExecutionType::COMMAND_FAILED: return "failed";
|
||||
case CommandExecutionType::COMMAND_EXPIRED: return "expired";
|
||||
case CommandExecutionType::COMMAND_PENDING:
|
||||
return "pending";
|
||||
case CommandExecutionType::COMMAND_EXECUTED:
|
||||
return "executed";
|
||||
case CommandExecutionType::COMMAND_COMPLETED:
|
||||
return "completed";
|
||||
case CommandExecutionType::COMMAND_TIMEDOUT:
|
||||
return "timedout";
|
||||
case CommandExecutionType::COMMAND_FAILED:
|
||||
return "failed";
|
||||
case CommandExecutionType::COMMAND_EXPIRED:
|
||||
return "expired";
|
||||
case CommandExecutionType::COMMAND_EXECUTING:
|
||||
default:
|
||||
return "executing";
|
||||
@@ -50,9 +55,11 @@ namespace OpenWifi {
|
||||
if (dbType_ == sqlite) {
|
||||
return " LIMIT " + std::to_string(From) + ", " + std::to_string(HowMany) + " ";
|
||||
} else if (dbType_ == pgsql) {
|
||||
return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From) + " ";
|
||||
return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From) +
|
||||
" ";
|
||||
} else if (dbType_ == mysql) {
|
||||
return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From) + " ";
|
||||
return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From) +
|
||||
" ";
|
||||
}
|
||||
return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From) + " ";
|
||||
}
|
||||
@@ -62,8 +69,7 @@ namespace OpenWifi {
|
||||
R.reserve(S.size() * 2 + 1);
|
||||
if (dbType_ == pgsql) {
|
||||
auto Idx = 1;
|
||||
for(auto const & i:S)
|
||||
{
|
||||
for (auto const &i : S) {
|
||||
if (i == '?') {
|
||||
R += '$';
|
||||
R.append(std::to_string(Idx++));
|
||||
@@ -86,77 +92,107 @@ namespace OpenWifi {
|
||||
|
||||
bool AddLog(const GWObjects::DeviceLog &Log);
|
||||
bool AddStatisticsData(const GWObjects::Statistics &Stats);
|
||||
bool GetStatisticsData(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate, uint64_t Offset, uint64_t HowMany,
|
||||
bool GetStatisticsData(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate,
|
||||
uint64_t Offset, uint64_t HowMany,
|
||||
std::vector<GWObjects::Statistics> &Stats);
|
||||
bool GetNumberOfStatisticsDataRecords(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate, std::uint64_t &Count);
|
||||
bool GetNumberOfStatisticsDataRecords(std::string &SerialNumber, uint64_t FromDate,
|
||||
uint64_t ToDate, std::uint64_t &Count);
|
||||
bool DeleteStatisticsData(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate);
|
||||
bool GetNewestStatisticsData(std::string &SerialNumber, uint64_t HowMany, std::vector<GWObjects::Statistics> &Stats);
|
||||
bool GetNewestStatisticsData(std::string &SerialNumber, uint64_t HowMany,
|
||||
std::vector<GWObjects::Statistics> &Stats);
|
||||
|
||||
bool AddHealthCheckData(const GWObjects::HealthCheck &Check);
|
||||
bool GetHealthCheckData(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate, uint64_t Offset, uint64_t HowMany,
|
||||
bool GetHealthCheckData(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate,
|
||||
uint64_t Offset, uint64_t HowMany,
|
||||
std::vector<GWObjects::HealthCheck> &Checks);
|
||||
bool DeleteHealthCheckData(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate);
|
||||
bool GetNewestHealthCheckData(std::string &SerialNumber, uint64_t HowMany,
|
||||
std::vector<GWObjects::HealthCheck> &Checks);
|
||||
|
||||
bool UpdateDeviceConfiguration(std::string &SerialNumber, std::string &Configuration, uint64_t & NewUUID );
|
||||
bool UpdateDeviceConfiguration(std::string &SerialNumber, std::string &Configuration,
|
||||
uint64_t &NewUUID);
|
||||
|
||||
bool CreateDevice(GWObjects::Device &);
|
||||
bool CreateDefaultDevice(std::string &SerialNumber, const Config::Capabilities &Caps, std::string & Firmware, const Poco::Net::IPAddress & IPAddress);
|
||||
bool CreateDefaultDevice(std::string &SerialNumber, const Config::Capabilities &Caps,
|
||||
std::string &Firmware, const Poco::Net::IPAddress &IPAddress);
|
||||
|
||||
bool GetDevice(std::string &SerialNumber, GWObjects::Device &);
|
||||
bool GetDevices(uint64_t From, uint64_t HowMany, std::vector<GWObjects::Device> &Devices, const std::string & orderBy="");
|
||||
// bool GetDevices(uint64_t From, uint64_t HowMany, const std::string & Select, std::vector<GWObjects::Device> &Devices, const std::string & orderBy="");
|
||||
bool GetDevices(uint64_t From, uint64_t HowMany, std::vector<GWObjects::Device> &Devices,
|
||||
const std::string &orderBy = "");
|
||||
// bool GetDevices(uint64_t From, uint64_t HowMany, const std::string & Select,
|
||||
//std::vector<GWObjects::Device> &Devices, const std::string & orderBy="");
|
||||
bool DeleteDevice(std::string &SerialNumber);
|
||||
bool UpdateDevice(GWObjects::Device &);
|
||||
bool DeviceExists(std::string &SerialNumber);
|
||||
bool SetConnectInfo(std::string &SerialNumber, std::string &Firmware);
|
||||
bool GetDeviceCount(uint64_t &Count);
|
||||
bool GetDeviceSerialNumbers(uint64_t From, uint64_t HowMany, std::vector<std::string> & SerialNumbers, const std::string & orderBy="");
|
||||
bool GetDeviceSerialNumbers(uint64_t From, uint64_t HowMany,
|
||||
std::vector<std::string> &SerialNumbers,
|
||||
const std::string &orderBy = "");
|
||||
bool GetDeviceFWUpdatePolicy(std::string &SerialNumber, std::string &Policy);
|
||||
bool SetDevicePassword(std::string &SerialNumber, std::string &Password);
|
||||
bool UpdateSerialNumberCache();
|
||||
static void GetDeviceDbFieldList(Types::StringVec &Fields);
|
||||
|
||||
bool ExistingConfiguration(std::string &SerialNumber, uint64_t CurrentConfig, std::string &NewConfig, uint64_t &);
|
||||
bool ExistingConfiguration(std::string &SerialNumber, uint64_t CurrentConfig,
|
||||
std::string &NewConfig, uint64_t &);
|
||||
|
||||
bool UpdateDeviceCapabilities(std::string &SerialNumber, const Config::Capabilities & Capabilities);
|
||||
bool UpdateDeviceCapabilities(std::string &SerialNumber,
|
||||
const Config::Capabilities &Capabilities);
|
||||
bool GetDeviceCapabilities(std::string &SerialNumber, GWObjects::Capabilities &);
|
||||
bool DeleteDeviceCapabilities(std::string &SerialNumber);
|
||||
bool CreateDeviceCapabilities(std::string & SerialNumber, const Config::Capabilities & Capabilities);
|
||||
bool CreateDeviceCapabilities(std::string &SerialNumber,
|
||||
const Config::Capabilities &Capabilities);
|
||||
bool InitCapabilitiesCache();
|
||||
|
||||
bool GetLogData(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate, uint64_t Offset, uint64_t HowMany,
|
||||
bool GetLogData(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate,
|
||||
uint64_t Offset, uint64_t HowMany, std::vector<GWObjects::DeviceLog> &Stats,
|
||||
uint64_t Type);
|
||||
bool DeleteLogData(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate,
|
||||
uint64_t Type);
|
||||
bool GetNewestLogData(std::string &SerialNumber, uint64_t HowMany,
|
||||
std::vector<GWObjects::DeviceLog> &Stats, uint64_t Type);
|
||||
bool DeleteLogData(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate, uint64_t Type);
|
||||
bool GetNewestLogData(std::string &SerialNumber, uint64_t HowMany, std::vector<GWObjects::DeviceLog> &Stats, uint64_t Type);
|
||||
|
||||
bool CreateDefaultConfiguration(std::string & name, GWObjects::DefaultConfiguration & DefConfig);
|
||||
bool CreateDefaultConfiguration(std::string &name,
|
||||
GWObjects::DefaultConfiguration &DefConfig);
|
||||
bool DeleteDefaultConfiguration(std::string &name);
|
||||
bool UpdateDefaultConfiguration(std::string & name, GWObjects::DefaultConfiguration & DefConfig);
|
||||
bool UpdateDefaultConfiguration(std::string &name,
|
||||
GWObjects::DefaultConfiguration &DefConfig);
|
||||
bool GetDefaultConfiguration(std::string &name, GWObjects::DefaultConfiguration &DefConfig);
|
||||
bool GetDefaultConfigurations(uint64_t From, uint64_t HowMany, std::vector<GWObjects::DefaultConfiguration> &Devices);
|
||||
bool FindDefaultConfigurationForModel(const std::string & Model, GWObjects::DefaultConfiguration & DefConfig );
|
||||
bool GetDefaultConfigurations(uint64_t From, uint64_t HowMany,
|
||||
std::vector<GWObjects::DefaultConfiguration> &Devices);
|
||||
bool FindDefaultConfigurationForModel(const std::string &Model,
|
||||
GWObjects::DefaultConfiguration &DefConfig);
|
||||
uint64_t GetDefaultConfigurationsCount();
|
||||
bool DefaultConfigurationAlreadyExists(std::string &Name);
|
||||
|
||||
bool AddCommand(std::string & SerialNumber, GWObjects::CommandDetails & Command,CommandExecutionType Type);
|
||||
bool GetCommands(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate, uint64_t Offset, uint64_t HowMany, std::vector<GWObjects::CommandDetails> & Commands);
|
||||
bool AddCommand(std::string &SerialNumber, GWObjects::CommandDetails &Command,
|
||||
CommandExecutionType Type);
|
||||
bool GetCommands(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate,
|
||||
uint64_t Offset, uint64_t HowMany,
|
||||
std::vector<GWObjects::CommandDetails> &Commands);
|
||||
bool DeleteCommands(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate);
|
||||
bool GetNonExecutedCommands( uint64_t Offset, uint64_t HowMany, std::vector<GWObjects::CommandDetails> & Commands );
|
||||
bool GetNonExecutedCommands(uint64_t Offset, uint64_t HowMany,
|
||||
std::vector<GWObjects::CommandDetails> &Commands);
|
||||
bool UpdateCommand(std::string &UUID, GWObjects::CommandDetails &Command);
|
||||
bool GetCommand(const std::string &UUID, GWObjects::CommandDetails &Command);
|
||||
bool DeleteCommand(std::string &UUID);
|
||||
bool GetReadyToExecuteCommands( uint64_t Offset, uint64_t HowMany, std::vector<GWObjects::CommandDetails> & Commands );
|
||||
bool GetReadyToExecuteCommands(uint64_t Offset, uint64_t HowMany,
|
||||
std::vector<GWObjects::CommandDetails> &Commands);
|
||||
bool CommandExecuted(std::string &UUID);
|
||||
bool SetCommandLastTry(std::string &UUID);
|
||||
bool CommandCompleted(std::string & UUID, Poco::JSON::Object::Ptr ReturnVars, const std::chrono::duration<double, std::milli> & execution_time, bool FullCommand);
|
||||
bool AttachFileDataToCommand(std::string & UUID, const std::stringstream &s, const std::string &Type);
|
||||
bool CommandCompleted(std::string &UUID, Poco::JSON::Object::Ptr ReturnVars,
|
||||
const std::chrono::duration<double, std::milli> &execution_time,
|
||||
bool FullCommand);
|
||||
bool AttachFileDataToCommand(std::string &UUID, const std::stringstream &s,
|
||||
const std::string &Type);
|
||||
bool CancelWaitFile(std::string &UUID, std::string &ErrorText);
|
||||
bool GetAttachedFileContent(std::string & UUID, const std::string & SerialNumber, std::string & FileContent, std::string &Type);
|
||||
bool GetAttachedFileContent(std::string &UUID, const std::string &SerialNumber,
|
||||
std::string &FileContent, std::string &Type);
|
||||
bool RemoveAttachedFile(std::string &UUID);
|
||||
bool SetCommandResult(std::string &UUID, std::string &Result);
|
||||
bool GetNewestCommands(std::string &SerialNumber, uint64_t HowMany, std::vector<GWObjects::CommandDetails> & Commands);
|
||||
bool GetNewestCommands(std::string &SerialNumber, uint64_t HowMany,
|
||||
std::vector<GWObjects::CommandDetails> &Commands);
|
||||
bool SetCommandExecuted(std::string &CommandUUID);
|
||||
bool SetCommandTimedOut(std::string &CommandUUID);
|
||||
bool SetCommandStatus(std::string &CommandUUID, std::uint64_t Error, const char *ErrorText);
|
||||
@@ -170,10 +206,12 @@ namespace OpenWifi {
|
||||
bool AddBlackListDevice(GWObjects::BlackListedDevice &Device);
|
||||
bool GetBlackListDevice(std::string &SerialNumber, GWObjects::BlackListedDevice &Device);
|
||||
bool DeleteBlackListDevice(std::string &SerialNumber);
|
||||
bool IsBlackListed(const std::string &SerialNumber, std::string &reason, std::string &author, std::uint64_t &created);
|
||||
bool IsBlackListed(const std::string &SerialNumber, std::string &reason,
|
||||
std::string &author, std::uint64_t &created);
|
||||
bool IsBlackListed(const std::string &SerialNumber);
|
||||
bool InitializeBlackListCache();
|
||||
bool GetBlackListDevices(uint64_t Offset, uint64_t HowMany, std::vector<GWObjects::BlackListedDevice> & Devices );
|
||||
bool GetBlackListDevices(uint64_t Offset, uint64_t HowMany,
|
||||
std::vector<GWObjects::BlackListedDevice> &Devices);
|
||||
bool UpdateBlackListDevice(std::string &SerialNumber, GWObjects::BlackListedDevice &Device);
|
||||
uint64_t GetBlackListDeviceCount();
|
||||
|
||||
@@ -201,12 +239,9 @@ namespace OpenWifi {
|
||||
void Stop() override;
|
||||
|
||||
private:
|
||||
|
||||
std::unique_ptr<OpenWifi::ScriptDB> ScriptDB_;
|
||||
|
||||
};
|
||||
|
||||
inline auto StorageService() { return Storage::instance(); }
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -2,26 +2,20 @@
|
||||
// Created by stephane bourque on 2022-02-03.
|
||||
//
|
||||
|
||||
#include "AP_WS_Server.h"
|
||||
#include "TelemetryClient.h"
|
||||
#include "TelemetryStream.h"
|
||||
#include "AP_WS_Server.h"
|
||||
#include "CommandManager.h"
|
||||
#include "TelemetryStream.h"
|
||||
|
||||
#include "Poco/Net/SSLException.h"
|
||||
#include "fmt/format.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
TelemetryClient::TelemetryClient(
|
||||
std::string UUID,
|
||||
uint64_t SerialNumber,
|
||||
TelemetryClient::TelemetryClient(std::string UUID, uint64_t SerialNumber,
|
||||
std::unique_ptr<Poco::Net::WebSocket> WSock,
|
||||
Poco::Net::SocketReactor& Reactor,
|
||||
Poco::Logger &Logger):
|
||||
UUID_(std::move(UUID)),
|
||||
SerialNumber_(SerialNumber),
|
||||
Reactor_(Reactor),
|
||||
Logger_(Logger),
|
||||
Poco::Net::SocketReactor &Reactor, Poco::Logger &Logger)
|
||||
: UUID_(std::move(UUID)), SerialNumber_(SerialNumber), Reactor_(Reactor), Logger_(Logger),
|
||||
WS_(std::move(WSock)) {
|
||||
CompleteStartup();
|
||||
}
|
||||
@@ -38,36 +32,38 @@ namespace OpenWifi {
|
||||
WS_->setKeepAlive(true);
|
||||
WS_->setMaxPayloadSize(2048);
|
||||
WS_->setBlocking(false);
|
||||
Reactor_.addEventHandler(
|
||||
*WS_, Poco::NObserver<TelemetryClient, Poco::Net::ReadableNotification>(
|
||||
Reactor_.addEventHandler(*WS_,
|
||||
Poco::NObserver<TelemetryClient, Poco::Net::ReadableNotification>(
|
||||
*this, &TelemetryClient::OnSocketReadable));
|
||||
Reactor_.addEventHandler(
|
||||
*WS_, Poco::NObserver<TelemetryClient, Poco::Net::ShutdownNotification>(
|
||||
Reactor_.addEventHandler(*WS_,
|
||||
Poco::NObserver<TelemetryClient, Poco::Net::ShutdownNotification>(
|
||||
*this, &TelemetryClient::OnSocketShutdown));
|
||||
Reactor_.addEventHandler(
|
||||
*WS_, Poco::NObserver<TelemetryClient, Poco::Net::ErrorNotification>(
|
||||
Reactor_.addEventHandler(*WS_,
|
||||
Poco::NObserver<TelemetryClient, Poco::Net::ErrorNotification>(
|
||||
*this, &TelemetryClient::OnSocketError));
|
||||
Registered_ = true;
|
||||
poco_information(Logger(),fmt::format("TELEMETRY-CONNECTION({}): Connection completed.", CId_));
|
||||
poco_information(Logger(),
|
||||
fmt::format("TELEMETRY-CONNECTION({}): Connection completed.", CId_));
|
||||
}
|
||||
|
||||
TelemetryClient::~TelemetryClient() {
|
||||
poco_information(Logger(),fmt::format("TELEMETRY-CONNECTION({}): Closing connection.", CId_));
|
||||
poco_information(Logger(),
|
||||
fmt::format("TELEMETRY-CONNECTION({}): Closing connection.", CId_));
|
||||
DeRegister();
|
||||
}
|
||||
|
||||
void TelemetryClient::DeRegister() {
|
||||
if (Registered_) {
|
||||
Registered_ = false;
|
||||
Reactor_.removeEventHandler(*WS_,
|
||||
Poco::NObserver<TelemetryClient,
|
||||
Poco::Net::ReadableNotification>(*this,&TelemetryClient::OnSocketReadable));
|
||||
Reactor_.removeEventHandler(*WS_,
|
||||
Poco::NObserver<TelemetryClient,
|
||||
Poco::Net::ShutdownNotification>(*this,&TelemetryClient::OnSocketShutdown));
|
||||
Reactor_.removeEventHandler(*WS_,
|
||||
Poco::NObserver<TelemetryClient,
|
||||
Poco::Net::ErrorNotification>(*this,&TelemetryClient::OnSocketError));
|
||||
Reactor_.removeEventHandler(
|
||||
*WS_, Poco::NObserver<TelemetryClient, Poco::Net::ReadableNotification>(
|
||||
*this, &TelemetryClient::OnSocketReadable));
|
||||
Reactor_.removeEventHandler(
|
||||
*WS_, Poco::NObserver<TelemetryClient, Poco::Net::ShutdownNotification>(
|
||||
*this, &TelemetryClient::OnSocketShutdown));
|
||||
Reactor_.removeEventHandler(
|
||||
*WS_, Poco::NObserver<TelemetryClient, Poco::Net::ErrorNotification>(
|
||||
*this, &TelemetryClient::OnSocketError));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,32 +80,36 @@ namespace OpenWifi {
|
||||
TelemetryStream()->DeRegisterClient(UUID_);
|
||||
}
|
||||
|
||||
void TelemetryClient::OnSocketShutdown([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification>& pNf) {
|
||||
poco_information(Logger(),fmt::format("TELEMETRY-SOCKET-SHUTDOWN({}): Orderly shutdown.", CId_));
|
||||
void TelemetryClient::OnSocketShutdown(
|
||||
[[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf) {
|
||||
poco_information(Logger(),
|
||||
fmt::format("TELEMETRY-SOCKET-SHUTDOWN({}): Orderly shutdown.", CId_));
|
||||
SendTelemetryShutdown();
|
||||
}
|
||||
|
||||
void TelemetryClient::OnSocketError([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ErrorNotification>& pNf) {
|
||||
void TelemetryClient::OnSocketError(
|
||||
[[maybe_unused]] const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf) {
|
||||
poco_information(Logger(), fmt::format("TELEMETRY-SOCKET-ERROR({}): Closing.", CId_));
|
||||
SendTelemetryShutdown();
|
||||
}
|
||||
|
||||
void TelemetryClient::OnSocketReadable([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf) {
|
||||
try
|
||||
{
|
||||
void TelemetryClient::OnSocketReadable(
|
||||
[[maybe_unused]] const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) {
|
||||
try {
|
||||
std::lock_guard Guard(Mutex_);
|
||||
return ProcessIncomingFrame();
|
||||
}
|
||||
catch (const Poco::Exception & E)
|
||||
{
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger().log(E);
|
||||
}
|
||||
catch (const std::exception & E) {
|
||||
} catch (const std::exception &E) {
|
||||
std::string W = E.what();
|
||||
poco_information(Logger(),fmt::format("TELEMETRY-std::exception caught: {}. Connection terminated with {}",W,CId_));
|
||||
}
|
||||
catch ( ... ) {
|
||||
poco_information(Logger(),fmt::format("TELEMETRY-Unknown exception for {}. Connection terminated.",CId_));
|
||||
poco_information(
|
||||
Logger(),
|
||||
fmt::format("TELEMETRY-std::exception caught: {}. Connection terminated with {}", W,
|
||||
CId_));
|
||||
} catch (...) {
|
||||
poco_information(
|
||||
Logger(),
|
||||
fmt::format("TELEMETRY-Unknown exception for {}. Connection terminated.", CId_));
|
||||
}
|
||||
SendTelemetryShutdown();
|
||||
}
|
||||
@@ -126,16 +126,21 @@ namespace OpenWifi {
|
||||
Op = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK;
|
||||
|
||||
if (IncomingSize == 0 && flags == 0 && Op == 0) {
|
||||
poco_information(Logger(),fmt::format("TELEMETRY-DISCONNECT({}): device has disconnected.", CId_));
|
||||
poco_information(
|
||||
Logger(),
|
||||
fmt::format("TELEMETRY-DISCONNECT({}): device has disconnected.", CId_));
|
||||
MustDisconnect = true;
|
||||
} else {
|
||||
if (Op == Poco::Net::WebSocket::FRAME_OP_PING) {
|
||||
Logger().debug(fmt::format("TELEMETRY-WS-PING({}): received. PONG sent back.", CId_));
|
||||
Logger().debug(
|
||||
fmt::format("TELEMETRY-WS-PING({}): received. PONG sent back.", CId_));
|
||||
WS_->sendFrame("", 0,
|
||||
(int)Poco::Net::WebSocket::FRAME_OP_PONG |
|
||||
(int)Poco::Net::WebSocket::FRAME_FLAG_FIN);
|
||||
} else if (Op == Poco::Net::WebSocket::FRAME_OP_CLOSE) {
|
||||
poco_information(Logger(),fmt::format("TELEMETRY-DISCONNECT({}): device wants to disconnect.", CId_));
|
||||
poco_information(
|
||||
Logger(),
|
||||
fmt::format("TELEMETRY-DISCONNECT({}): device wants to disconnect.", CId_));
|
||||
MustDisconnect = true;
|
||||
}
|
||||
}
|
||||
@@ -149,4 +154,4 @@ namespace OpenWifi {
|
||||
SendTelemetryShutdown();
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -4,25 +4,23 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
#include "Poco/AutoPtr.h"
|
||||
#include "Poco/Logger.h"
|
||||
#include "Poco/Net/SocketNotification.h"
|
||||
#include "Poco/Net/SocketReactor.h"
|
||||
#include "Poco/Net/WebSocket.h"
|
||||
#include "Poco/Net/SocketNotification.h"
|
||||
#include "Poco/Logger.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class TelemetryClient {
|
||||
static constexpr int BufSize = 64000;
|
||||
|
||||
public:
|
||||
TelemetryClient(
|
||||
std::string UUID,
|
||||
uint64_t SerialNumber,
|
||||
TelemetryClient(std::string UUID, uint64_t SerialNumber,
|
||||
std::unique_ptr<Poco::Net::WebSocket> WSock,
|
||||
Poco::Net::SocketReactor& Reactor,
|
||||
Poco::Logger &Logger);
|
||||
Poco::Net::SocketReactor &Reactor, Poco::Logger &Logger);
|
||||
~TelemetryClient();
|
||||
|
||||
void OnSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf);
|
||||
@@ -46,4 +44,4 @@ namespace OpenWifi {
|
||||
void CompleteStartup();
|
||||
void DeRegister();
|
||||
};
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -47,7 +47,8 @@ namespace OpenWifi {
|
||||
return (N->second.find(UUID) != N->second.end());
|
||||
}
|
||||
|
||||
bool TelemetryStream::CreateEndpoint(uint64_t SerialNumber, std::string &EndPoint, const std::string &UUID) {
|
||||
bool TelemetryStream::CreateEndpoint(uint64_t SerialNumber, std::string &EndPoint,
|
||||
const std::string &UUID) {
|
||||
std::lock_guard G(Mutex_);
|
||||
|
||||
Poco::URI Public(MicroServiceConfigGetString("openwifi.system.uri.public", ""));
|
||||
@@ -87,14 +88,26 @@ namespace OpenWifi {
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger().log(E);
|
||||
} catch (std::exception &E) {
|
||||
poco_warning(Logger(),fmt::format("Std:Ex Cannot send WS telemetry notification: {} for SerialNumber: {}", E.what(), Utils::IntToSerialNumber(Notification->SerialNumber_)));
|
||||
poco_warning(
|
||||
Logger(),
|
||||
fmt::format(
|
||||
"Std:Ex Cannot send WS telemetry notification: {} for "
|
||||
"SerialNumber: {}",
|
||||
E.what(),
|
||||
Utils::IntToSerialNumber(Notification->SerialNumber_)));
|
||||
}
|
||||
} else {
|
||||
poco_warning(Logger(),fmt::format("Cannot send WS telemetry notification for SerialNumber: {}", Utils::IntToSerialNumber(Notification->SerialNumber_)));
|
||||
poco_warning(Logger(),
|
||||
fmt::format("Cannot send WS telemetry notification "
|
||||
"for SerialNumber: {}",
|
||||
Utils::IntToSerialNumber(
|
||||
Notification->SerialNumber_)));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
poco_warning(Logger(),fmt::format("Cannot find serial: {}", Utils::IntToSerialNumber(Notification->SerialNumber_)));
|
||||
poco_warning(Logger(), fmt::format("Cannot find serial: {}",
|
||||
Utils::IntToSerialNumber(
|
||||
Notification->SerialNumber_)));
|
||||
}
|
||||
} break;
|
||||
case TelemetryNotification::NotificationType::unregister: {
|
||||
@@ -112,7 +125,8 @@ namespace OpenWifi {
|
||||
}
|
||||
Clients_.erase(client);
|
||||
} else {
|
||||
poco_warning(Logger(),fmt::format("Unknown connection: {}", Notification->Data_));
|
||||
poco_warning(Logger(),
|
||||
fmt::format("Unknown connection: {}", Notification->Data_));
|
||||
}
|
||||
} break;
|
||||
|
||||
@@ -125,7 +139,8 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
|
||||
bool TelemetryStream::NewClient(const std::string &UUID, uint64_t SerialNumber, std::unique_ptr<Poco::Net::WebSocket> Client) {
|
||||
bool TelemetryStream::NewClient(const std::string &UUID, uint64_t SerialNumber,
|
||||
std::unique_ptr<Poco::Net::WebSocket> Client) {
|
||||
std::lock_guard G(Mutex_);
|
||||
try {
|
||||
Clients_[UUID] = std::make_unique<TelemetryClient>(
|
||||
@@ -137,8 +152,12 @@ namespace OpenWifi {
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger().log(E);
|
||||
} catch (...) {
|
||||
poco_warning(Logger(),fmt::format("Could not create a telemetry client for session {} and serial number {}", UUID, SerialNumber));
|
||||
poco_warning(
|
||||
Logger(),
|
||||
fmt::format(
|
||||
"Could not create a telemetry client for session {} and serial number {}", UUID,
|
||||
SerialNumber));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -6,20 +6,20 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "Poco/Net/SocketReactor.h"
|
||||
#include "Poco/Net/ParallelSocketAcceptor.h"
|
||||
#include "Poco/Net/WebSocket.h"
|
||||
#include "Poco/Net/SecureStreamSocket.h"
|
||||
#include "Poco/Net/SecureStreamSocketImpl.h"
|
||||
#include "Poco/Net/HTTPRequestHandlerFactory.h"
|
||||
#include "Poco/Net/HTTPRequestHandler.h"
|
||||
#include "Poco/Net/HTTPRequestHandlerFactory.h"
|
||||
#include "Poco/Net/HTTPServer.h"
|
||||
#include "Poco/Net/HTTPServerRequest.h"
|
||||
#include "Poco/Net/HTTPServerRequestImpl.h"
|
||||
#include "Poco/Net/ParallelSocketAcceptor.h"
|
||||
#include "Poco/Net/SecureStreamSocket.h"
|
||||
#include "Poco/Net/SecureStreamSocketImpl.h"
|
||||
#include "Poco/Net/SocketReactor.h"
|
||||
#include "Poco/Net/WebSocket.h"
|
||||
#include "Poco/Notification.h"
|
||||
#include "Poco/NotificationQueue.h"
|
||||
#include "Poco/Timespan.h"
|
||||
#include "Poco/URI.h"
|
||||
#include "Poco/Net/HTTPServer.h"
|
||||
#include "Poco/NotificationQueue.h"
|
||||
#include "Poco/Notification.h"
|
||||
|
||||
#include "framework/SubSystemServer.h"
|
||||
|
||||
@@ -30,21 +30,13 @@ namespace OpenWifi {
|
||||
|
||||
class TelemetryNotification : public Poco::Notification {
|
||||
public:
|
||||
enum class NotificationType {
|
||||
data,
|
||||
unregister
|
||||
};
|
||||
enum class NotificationType { data, unregister };
|
||||
|
||||
explicit TelemetryNotification(std::uint64_t SerialNumber, const std::string &Payload) :
|
||||
Type_(NotificationType::data),
|
||||
SerialNumber_(SerialNumber),
|
||||
Data_(Payload) {
|
||||
}
|
||||
explicit TelemetryNotification(std::uint64_t SerialNumber, const std::string &Payload)
|
||||
: Type_(NotificationType::data), SerialNumber_(SerialNumber), Data_(Payload) {}
|
||||
|
||||
explicit TelemetryNotification(const std::string &UUID) :
|
||||
Type_(NotificationType::unregister),
|
||||
Data_(UUID) {
|
||||
}
|
||||
explicit TelemetryNotification(const std::string &UUID)
|
||||
: Type_(NotificationType::unregister), Data_(UUID) {}
|
||||
|
||||
NotificationType Type_;
|
||||
std::uint64_t SerialNumber_ = 0;
|
||||
@@ -53,7 +45,6 @@ namespace OpenWifi {
|
||||
|
||||
class TelemetryStream : public SubSystemServer, Poco::Runnable {
|
||||
public:
|
||||
|
||||
struct QueueUpdate {
|
||||
uint64_t SerialNumber;
|
||||
std::string Payload;
|
||||
@@ -79,8 +70,8 @@ namespace OpenWifi {
|
||||
MsgQueue_.enqueueNotification(new TelemetryNotification(UUID));
|
||||
}
|
||||
|
||||
bool NewClient(const std::string &UUID, uint64_t SerialNumber, std::unique_ptr<Poco::Net::WebSocket> Client);
|
||||
|
||||
bool NewClient(const std::string &UUID, uint64_t SerialNumber,
|
||||
std::unique_ptr<Poco::Net::WebSocket> Client);
|
||||
|
||||
Poco::Net::SocketReactor &NextReactor() { return Reactor_; }
|
||||
|
||||
@@ -94,11 +85,10 @@ namespace OpenWifi {
|
||||
|
||||
std::map<std::string, std::unique_ptr<TelemetryClient>> Clients_; // uuid -> client
|
||||
|
||||
TelemetryStream() noexcept:
|
||||
SubSystemServer("TelemetryServer", "TELEMETRY-SVR", "openwifi.telemetry") {
|
||||
}
|
||||
TelemetryStream() noexcept
|
||||
: SubSystemServer("TelemetryServer", "TELEMETRY-SVR", "openwifi.telemetry") {}
|
||||
};
|
||||
|
||||
inline auto TelemetryStream() { return TelemetryStream::instance(); }
|
||||
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -15,7 +15,6 @@ namespace OpenWifi::GWWebSocketNotifications {
|
||||
RESTAPI_utils::field_from_json(Obj, "serialNumber", serialNumber);
|
||||
return true;
|
||||
} catch (...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -33,7 +32,6 @@ namespace OpenWifi::GWWebSocketNotifications {
|
||||
RESTAPI_utils::field_from_json(Obj, "newUUID", newUUID);
|
||||
return true;
|
||||
} catch (...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -49,7 +47,6 @@ namespace OpenWifi::GWWebSocketNotifications {
|
||||
RESTAPI_utils::field_from_json(Obj, "newFirmware", newFirmware);
|
||||
return true;
|
||||
} catch (...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -64,10 +61,10 @@ namespace OpenWifi::GWWebSocketNotifications {
|
||||
try {
|
||||
RESTAPI_utils::field_from_json(Obj, "numberOfDevices", numberOfDevices);
|
||||
RESTAPI_utils::field_from_json(Obj, "averageConnectedTime", averageConnectedTime);
|
||||
RESTAPI_utils::field_from_json(Obj,"numberOfConnectingDevices", numberOfConnectingDevices);
|
||||
RESTAPI_utils::field_from_json(Obj, "numberOfConnectingDevices",
|
||||
numberOfConnectingDevices);
|
||||
return true;
|
||||
} catch (...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -146,15 +143,11 @@ namespace OpenWifi::GWWebSocketNotifications {
|
||||
|
||||
void Register() {
|
||||
static const UI_WebSocketClientServer::NotificationTypeIdVec Notifications = {
|
||||
{ 1000, "device_connections_statistics" },
|
||||
{ 2000, "device_configuration_upgrade" },
|
||||
{ 3000, "device_firmware_upgrade" },
|
||||
{ 4000, "device_connection" },
|
||||
{ 5000, "device_disconnection" },
|
||||
{ 6000, "device_statistics" }
|
||||
};
|
||||
{1000, "device_connections_statistics"}, {2000, "device_configuration_upgrade"},
|
||||
{3000, "device_firmware_upgrade"}, {4000, "device_connection"},
|
||||
{5000, "device_disconnection"}, {6000, "device_statistics"}};
|
||||
|
||||
UI_WebSocketClientServer()->RegisterNotifications(Notifications);
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace OpenWifi::GWWebSocketNotifications
|
||||
@@ -43,7 +43,8 @@ namespace OpenWifi::GWWebSocketNotifications {
|
||||
void Register();
|
||||
|
||||
typedef WebSocketNotification<SingleDevice> SingleDevice_t;
|
||||
typedef WebSocketNotification<SingleDeviceConfigurationChange> SingleDeviceConfigurationChange_t;
|
||||
typedef WebSocketNotification<SingleDeviceConfigurationChange>
|
||||
SingleDeviceConfigurationChange_t;
|
||||
typedef WebSocketNotification<SingleDeviceFirmwareChange> SingleDeviceFirmwareChange_t;
|
||||
typedef WebSocketNotification<NumberOfConnection> NumberOfConnection_t;
|
||||
|
||||
@@ -61,4 +62,4 @@ namespace OpenWifi::GWWebSocketNotifications {
|
||||
void DeviceDisconnected(const std::string &User, SingleDevice_t &N);
|
||||
void DeviceStatistics(const std::string &User, SingleDevice_t &N);
|
||||
|
||||
};
|
||||
}; // namespace OpenWifi::GWWebSocketNotifications
|
||||
@@ -7,8 +7,8 @@
|
||||
#include "Poco/Notification.h"
|
||||
#include "Poco/NotificationQueue.h"
|
||||
|
||||
#include "sdks/sdk_prov.h"
|
||||
#include "AP_WS_Server.h"
|
||||
#include "sdks/sdk_prov.h"
|
||||
|
||||
#include "framework/MicroServiceFuncs.h"
|
||||
#include "framework/SubSystemServer.h"
|
||||
@@ -18,12 +18,9 @@ namespace OpenWifi {
|
||||
|
||||
class VenueBroadcastNotification : public Poco::Notification {
|
||||
public:
|
||||
VenueBroadcastNotification(const std::string &SourceSerialNumber, const std::string &Data, uint64_t TimeStamp) :
|
||||
SourceSerialNumber_(SourceSerialNumber),
|
||||
Data_(Data),
|
||||
TimeStamp_(TimeStamp) {
|
||||
|
||||
}
|
||||
VenueBroadcastNotification(const std::string &SourceSerialNumber, const std::string &Data,
|
||||
uint64_t TimeStamp)
|
||||
: SourceSerialNumber_(SourceSerialNumber), Data_(Data), TimeStamp_(TimeStamp) {}
|
||||
std::string SourceSerialNumber_;
|
||||
std::string Data_;
|
||||
uint64_t TimeStamp_ = Utils::Now();
|
||||
@@ -58,17 +55,19 @@ namespace OpenWifi {
|
||||
poco_information(Logger(), "Reinitializing.");
|
||||
}
|
||||
|
||||
|
||||
struct VenueInfo {
|
||||
uint64_t timestamp = Utils::Now();
|
||||
Types::StringVec serialNumbers;
|
||||
};
|
||||
|
||||
inline bool FindSerialNumberList(const std::string &Source, OpenWifi::Types::StringVec & SerialNumbers) {
|
||||
inline bool FindSerialNumberList(const std::string &Source,
|
||||
OpenWifi::Types::StringVec &SerialNumbers) {
|
||||
// Can we find our serial number in any of the lists so far...
|
||||
for (const auto &venue : Venues_) {
|
||||
auto entry = std::find(venue.second.serialNumbers.begin(),venue.second.serialNumbers.end(),Source);
|
||||
if(entry!=venue.second.serialNumbers.end() && (Utils::Now()-venue.second.timestamp)<600) {
|
||||
auto entry = std::find(venue.second.serialNumbers.begin(),
|
||||
venue.second.serialNumbers.end(), Source);
|
||||
if (entry != venue.second.serialNumbers.end() &&
|
||||
(Utils::Now() - venue.second.timestamp) < 600) {
|
||||
SerialNumbers = venue.second.serialNumbers;
|
||||
auto entry2 = std::find(SerialNumbers.begin(), SerialNumbers.end(), Source);
|
||||
SerialNumbers.erase(entry2);
|
||||
@@ -79,7 +78,8 @@ namespace OpenWifi {
|
||||
// get the venue from Prov and the serial numbers.
|
||||
Types::UUID_t Venue;
|
||||
Types::StringVec TmpSerialNumbers;
|
||||
if(OpenWifi::SDK::Prov::GetSerialNumbersForVenueOfSerialNumber(Source,Venue,TmpSerialNumbers,Logger())) {
|
||||
if (OpenWifi::SDK::Prov::GetSerialNumbersForVenueOfSerialNumber(
|
||||
Source, Venue, TmpSerialNumbers, Logger())) {
|
||||
std::sort(TmpSerialNumbers.begin(), TmpSerialNumbers.end());
|
||||
VenueInfo V{.timestamp = Utils::Now(), .serialNumbers = TmpSerialNumbers};
|
||||
Venues_[Venue] = V;
|
||||
@@ -101,9 +101,11 @@ namespace OpenWifi {
|
||||
inline void run() final {
|
||||
Running_ = true;
|
||||
Utils::SetThreadName("venue-bcast");
|
||||
Poco::AutoPtr<Poco::Notification> NextNotification(BroadcastQueue_.waitDequeueNotification());
|
||||
Poco::AutoPtr<Poco::Notification> NextNotification(
|
||||
BroadcastQueue_.waitDequeueNotification());
|
||||
while (NextNotification && Running_) {
|
||||
auto Notification = dynamic_cast<VenueBroadcastNotification *>(NextNotification.get());
|
||||
auto Notification =
|
||||
dynamic_cast<VenueBroadcastNotification *>(NextNotification.get());
|
||||
if (Notification != nullptr) {
|
||||
Types::StringVec SerialNumbers;
|
||||
if (FindSerialNumberList(Notification->SourceSerialNumber_, SerialNumbers)) {
|
||||
@@ -127,11 +129,12 @@ namespace OpenWifi {
|
||||
Running_ = false;
|
||||
}
|
||||
|
||||
inline void Broadcast(const std::string &SourceSerial, const std::string &Data, uint64_t TimeStamp) {
|
||||
BroadcastQueue_.enqueueNotification(new VenueBroadcastNotification(SourceSerial,Data,TimeStamp));
|
||||
inline void Broadcast(const std::string &SourceSerial, const std::string &Data,
|
||||
uint64_t TimeStamp) {
|
||||
BroadcastQueue_.enqueueNotification(
|
||||
new VenueBroadcastNotification(SourceSerial, Data, TimeStamp));
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
std::atomic_bool Running_ = false;
|
||||
bool Enabled_ = false;
|
||||
@@ -140,11 +143,9 @@ namespace OpenWifi {
|
||||
|
||||
std::map<OpenWifi::Types::UUID_t, VenueInfo> Venues_;
|
||||
|
||||
VenueBroadcaster() noexcept:
|
||||
SubSystemServer("VenueBroadcaster", "VENUE-BCAST", "venue.broacast")
|
||||
{
|
||||
}
|
||||
VenueBroadcaster() noexcept
|
||||
: SubSystemServer("VenueBroadcaster", "VENUE-BCAST", "venue.broacast") {}
|
||||
};
|
||||
|
||||
inline auto VenueBroadcaster() { return VenueBroadcaster::instance(); }
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
Reference in New Issue
Block a user