mirror of
https://github.com/Telecominfraproject/wlan-cloud-ucentralgw.git
synced 2025-10-30 18:28:03 +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
|
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_telemetry.cpp
|
||||||
src/AP_WS_Process_venuebroadcast.cpp
|
src/AP_WS_Process_venuebroadcast.cpp
|
||||||
src/RADSEC_server.h
|
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)
|
if(NOT SMALL_BUILD)
|
||||||
|
|
||||||
|
|||||||
@@ -4,13 +4,13 @@
|
|||||||
|
|
||||||
#include "AP_WS_Connection.h"
|
#include "AP_WS_Connection.h"
|
||||||
|
|
||||||
#include "Poco/Net/SecureStreamSocketImpl.h"
|
#include "Poco/Base64Decoder.h"
|
||||||
#include "Poco/Net/HTTPServerResponseImpl.h"
|
#include "Poco/Net/Context.h"
|
||||||
#include "Poco/Net/HTTPServerRequestImpl.h"
|
#include "Poco/Net/HTTPServerRequestImpl.h"
|
||||||
|
#include "Poco/Net/HTTPServerResponseImpl.h"
|
||||||
#include "Poco/Net/NetException.h"
|
#include "Poco/Net/NetException.h"
|
||||||
#include "Poco/Net/SSLException.h"
|
#include "Poco/Net/SSLException.h"
|
||||||
#include "Poco/Net/Context.h"
|
#include "Poco/Net/SecureStreamSocketImpl.h"
|
||||||
#include "Poco/Base64Decoder.h"
|
|
||||||
#include "Poco/Net/WebSocketImpl.h"
|
#include "Poco/Net/WebSocketImpl.h"
|
||||||
#include "Poco/zlib.h"
|
#include "Poco/zlib.h"
|
||||||
|
|
||||||
@@ -21,37 +21,37 @@
|
|||||||
#include "StorageService.h"
|
#include "StorageService.h"
|
||||||
#include "TelemetryStream.h"
|
#include "TelemetryStream.h"
|
||||||
|
|
||||||
|
#include "GWKafkaEvents.h"
|
||||||
|
#include "UI_GW_WebSocketNotifications.h"
|
||||||
#include "framework/KafkaManager.h"
|
#include "framework/KafkaManager.h"
|
||||||
#include "framework/MicroServiceFuncs.h"
|
#include "framework/MicroServiceFuncs.h"
|
||||||
#include "framework/utils.h"
|
#include "framework/utils.h"
|
||||||
#include "UI_GW_WebSocketNotifications.h"
|
|
||||||
#include "GWKafkaEvents.h"
|
|
||||||
|
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
|
|
||||||
#include "framework/ow_constants.h"
|
#include "framework/ow_constants.h"
|
||||||
|
|
||||||
|
|
||||||
#include "RADIUS_proxy_server.h"
|
#include "RADIUS_proxy_server.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
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) {
|
void AP_WS_Connection::LogException(const Poco::Exception &E) {
|
||||||
poco_information(Logger_,fmt::format("EXCEPTION({}): {}", CId_, E.displayText()));
|
poco_information(Logger_, fmt::format("EXCEPTION({}): {}", CId_, E.displayText()));
|
||||||
}
|
}
|
||||||
|
|
||||||
AP_WS_Connection::AP_WS_Connection(Poco::Net::HTTPServerRequest &request,
|
AP_WS_Connection::AP_WS_Connection(Poco::Net::HTTPServerRequest &request,
|
||||||
Poco::Net::HTTPServerResponse &response,
|
Poco::Net::HTTPServerResponse &response,
|
||||||
uint64_t connection_id,
|
uint64_t connection_id, Poco::Logger &L,
|
||||||
Poco::Logger &L,
|
|
||||||
Poco::Net::SocketReactor &R)
|
Poco::Net::SocketReactor &R)
|
||||||
: Logger_(L) ,
|
: Logger_(L), Reactor_(R) {
|
||||||
Reactor_(R)
|
|
||||||
{
|
|
||||||
State_.sessionId = connection_id;
|
State_.sessionId = connection_id;
|
||||||
WS_ = std::make_unique<Poco::Net::WebSocket>(request,response);
|
WS_ = std::make_unique<Poco::Net::WebSocket>(request, response);
|
||||||
|
|
||||||
auto TS = Poco::Timespan(360, 0);
|
auto TS = Poco::Timespan(360, 0);
|
||||||
|
|
||||||
@@ -61,30 +61,31 @@ namespace OpenWifi {
|
|||||||
WS_->setKeepAlive(true);
|
WS_->setKeepAlive(true);
|
||||||
WS_->setBlocking(false);
|
WS_->setBlocking(false);
|
||||||
|
|
||||||
Reactor_.addEventHandler(
|
Reactor_.addEventHandler(*WS_,
|
||||||
*WS_, Poco::NObserver<AP_WS_Connection, Poco::Net::ReadableNotification>(
|
Poco::NObserver<AP_WS_Connection, Poco::Net::ReadableNotification>(
|
||||||
*this, &AP_WS_Connection::OnSocketReadable));
|
*this, &AP_WS_Connection::OnSocketReadable));
|
||||||
Reactor_.addEventHandler(
|
Reactor_.addEventHandler(*WS_,
|
||||||
*WS_, Poco::NObserver<AP_WS_Connection, Poco::Net::ShutdownNotification>(
|
Poco::NObserver<AP_WS_Connection, Poco::Net::ShutdownNotification>(
|
||||||
*this, &AP_WS_Connection::OnSocketShutdown));
|
*this, &AP_WS_Connection::OnSocketShutdown));
|
||||||
Reactor_.addEventHandler(
|
Reactor_.addEventHandler(*WS_,
|
||||||
*WS_, Poco::NObserver<AP_WS_Connection, Poco::Net::ErrorNotification>(
|
Poco::NObserver<AP_WS_Connection, Poco::Net::ErrorNotification>(
|
||||||
*this, &AP_WS_Connection::OnSocketError));
|
*this, &AP_WS_Connection::OnSocketError));
|
||||||
Registered_ = true;
|
Registered_ = true;
|
||||||
Valid_ = true;
|
Valid_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AP_WS_Connection::ValidatedDevice() {
|
bool AP_WS_Connection::ValidatedDevice() {
|
||||||
if(DeviceValidated_)
|
if (DeviceValidated_)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if(!Valid_)
|
if (!Valid_)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
std::lock_guard Lock(ConnectionMutex_);
|
std::lock_guard Lock(ConnectionMutex_);
|
||||||
try {
|
try {
|
||||||
auto SockImpl = dynamic_cast<Poco::Net::WebSocketImpl *>(WS_->impl());
|
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();
|
PeerAddress_ = SS->peerAddress().host();
|
||||||
CId_ = Utils::FormatIPv6(SS->peerAddress().toString());
|
CId_ = Utils::FormatIPv6(SS->peerAddress().toString());
|
||||||
@@ -92,16 +93,22 @@ namespace OpenWifi {
|
|||||||
State_.started = Utils::Now();
|
State_.started = Utils::Now();
|
||||||
|
|
||||||
if (!SS->secure()) {
|
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();
|
EndConnection();
|
||||||
return false;
|
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()) {
|
if (!SS->havePeerCertificate()) {
|
||||||
State_.VerifiedCertificate = GWObjects::NO_CERTIFICATE;
|
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();
|
EndConnection();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -109,8 +116,10 @@ namespace OpenWifi {
|
|||||||
Poco::Crypto::X509Certificate PeerCert(SS->peerCertificate());
|
Poco::Crypto::X509Certificate PeerCert(SS->peerCertificate());
|
||||||
if (!AP_WS_Server()->ValidateCertificate(CId_, PeerCert)) {
|
if (!AP_WS_Server()->ValidateCertificate(CId_, PeerCert)) {
|
||||||
State_.VerifiedCertificate = GWObjects::NO_CERTIFICATE;
|
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_,
|
||||||
CId_, State_.sessionId ));
|
fmt::format("TLS-CONNECTION({}): Session={} Device certificate is not "
|
||||||
|
"valid. Device is not allowed.",
|
||||||
|
CId_, State_.sessionId));
|
||||||
EndConnection();
|
EndConnection();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -118,13 +127,13 @@ namespace OpenWifi {
|
|||||||
CN_ = Poco::trim(Poco::toLower(PeerCert.commonName()));
|
CN_ = Poco::trim(Poco::toLower(PeerCert.commonName()));
|
||||||
State_.VerifiedCertificate = GWObjects::VALID_CERTIFICATE;
|
State_.VerifiedCertificate = GWObjects::VALID_CERTIFICATE;
|
||||||
poco_debug(Logger_,
|
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()) {
|
if (AP_WS_Server::IsSim(CN_) && !AP_WS_Server()->IsSimEnabled()) {
|
||||||
poco_warning(
|
poco_warning(Logger_, fmt::format("TLS-CONNECTION({}): Session={} Sim Device {} is "
|
||||||
Logger_,
|
"not allowed. Disconnecting.",
|
||||||
fmt::format("TLS-CONNECTION({}): Session={} Sim Device {} is not allowed. Disconnecting.",
|
CId_, State_.sessionId, CN_));
|
||||||
CId_, State_.sessionId , CN_));
|
|
||||||
EndConnection();
|
EndConnection();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -132,11 +141,12 @@ namespace OpenWifi {
|
|||||||
std::string reason, author;
|
std::string reason, author;
|
||||||
std::uint64_t created;
|
std::uint64_t created;
|
||||||
if (!CN_.empty() && StorageService()->IsBlackListed(CN_, reason, author, created)) {
|
if (!CN_.empty() && StorageService()->IsBlackListed(CN_, reason, author, created)) {
|
||||||
DeviceBlacklistedKafkaEvent KE(CN_,Utils::Now(),reason,author,created,CId_);
|
DeviceBlacklistedKafkaEvent KE(CN_, Utils::Now(), reason, author, created, CId_);
|
||||||
poco_warning(
|
poco_warning(
|
||||||
Logger_,
|
Logger_,
|
||||||
fmt::format("TLS-CONNECTION({}): Session={} Device {} is black listed. Disconnecting.",
|
fmt::format(
|
||||||
CId_, State_.sessionId , CN_));
|
"TLS-CONNECTION({}): Session={} Device {} is black listed. Disconnecting.",
|
||||||
|
CId_, State_.sessionId, CN_));
|
||||||
EndConnection();
|
EndConnection();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -145,48 +155,69 @@ namespace OpenWifi {
|
|||||||
SerialNumber_ = CN_;
|
SerialNumber_ = CN_;
|
||||||
SerialNumberInt_ = Utils::SerialNumberToInt(SerialNumber_);
|
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;
|
DeviceValidated_ = true;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
} catch (const Poco::Net::CertificateValidationException &E) {
|
} 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(
|
||||||
CId_, State_.sessionId ));
|
Logger_,
|
||||||
|
fmt::format(
|
||||||
|
"CONNECTION({}): Session:{} Poco::CertificateValidationException Certificate "
|
||||||
|
"Validation failed during connection. Device will have to retry.",
|
||||||
|
CId_, State_.sessionId));
|
||||||
Logger_.log(E);
|
Logger_.log(E);
|
||||||
} catch (const Poco::Net::WebSocketException &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_,
|
||||||
CId_, State_.sessionId ));
|
fmt::format("CONNECTION({}): Session:{} Poco::WebSocketException WebSocket "
|
||||||
|
"error during connection. Device will have to retry.",
|
||||||
|
CId_, State_.sessionId));
|
||||||
Logger_.log(E);
|
Logger_.log(E);
|
||||||
} catch (const Poco::Net::ConnectionAbortedException &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(
|
||||||
CId_, State_.sessionId ));
|
Logger_,
|
||||||
|
fmt::format("CONNECTION({}):Session:{} Poco::ConnectionAbortedException "
|
||||||
|
"Connection was aborted during connection. Device will have to retry.",
|
||||||
|
CId_, State_.sessionId));
|
||||||
Logger_.log(E);
|
Logger_.log(E);
|
||||||
} catch (const Poco::Net::ConnectionResetException &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(
|
||||||
CId_, State_.sessionId ));
|
Logger_,
|
||||||
|
fmt::format("CONNECTION({}): Session:{} Poco::ConnectionResetException Connection "
|
||||||
|
"was reset during connection. Device will have to retry.",
|
||||||
|
CId_, State_.sessionId));
|
||||||
Logger_.log(E);
|
Logger_.log(E);
|
||||||
} catch (const Poco::Net::InvalidCertificateException &E) {
|
} catch (const Poco::Net::InvalidCertificateException &E) {
|
||||||
poco_error(Logger_,fmt::format(
|
poco_error(Logger_,
|
||||||
"CONNECTION({}): Session:{} Poco::InvalidCertificateException Invalid certificate. Device will have to retry.",
|
fmt::format("CONNECTION({}): Session:{} Poco::InvalidCertificateException "
|
||||||
CId_, State_.sessionId ));
|
"Invalid certificate. Device will have to retry.",
|
||||||
|
CId_, State_.sessionId));
|
||||||
Logger_.log(E);
|
Logger_.log(E);
|
||||||
} catch (const Poco::Net::SSLException &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_,
|
||||||
CId_, State_.sessionId ));
|
fmt::format("CONNECTION({}): Session:{} Poco::SSLException SSL Exception "
|
||||||
|
"during connection. Device will have to retry.",
|
||||||
|
CId_, State_.sessionId));
|
||||||
Logger_.log(E);
|
Logger_.log(E);
|
||||||
} catch (const Poco::Exception &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 "
|
||||||
CId_, State_.sessionId ));
|
"during device connection. Device will have to retry.",
|
||||||
|
CId_, State_.sessionId));
|
||||||
Logger_.log(E);
|
Logger_.log(E);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
poco_error(Logger_,fmt::format("CONNECTION({}): Session:{} Exception caught during device connection. Device will have to retry. Unsecure connect denied.",
|
poco_error(
|
||||||
CId_, State_.sessionId ));
|
Logger_,
|
||||||
|
fmt::format("CONNECTION({}): Session:{} Exception caught during device connection. "
|
||||||
|
"Device will have to retry. Unsecure connect denied.",
|
||||||
|
CId_, State_.sessionId));
|
||||||
}
|
}
|
||||||
EndConnection();
|
EndConnection();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void NotifyKafkaDisconnect(const std::string & SerialNumber) {
|
static void NotifyKafkaDisconnect(const std::string &SerialNumber) {
|
||||||
try {
|
try {
|
||||||
Poco::JSON::Object Disconnect;
|
Poco::JSON::Object Disconnect;
|
||||||
Poco::JSON::Object Details;
|
Poco::JSON::Object Details;
|
||||||
@@ -202,13 +233,13 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
AP_WS_Connection::~AP_WS_Connection() {
|
AP_WS_Connection::~AP_WS_Connection() {
|
||||||
Valid_=false;
|
Valid_ = false;
|
||||||
EndConnection();
|
EndConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AP_WS_Connection::EndConnection() {
|
void AP_WS_Connection::EndConnection() {
|
||||||
Valid_=false;
|
Valid_ = false;
|
||||||
if(!Dead_.test_and_set()) {
|
if (!Dead_.test_and_set()) {
|
||||||
|
|
||||||
if (Registered_) {
|
if (Registered_) {
|
||||||
Registered_ = false;
|
Registered_ = false;
|
||||||
@@ -239,7 +270,7 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AP_WS_Connection::LookForUpgrade(const uint64_t UUID, uint64_t & UpgradedUUID) {
|
bool AP_WS_Connection::LookForUpgrade(const uint64_t UUID, uint64_t &UpgradedUUID) {
|
||||||
|
|
||||||
// A UUID of zero means ignore updates for that connection.
|
// A UUID of zero means ignore updates for that connection.
|
||||||
if (UUID == 0)
|
if (UUID == 0)
|
||||||
@@ -254,18 +285,19 @@ namespace OpenWifi {
|
|||||||
GWObjects::Device D;
|
GWObjects::Device D;
|
||||||
if (StorageService()->GetDevice(SerialNumber_, 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) {
|
if (D.UUID == UUID) {
|
||||||
UpgradedUUID = UUID;
|
UpgradedUUID = UUID;
|
||||||
ConfigurationCache().Add(SerialNumberInt_, UUID);
|
ConfigurationCache().Add(SerialNumberInt_, UUID);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(UUID>D.UUID) {
|
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
|
// so we have a problem, the device has a newer config than we have. So we need to
|
||||||
// is newer.
|
//make sure our config is newer.
|
||||||
Config::Config Cfg(D.Configuration);
|
Config::Config Cfg(D.Configuration);
|
||||||
D.UUID = UUID+2;
|
D.UUID = UUID + 2;
|
||||||
UpgradedUUID = D.UUID;
|
UpgradedUUID = D.UUID;
|
||||||
Cfg.SetUUID(D.UUID);
|
Cfg.SetUUID(D.UUID);
|
||||||
D.Configuration = Cfg.get();
|
D.Configuration = Cfg.get();
|
||||||
@@ -291,12 +323,16 @@ namespace OpenWifi {
|
|||||||
std::ostringstream O;
|
std::ostringstream O;
|
||||||
Poco::JSON::Stringifier::stringify(Params, O);
|
Poco::JSON::Stringifier::stringify(Params, O);
|
||||||
Cmd.Details = O.str();
|
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));
|
CId_, UUID, D.UUID));
|
||||||
bool Sent;
|
bool Sent;
|
||||||
|
|
||||||
StorageService()->AddCommand(SerialNumber_, Cmd, Storage::CommandExecutionType::COMMAND_EXECUTED);
|
StorageService()->AddCommand(SerialNumber_, Cmd,
|
||||||
CommandManager()->PostCommand(CommandManager()->Next_RPC_ID(), APCommands::to_apcommand(Cmd.Command.c_str()),SerialNumber_, Cmd.Command, Params, Cmd.UUID, Sent, false, false);
|
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;
|
GWWebSocketNotifications::SingleDeviceConfigurationChange_t Notification;
|
||||||
Notification.content.serialNumber = D.SerialNumber;
|
Notification.content.serialNumber = D.SerialNumber;
|
||||||
@@ -310,7 +346,8 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AP_WS_Connection::ProcessJSONRPCResult(Poco::JSON::Object::Ptr Doc) {
|
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);
|
CommandManager()->PostCommandResult(SerialNumber_, Doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,13 +355,15 @@ namespace OpenWifi {
|
|||||||
auto Method = Doc->get(uCentralProtocol::METHOD).toString();
|
auto Method = Doc->get(uCentralProtocol::METHOD).toString();
|
||||||
auto EventType = uCentralProtocol::Events::EventFromString(Method);
|
auto EventType = uCentralProtocol::Events::EventFromString(Method);
|
||||||
if (EventType == uCentralProtocol::Events::ET_UNKNOWN) {
|
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_++;
|
Errors_++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Doc->isObject(uCentralProtocol::PARAMS)) {
|
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_++;
|
Errors_++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -335,24 +374,29 @@ namespace OpenWifi {
|
|||||||
std::string UncompressedData;
|
std::string UncompressedData;
|
||||||
try {
|
try {
|
||||||
auto CompressedData = ParamsObj->get(uCentralProtocol::COMPRESS_64).toString();
|
auto CompressedData = ParamsObj->get(uCentralProtocol::COMPRESS_64).toString();
|
||||||
uint64_t compress_sz = 0 ;
|
uint64_t compress_sz = 0;
|
||||||
if(ParamsObj->has("compress_sz")) {
|
if (ParamsObj->has("compress_sz")) {
|
||||||
compress_sz = ParamsObj->get("compress_sz");
|
compress_sz = ParamsObj->get("compress_sz");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Utils::ExtractBase64CompressedData(CompressedData, UncompressedData, compress_sz)) {
|
if (Utils::ExtractBase64CompressedData(CompressedData, UncompressedData,
|
||||||
poco_trace(Logger_,fmt::format("EVENT({}): Found compressed payload expanded to '{}'.",
|
compress_sz)) {
|
||||||
|
poco_trace(Logger_,
|
||||||
|
fmt::format("EVENT({}): Found compressed payload expanded to '{}'.",
|
||||||
CId_, UncompressedData));
|
CId_, UncompressedData));
|
||||||
Poco::JSON::Parser Parser;
|
Poco::JSON::Parser Parser;
|
||||||
ParamsObj = Parser.parse(UncompressedData).extract<Poco::JSON::Object::Ptr>();
|
ParamsObj = Parser.parse(UncompressedData).extract<Poco::JSON::Object::Ptr>();
|
||||||
} else {
|
} 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()));
|
CId_, CompressedData.size()));
|
||||||
Errors_++;
|
Errors_++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (const Poco::Exception &E) {
|
} 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_));
|
CId_));
|
||||||
Logger_.log(E);
|
Logger_.log(E);
|
||||||
return;
|
return;
|
||||||
@@ -360,11 +404,14 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!ParamsObj->has(uCentralProtocol::SERIAL)) {
|
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;
|
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)) {
|
if (!Utils::ValidSerialNumber(Serial)) {
|
||||||
Poco::Exception E(
|
Poco::Exception E(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -377,7 +424,7 @@ namespace OpenWifi {
|
|||||||
std::string reason, author;
|
std::string reason, author;
|
||||||
std::uint64_t created;
|
std::uint64_t created;
|
||||||
if (StorageService()->IsBlackListed(Serial, reason, author, created)) {
|
if (StorageService()->IsBlackListed(Serial, reason, author, created)) {
|
||||||
DeviceBlacklistedKafkaEvent KE(CN_,Utils::Now(),reason,author,created,CId_);
|
DeviceBlacklistedKafkaEvent KE(CN_, Utils::Now(), reason, author, created, CId_);
|
||||||
Poco::Exception E(
|
Poco::Exception E(
|
||||||
fmt::format("BLACKLIST({}): device is blacklisted and not allowed to connect.",
|
fmt::format("BLACKLIST({}): device is blacklisted and not allowed to connect.",
|
||||||
Serial),
|
Serial),
|
||||||
@@ -445,13 +492,15 @@ namespace OpenWifi {
|
|||||||
// this will never be called but some compilers will complain if we do not have a case for
|
// this will never be called but some compilers will complain if we do not have a case for
|
||||||
// every single values of an enum
|
// every single values of an enum
|
||||||
case uCentralProtocol::Events::ET_UNKNOWN: {
|
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_++;
|
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_information(Logger_, fmt::format("TELEMETRY({}): Starting.", CId_));
|
||||||
Poco::JSON::Object StartMessage;
|
Poco::JSON::Object StartMessage;
|
||||||
StartMessage.set("jsonrpc", "2.0");
|
StartMessage.set("jsonrpc", "2.0");
|
||||||
@@ -460,12 +509,12 @@ namespace OpenWifi {
|
|||||||
Params.set("serial", SerialNumber_);
|
Params.set("serial", SerialNumber_);
|
||||||
Params.set("interval", (uint64_t)TelemetryInterval_);
|
Params.set("interval", (uint64_t)TelemetryInterval_);
|
||||||
Poco::JSON::Array Types;
|
Poco::JSON::Array Types;
|
||||||
if(TelemetryTypes.empty()) {
|
if (TelemetryTypes.empty()) {
|
||||||
Types.add("wifi-frames");
|
Types.add("wifi-frames");
|
||||||
Types.add("dhcp-snooping");
|
Types.add("dhcp-snooping");
|
||||||
Types.add("state");
|
Types.add("state");
|
||||||
} else {
|
} else {
|
||||||
for(const auto &type:TelemetryTypes)
|
for (const auto &type : TelemetryTypes)
|
||||||
Types.add(type);
|
Types.add(type);
|
||||||
}
|
}
|
||||||
Params.set(RESTAPI::Protocol::TYPES, Types);
|
Params.set(RESTAPI::Protocol::TYPES, Types);
|
||||||
@@ -500,13 +549,18 @@ namespace OpenWifi {
|
|||||||
State_.webSocketClients = TelemetryWebSocketRefCount_;
|
State_.webSocketClients = TelemetryWebSocketRefCount_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AP_WS_Connection::SetWebSocketTelemetryReporting(uint64_t RPCID, uint64_t Interval,
|
bool AP_WS_Connection::SetWebSocketTelemetryReporting(
|
||||||
uint64_t LifeTime, const std::vector<std::string> & TelemetryTypes) {
|
uint64_t RPCID, uint64_t Interval, uint64_t LifeTime,
|
||||||
|
const std::vector<std::string> &TelemetryTypes) {
|
||||||
std::unique_lock Lock(TelemetryMutex_);
|
std::unique_lock Lock(TelemetryMutex_);
|
||||||
TelemetryWebSocketRefCount_++;
|
TelemetryWebSocketRefCount_++;
|
||||||
TelemetryInterval_ = TelemetryInterval_ ? ( Interval< TelemetryInterval_ ? Interval : TelemetryInterval_) : Interval;
|
TelemetryInterval_ = TelemetryInterval_
|
||||||
|
? (Interval < TelemetryInterval_ ? Interval : TelemetryInterval_)
|
||||||
|
: Interval;
|
||||||
auto TelemetryWebSocketTimer = LifeTime + Utils::Now();
|
auto TelemetryWebSocketTimer = LifeTime + Utils::Now();
|
||||||
TelemetryWebSocketTimer_ = TelemetryWebSocketTimer > TelemetryWebSocketTimer_ ? TelemetryWebSocketTimer : TelemetryWebSocketTimer_;
|
TelemetryWebSocketTimer_ = TelemetryWebSocketTimer > TelemetryWebSocketTimer_
|
||||||
|
? TelemetryWebSocketTimer
|
||||||
|
: TelemetryWebSocketTimer_;
|
||||||
UpdateCounts();
|
UpdateCounts();
|
||||||
if (!TelemetryReporting_) {
|
if (!TelemetryReporting_) {
|
||||||
TelemetryReporting_ = true;
|
TelemetryReporting_ = true;
|
||||||
@@ -515,12 +569,18 @@ namespace OpenWifi {
|
|||||||
return true;
|
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_);
|
std::unique_lock Lock(TelemetryMutex_);
|
||||||
TelemetryKafkaRefCount_++;
|
TelemetryKafkaRefCount_++;
|
||||||
TelemetryInterval_ = TelemetryInterval_ ? ( Interval<TelemetryInterval_ ? Interval : TelemetryInterval_) : Interval;
|
TelemetryInterval_ = TelemetryInterval_
|
||||||
|
? (Interval < TelemetryInterval_ ? Interval : TelemetryInterval_)
|
||||||
|
: Interval;
|
||||||
auto TelemetryKafkaTimer = LifeTime + Utils::Now();
|
auto TelemetryKafkaTimer = LifeTime + Utils::Now();
|
||||||
TelemetryKafkaTimer_ = TelemetryKafkaTimer > TelemetryKafkaTimer_ ? TelemetryKafkaTimer : TelemetryKafkaTimer_;
|
TelemetryKafkaTimer_ =
|
||||||
|
TelemetryKafkaTimer > TelemetryKafkaTimer_ ? TelemetryKafkaTimer : TelemetryKafkaTimer_;
|
||||||
UpdateCounts();
|
UpdateCounts();
|
||||||
if (!TelemetryReporting_) {
|
if (!TelemetryReporting_) {
|
||||||
TelemetryReporting_ = true;
|
TelemetryReporting_ = true;
|
||||||
@@ -553,25 +613,28 @@ namespace OpenWifi {
|
|||||||
return true;
|
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_));
|
poco_trace(Logger_, fmt::format("SOCKET-SHUTDOWN({}): Closing.", CId_));
|
||||||
return EndConnection();
|
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_));
|
poco_trace(Logger_, fmt::format("SOCKET-ERROR({}): Closing.", CId_));
|
||||||
return EndConnection();
|
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_)
|
if (!Valid_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(!AP_WS_Server()->Running())
|
if (!AP_WS_Server()->Running())
|
||||||
return EndConnection();
|
return EndConnection();
|
||||||
|
|
||||||
if(!ValidatedDevice())
|
if (!ValidatedDevice())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -581,10 +644,13 @@ namespace OpenWifi {
|
|||||||
return EndConnection();
|
return EndConnection();
|
||||||
} catch (const std::exception &E) {
|
} catch (const std::exception &E) {
|
||||||
std::string W = E.what();
|
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();
|
return EndConnection();
|
||||||
} catch (...) {
|
} 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();
|
return EndConnection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -598,7 +664,9 @@ namespace OpenWifi {
|
|||||||
Op = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK;
|
Op = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK;
|
||||||
|
|
||||||
if (IncomingSize == 0 && flags == 0 && Op == 0) {
|
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();
|
return EndConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -623,7 +691,7 @@ namespace OpenWifi {
|
|||||||
PingDetails.set(uCentralProtocol::COMPATIBLE, Compatible_);
|
PingDetails.set(uCentralProtocol::COMPATIBLE, Compatible_);
|
||||||
PingDetails.set(uCentralProtocol::CONNECTIONIP, CId_);
|
PingDetails.set(uCentralProtocol::CONNECTIONIP, CId_);
|
||||||
PingDetails.set(uCentralProtocol::TIMESTAMP, Utils::Now());
|
PingDetails.set(uCentralProtocol::TIMESTAMP, Utils::Now());
|
||||||
PingDetails.set("locale", State_.locale );
|
PingDetails.set("locale", State_.locale);
|
||||||
PingObject.set(uCentralProtocol::PING, PingDetails);
|
PingObject.set(uCentralProtocol::PING, PingDetails);
|
||||||
Poco::JSON::Stringifier Stringify;
|
Poco::JSON::Stringifier Stringify;
|
||||||
std::ostringstream OS;
|
std::ostringstream OS;
|
||||||
@@ -639,8 +707,9 @@ namespace OpenWifi {
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Poco::Net::WebSocket::FRAME_OP_TEXT: {
|
case Poco::Net::WebSocket::FRAME_OP_TEXT: {
|
||||||
poco_trace(Logger_, fmt::format("FRAME({}): Frame received (length={}, flags={}). Msg={}", CId_,
|
poco_trace(Logger_,
|
||||||
IncomingSize, flags, IncomingFrame.begin()));
|
fmt::format("FRAME({}): Frame received (length={}, flags={}). Msg={}",
|
||||||
|
CId_, IncomingSize, flags, IncomingFrame.begin()));
|
||||||
|
|
||||||
Poco::JSON::Parser parser;
|
Poco::JSON::Parser parser;
|
||||||
auto ParsedMessage = parser.parse(IncomingFrame.begin());
|
auto ParsedMessage = parser.parse(IncomingFrame.begin());
|
||||||
@@ -652,10 +721,12 @@ namespace OpenWifi {
|
|||||||
ProcessJSONRPCEvent(IncomingJSON);
|
ProcessJSONRPCEvent(IncomingJSON);
|
||||||
} else if (IncomingJSON->has(uCentralProtocol::RESULT) &&
|
} else if (IncomingJSON->has(uCentralProtocol::RESULT) &&
|
||||||
IncomingJSON->has(uCentralProtocol::ID)) {
|
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);
|
ProcessJSONRPCResult(IncomingJSON);
|
||||||
} else {
|
} else {
|
||||||
poco_warning(Logger_,
|
poco_warning(
|
||||||
|
Logger_,
|
||||||
fmt::format("INVALID-PAYLOAD({}): Payload is not JSON-RPC 2.0: {}",
|
fmt::format("INVALID-PAYLOAD({}): Payload is not JSON-RPC 2.0: {}",
|
||||||
CId_, IncomingFrame.begin()));
|
CId_, IncomingFrame.begin()));
|
||||||
}
|
}
|
||||||
@@ -665,8 +736,10 @@ namespace OpenWifi {
|
|||||||
std::ostringstream iS;
|
std::ostringstream iS;
|
||||||
IncomingJSON->stringify(iS);
|
IncomingJSON->stringify(iS);
|
||||||
std::cout << iS.str() << std::endl;
|
std::cout << iS.str() << std::endl;
|
||||||
poco_warning(Logger_, fmt::format(
|
poco_warning(
|
||||||
"FRAME({}): illegal transaction header, missing 'jsonrpc'", CId_));
|
Logger_,
|
||||||
|
fmt::format("FRAME({}): illegal transaction header, missing 'jsonrpc'",
|
||||||
|
CId_));
|
||||||
Errors_++;
|
Errors_++;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -679,75 +752,79 @@ namespace OpenWifi {
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
poco_warning(Logger_, fmt::format("UNKNOWN({}): unknown WS Frame operation: {}", CId_,
|
poco_warning(Logger_, fmt::format("UNKNOWN({}): unknown WS Frame operation: {}",
|
||||||
std::to_string(Op)));
|
CId_, std::to_string(Op)));
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
} catch (const Poco::Net::ConnectionResetException &E) {
|
} catch (const Poco::Net::ConnectionResetException &E) {
|
||||||
poco_warning(Logger_, fmt::format("ConnectionResetException({}): Text:{} Payload:{} Session:{}",
|
poco_warning(Logger_,
|
||||||
CId_,
|
fmt::format("ConnectionResetException({}): Text:{} Payload:{} Session:{}",
|
||||||
E.displayText(),
|
CId_, E.displayText(),
|
||||||
IncomingFrame.begin()==nullptr ? "" : IncomingFrame.begin(),
|
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
||||||
State_.sessionId));
|
State_.sessionId));
|
||||||
return EndConnection();
|
return EndConnection();
|
||||||
} catch (const Poco::JSON::JSONException &E) {
|
} catch (const Poco::JSON::JSONException &E) {
|
||||||
poco_warning(Logger_, fmt::format("JSONException({}): Text:{} Payload:{} Session:{}",
|
poco_warning(Logger_,
|
||||||
CId_,
|
fmt::format("JSONException({}): Text:{} Payload:{} Session:{}", CId_,
|
||||||
E.displayText(),
|
E.displayText(),
|
||||||
IncomingFrame.begin()==nullptr ? "" : IncomingFrame.begin(),
|
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
||||||
State_.sessionId));
|
State_.sessionId));
|
||||||
return EndConnection();
|
return EndConnection();
|
||||||
} catch (const Poco::Net::WebSocketException &E) {
|
} catch (const Poco::Net::WebSocketException &E) {
|
||||||
poco_warning(Logger_, fmt::format("WebSocketException({}): Text:{} Payload:{} Session:{}",
|
poco_warning(Logger_,
|
||||||
CId_,
|
fmt::format("WebSocketException({}): Text:{} Payload:{} Session:{}", CId_,
|
||||||
E.displayText(),
|
E.displayText(),
|
||||||
IncomingFrame.begin()==nullptr ? "" : IncomingFrame.begin(),
|
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
||||||
State_.sessionId));
|
State_.sessionId));
|
||||||
return EndConnection();
|
return EndConnection();
|
||||||
} catch (const Poco::Net::SSLConnectionUnexpectedlyClosedException &E) {
|
} catch (const Poco::Net::SSLConnectionUnexpectedlyClosedException &E) {
|
||||||
poco_warning(Logger_, fmt::format("SSLConnectionUnexpectedlyClosedException({}): Text:{} Payload:{} Session:{}",
|
poco_warning(
|
||||||
CId_,
|
Logger_,
|
||||||
E.displayText(),
|
fmt::format(
|
||||||
IncomingFrame.begin()==nullptr ? "" : IncomingFrame.begin(),
|
"SSLConnectionUnexpectedlyClosedException({}): Text:{} Payload:{} Session:{}",
|
||||||
|
CId_, E.displayText(),
|
||||||
|
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
||||||
State_.sessionId));
|
State_.sessionId));
|
||||||
return EndConnection();
|
return EndConnection();
|
||||||
} catch (const Poco::Net::SSLException &E) {
|
} catch (const Poco::Net::SSLException &E) {
|
||||||
poco_warning(Logger_, fmt::format("SSLException({}): Text:{} Payload:{} Session:{}",
|
poco_warning(Logger_,
|
||||||
CId_,
|
fmt::format("SSLException({}): Text:{} Payload:{} Session:{}", CId_,
|
||||||
E.displayText(),
|
E.displayText(),
|
||||||
IncomingFrame.begin()==nullptr ? "" : IncomingFrame.begin(),
|
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
||||||
State_.sessionId));
|
State_.sessionId));
|
||||||
return EndConnection();
|
return EndConnection();
|
||||||
} catch (const Poco::Net::NetException &E) {
|
} catch (const Poco::Net::NetException &E) {
|
||||||
poco_warning(Logger_, fmt::format("NetException({}): Text:{} Payload:{} Session:{}",
|
poco_warning(Logger_,
|
||||||
CId_,
|
fmt::format("NetException({}): Text:{} Payload:{} Session:{}", CId_,
|
||||||
E.displayText(),
|
E.displayText(),
|
||||||
IncomingFrame.begin()==nullptr ? "" : IncomingFrame.begin(),
|
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
||||||
State_.sessionId));
|
State_.sessionId));
|
||||||
return EndConnection();
|
return EndConnection();
|
||||||
} catch (const Poco::IOException &E) {
|
} catch (const Poco::IOException &E) {
|
||||||
poco_warning(Logger_, fmt::format("IOException({}): Text:{} Payload:{} Session:{}",
|
poco_warning(Logger_,
|
||||||
CId_,
|
fmt::format("IOException({}): Text:{} Payload:{} Session:{}", CId_,
|
||||||
E.displayText(),
|
E.displayText(),
|
||||||
IncomingFrame.begin()==nullptr ? "" : IncomingFrame.begin(),
|
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
||||||
State_.sessionId));
|
State_.sessionId));
|
||||||
return EndConnection();
|
return EndConnection();
|
||||||
} catch (const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
poco_warning(Logger_, fmt::format("Exception({}): Text:{} Payload:{} Session:{}",
|
poco_warning(Logger_,
|
||||||
CId_,
|
fmt::format("Exception({}): Text:{} Payload:{} Session:{}", CId_,
|
||||||
E.displayText(),
|
E.displayText(),
|
||||||
IncomingFrame.begin()==nullptr ? "" : IncomingFrame.begin(),
|
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
||||||
State_.sessionId));
|
State_.sessionId));
|
||||||
return EndConnection();
|
return EndConnection();
|
||||||
} catch (const std::exception &E) {
|
} catch (const std::exception &E) {
|
||||||
poco_warning(Logger_, fmt::format("std::exception({}): Text:{} Payload:{} Session:{}",
|
poco_warning(Logger_,
|
||||||
CId_,
|
fmt::format("std::exception({}): Text:{} Payload:{} Session:{}", CId_,
|
||||||
E.what(),
|
E.what(),
|
||||||
IncomingFrame.begin()==nullptr ? "" : IncomingFrame.begin(),
|
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
||||||
State_.sessionId));
|
State_.sessionId));
|
||||||
return EndConnection();
|
return EndConnection();
|
||||||
} catch (...) {
|
} 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();
|
return EndConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -763,45 +840,47 @@ namespace OpenWifi {
|
|||||||
size_t BytesSent = WS_->sendFrame(Payload.c_str(), (int)Payload.size());
|
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.
|
* There is a possibility to actually try and send data but the device is no longer
|
||||||
* This code attempts to wait 5 seconds to see if the device is actually still listening.
|
* listening. This code attempts to wait 5 seconds to see if the device is actually
|
||||||
* if the data is not acked under 5 seconds, then we consider that the data never made it or the device is disconnected somehow.
|
* 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__)
|
#if defined(__APPLE__)
|
||||||
tcp_connection_info info;
|
tcp_connection_info info;
|
||||||
int timeout=4000;
|
int timeout = 4000;
|
||||||
auto expireAt = std::chrono::system_clock::now() + std::chrono::milliseconds(timeout);
|
auto expireAt = std::chrono::system_clock::now() + std::chrono::milliseconds(timeout);
|
||||||
do {
|
do {
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||||
socklen_t opt_len = sizeof(info);
|
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());
|
} while (!info.tcpi_tfo_syn_data_acked && expireAt > std::chrono::system_clock::now());
|
||||||
if(!info.tcpi_tfo_syn_data_acked)
|
if (!info.tcpi_tfo_syn_data_acked)
|
||||||
return false;
|
return false;
|
||||||
#else
|
#else
|
||||||
tcp_info info;
|
tcp_info info;
|
||||||
int timeout=4000;
|
int timeout = 4000;
|
||||||
auto expireAt = std::chrono::system_clock::now() + std::chrono::milliseconds(timeout);
|
auto expireAt = std::chrono::system_clock::now() + std::chrono::milliseconds(timeout);
|
||||||
do {
|
do {
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
||||||
socklen_t opt_len = sizeof(info);
|
socklen_t opt_len = sizeof(info);
|
||||||
getsockopt(WS_->impl()->sockfd(),SOL_TCP, TCP_INFO, (void *) &info, &opt_len);
|
getsockopt(WS_->impl()->sockfd(), SOL_TCP, TCP_INFO, (void *)&info, &opt_len);
|
||||||
} while (info.tcpi_unacked > 0 && expireAt > std::chrono::system_clock::now());
|
} while (info.tcpi_unacked > 0 && expireAt > std::chrono::system_clock::now());
|
||||||
|
|
||||||
if(info.tcpi_unacked>0) {
|
if (info.tcpi_unacked > 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
State_.TX += BytesSent;
|
State_.TX += BytesSent;
|
||||||
return BytesSent == Payload.size();
|
return BytesSent == Payload.size();
|
||||||
} catch(const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
Logger_.log(E);
|
Logger_.log(E);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Base64Encode(const unsigned char *buffer, std::size_t size) {
|
std::string Base64Encode(const unsigned char *buffer, std::size_t size) {
|
||||||
return Utils::base64encode(buffer,size);
|
return Utils::base64encode(buffer, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Base64Decode(const std::string &F) {
|
std::string Base64Decode(const std::string &F) {
|
||||||
@@ -812,30 +891,31 @@ namespace OpenWifi {
|
|||||||
return ofs.str();
|
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;
|
Poco::JSON::Object Answer;
|
||||||
Answer.set(uCentralProtocol::RADIUS,uCentralProtocol::RADIUSAUTH);
|
Answer.set(uCentralProtocol::RADIUS, uCentralProtocol::RADIUSAUTH);
|
||||||
Answer.set(uCentralProtocol::RADIUSDATA, Base64Encode(buffer,size));
|
Answer.set(uCentralProtocol::RADIUSDATA, Base64Encode(buffer, size));
|
||||||
|
|
||||||
std::ostringstream Payload;
|
std::ostringstream Payload;
|
||||||
Answer.stringify(Payload);
|
Answer.stringify(Payload);
|
||||||
return Send(Payload.str());
|
return Send(Payload.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AP_WS_Connection::SendRadiusAccountingData(const unsigned char * buffer, std::size_t size) {
|
bool AP_WS_Connection::SendRadiusAccountingData(const unsigned char *buffer, std::size_t size) {
|
||||||
Poco::JSON::Object Answer;
|
Poco::JSON::Object Answer;
|
||||||
Answer.set(uCentralProtocol::RADIUS,uCentralProtocol::RADIUSACCT);
|
Answer.set(uCentralProtocol::RADIUS, uCentralProtocol::RADIUSACCT);
|
||||||
Answer.set(uCentralProtocol::RADIUSDATA, Base64Encode(buffer,size));
|
Answer.set(uCentralProtocol::RADIUSDATA, Base64Encode(buffer, size));
|
||||||
|
|
||||||
std::ostringstream Payload;
|
std::ostringstream Payload;
|
||||||
Answer.stringify(Payload);
|
Answer.stringify(Payload);
|
||||||
return Send(Payload.str());
|
return Send(Payload.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AP_WS_Connection::SendRadiusCoAData(const unsigned char * buffer, std::size_t size) {
|
bool AP_WS_Connection::SendRadiusCoAData(const unsigned char *buffer, std::size_t size) {
|
||||||
Poco::JSON::Object Answer;
|
Poco::JSON::Object Answer;
|
||||||
Answer.set(uCentralProtocol::RADIUS,uCentralProtocol::RADIUSCOA);
|
Answer.set(uCentralProtocol::RADIUS, uCentralProtocol::RADIUSCOA);
|
||||||
Answer.set(uCentralProtocol::RADIUSDATA, Base64Encode(buffer,size));
|
Answer.set(uCentralProtocol::RADIUSDATA, Base64Encode(buffer, size));
|
||||||
|
|
||||||
std::ostringstream Payload;
|
std::ostringstream Payload;
|
||||||
Answer.stringify(Payload);
|
Answer.stringify(Payload);
|
||||||
@@ -843,21 +923,24 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AP_WS_Connection::ProcessIncomingRadiusData(const Poco::JSON::Object::Ptr &Doc) {
|
void AP_WS_Connection::ProcessIncomingRadiusData(const Poco::JSON::Object::Ptr &Doc) {
|
||||||
if( Doc->has(uCentralProtocol::RADIUSDATA)) {
|
if (Doc->has(uCentralProtocol::RADIUSDATA)) {
|
||||||
auto Type = Doc->get(uCentralProtocol::RADIUS).toString();
|
auto Type = Doc->get(uCentralProtocol::RADIUS).toString();
|
||||||
if(Type==uCentralProtocol::RADIUSACCT) {
|
if (Type == uCentralProtocol::RADIUSACCT) {
|
||||||
auto Data = Doc->get(uCentralProtocol::RADIUSDATA).toString();
|
auto Data = Doc->get(uCentralProtocol::RADIUSDATA).toString();
|
||||||
auto DecodedData = Base64Decode(Data);
|
auto DecodedData = Base64Decode(Data);
|
||||||
RADIUS_proxy_server()->SendAccountingData(SerialNumber_,DecodedData.c_str(),DecodedData.size());
|
RADIUS_proxy_server()->SendAccountingData(SerialNumber_, DecodedData.c_str(),
|
||||||
} else if(Type==uCentralProtocol::RADIUSAUTH) {
|
DecodedData.size());
|
||||||
|
} else if (Type == uCentralProtocol::RADIUSAUTH) {
|
||||||
auto Data = Doc->get(uCentralProtocol::RADIUSDATA).toString();
|
auto Data = Doc->get(uCentralProtocol::RADIUSDATA).toString();
|
||||||
auto DecodedData = Base64Decode(Data);
|
auto DecodedData = Base64Decode(Data);
|
||||||
RADIUS_proxy_server()->SendAuthenticationData(SerialNumber_,DecodedData.c_str(),DecodedData.size());
|
RADIUS_proxy_server()->SendAuthenticationData(SerialNumber_, DecodedData.c_str(),
|
||||||
} else if(Type==uCentralProtocol::RADIUSCOA) {
|
DecodedData.size());
|
||||||
|
} else if (Type == uCentralProtocol::RADIUSCOA) {
|
||||||
auto Data = Doc->get(uCentralProtocol::RADIUSDATA).toString();
|
auto Data = Doc->get(uCentralProtocol::RADIUSDATA).toString();
|
||||||
auto DecodedData = Base64Decode(Data);
|
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
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <shared_mutex>
|
#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/SocketReactor.h"
|
||||||
#include "Poco/Net/StreamSocket.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 "Poco/Net/WebSocket.h"
|
||||||
|
|
||||||
#include "RESTObjects/RESTAPI_GWobjects.h"
|
#include "RESTObjects/RESTAPI_GWobjects.h"
|
||||||
@@ -20,35 +20,40 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
class AP_WS_Connection {
|
class AP_WS_Connection {
|
||||||
static constexpr int BufSize = 256000;
|
static constexpr int BufSize = 256000;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit AP_WS_Connection( Poco::Net::HTTPServerRequest &request,
|
explicit AP_WS_Connection(Poco::Net::HTTPServerRequest &request,
|
||||||
Poco::Net::HTTPServerResponse &response,
|
Poco::Net::HTTPServerResponse &response, uint64_t connection_id,
|
||||||
uint64_t connection_id,
|
Poco::Logger &L, Poco::Net::SocketReactor &R);
|
||||||
Poco::Logger &L,
|
|
||||||
Poco::Net::SocketReactor &R);
|
|
||||||
~AP_WS_Connection();
|
~AP_WS_Connection();
|
||||||
|
|
||||||
void EndConnection();
|
void EndConnection();
|
||||||
void ProcessJSONRPCEvent(Poco::JSON::Object::Ptr & Doc);
|
void ProcessJSONRPCEvent(Poco::JSON::Object::Ptr &Doc);
|
||||||
void ProcessJSONRPCResult(Poco::JSON::Object::Ptr Doc);
|
void ProcessJSONRPCResult(Poco::JSON::Object::Ptr Doc);
|
||||||
void ProcessIncomingFrame();
|
void ProcessIncomingFrame();
|
||||||
void ProcessIncomingRadiusData(const Poco::JSON::Object::Ptr &Doc);
|
void ProcessIncomingRadiusData(const Poco::JSON::Object::Ptr &Doc);
|
||||||
|
|
||||||
[[nodiscard]] bool Send(const std::string &Payload);
|
[[nodiscard]] bool Send(const std::string &Payload);
|
||||||
|
|
||||||
bool SendRadiusAuthenticationData(const unsigned char * buffer, std::size_t size);
|
bool SendRadiusAuthenticationData(const unsigned char *buffer, std::size_t size);
|
||||||
bool SendRadiusAccountingData(const unsigned char * buffer, std::size_t size);
|
bool SendRadiusAccountingData(const unsigned char *buffer, std::size_t size);
|
||||||
bool SendRadiusCoAData(const unsigned char * buffer, std::size_t size);
|
bool SendRadiusCoAData(const unsigned char *buffer, std::size_t size);
|
||||||
|
|
||||||
void OnSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf);
|
void OnSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf);
|
||||||
void OnSocketShutdown(const Poco::AutoPtr<Poco::Net::ShutdownNotification>& pNf);
|
void OnSocketShutdown(const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf);
|
||||||
void OnSocketError(const Poco::AutoPtr<Poco::Net::ErrorNotification>& pNf);
|
void OnSocketError(const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf);
|
||||||
bool LookForUpgrade(uint64_t UUID, uint64_t & UpgradedUUID);
|
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);
|
void LogException(const Poco::Exception &E);
|
||||||
inline Poco::Logger & Logger() { return Logger_; }
|
inline Poco::Logger &Logger() { return Logger_; }
|
||||||
bool SetWebSocketTelemetryReporting(uint64_t RPCID, uint64_t interval, uint64_t TelemetryWebSocketTimer, const std::vector<std::string> & TelemetryTypes);
|
bool SetWebSocketTelemetryReporting(uint64_t RPCID, uint64_t interval,
|
||||||
bool SetKafkaTelemetryReporting(uint64_t RPCID, uint64_t interval, uint64_t TelemetryKafkaTimer, const std::vector<std::string> & TelemetryTypes);
|
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 StopWebSocketTelemetry(uint64_t RPCID);
|
||||||
bool StopKafkaTelemetry(uint64_t RPCID);
|
bool StopKafkaTelemetry(uint64_t RPCID);
|
||||||
|
|
||||||
@@ -77,7 +82,7 @@ namespace OpenWifi {
|
|||||||
State = State_;
|
State = State_;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void GetRestrictions(GWObjects::DeviceRestrictions & R) const {
|
inline void GetRestrictions(GWObjects::DeviceRestrictions &R) const {
|
||||||
std::shared_lock G(ConnectionMutex_);
|
std::shared_lock G(ConnectionMutex_);
|
||||||
R = Restrictions_;
|
R = Restrictions_;
|
||||||
}
|
}
|
||||||
@@ -99,11 +104,11 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
bool ValidatedDevice();
|
bool ValidatedDevice();
|
||||||
|
|
||||||
inline bool GetTelemetryParameters(bool & Reporting, uint64_t & Interval,
|
inline bool GetTelemetryParameters(bool &Reporting, uint64_t &Interval,
|
||||||
uint64_t & WebSocketTimer, uint64_t & KafkaTimer,
|
uint64_t &WebSocketTimer, uint64_t &KafkaTimer,
|
||||||
uint64_t &WebSocketCount, uint64_t & KafkaCount,
|
uint64_t &WebSocketCount, uint64_t &KafkaCount,
|
||||||
uint64_t &WebSocketPackets,
|
uint64_t &WebSocketPackets,
|
||||||
uint64_t &KafkaPackets ) const {
|
uint64_t &KafkaPackets) const {
|
||||||
Reporting = TelemetryReporting_;
|
Reporting = TelemetryReporting_;
|
||||||
WebSocketTimer = TelemetryWebSocketTimer_;
|
WebSocketTimer = TelemetryWebSocketTimer_;
|
||||||
KafkaTimer = TelemetryKafkaTimer_;
|
KafkaTimer = TelemetryKafkaTimer_;
|
||||||
@@ -129,36 +134,37 @@ namespace OpenWifi {
|
|||||||
Poco::Net::SocketReactor &Reactor_;
|
Poco::Net::SocketReactor &Reactor_;
|
||||||
std::unique_ptr<Poco::Net::WebSocket> WS_;
|
std::unique_ptr<Poco::Net::WebSocket> WS_;
|
||||||
std::string SerialNumber_;
|
std::string SerialNumber_;
|
||||||
uint64_t SerialNumberInt_=0;
|
uint64_t SerialNumberInt_ = 0;
|
||||||
std::string Compatible_;
|
std::string Compatible_;
|
||||||
std::atomic_bool Registered_ = false ;
|
std::atomic_bool Registered_ = false;
|
||||||
std::string CId_;
|
std::string CId_;
|
||||||
std::string CN_;
|
std::string CN_;
|
||||||
uint64_t Errors_=0;
|
uint64_t Errors_ = 0;
|
||||||
Poco::Net::IPAddress PeerAddress_;
|
Poco::Net::IPAddress PeerAddress_;
|
||||||
volatile bool TelemetryReporting_ = false;
|
volatile bool TelemetryReporting_ = false;
|
||||||
volatile uint64_t TelemetryWebSocketRefCount_ = 0;
|
volatile uint64_t TelemetryWebSocketRefCount_ = 0;
|
||||||
volatile uint64_t TelemetryKafkaRefCount_ = 0;
|
volatile uint64_t TelemetryKafkaRefCount_ = 0;
|
||||||
volatile uint64_t TelemetryWebSocketTimer_ = 0;
|
volatile uint64_t TelemetryWebSocketTimer_ = 0;
|
||||||
volatile uint64_t TelemetryKafkaTimer_ = 0 ;
|
volatile uint64_t TelemetryKafkaTimer_ = 0;
|
||||||
volatile uint64_t TelemetryInterval_ = 0;
|
volatile uint64_t TelemetryInterval_ = 0;
|
||||||
volatile uint64_t TelemetryWebSocketPackets_=0;
|
volatile uint64_t TelemetryWebSocketPackets_ = 0;
|
||||||
volatile uint64_t TelemetryKafkaPackets_=0;
|
volatile uint64_t TelemetryKafkaPackets_ = 0;
|
||||||
GWObjects::ConnectionState State_;
|
GWObjects::ConnectionState State_;
|
||||||
std::string RawLastStats_;
|
std::string RawLastStats_;
|
||||||
GWObjects::HealthCheck RawLastHealthcheck_;
|
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::chrono::duration<double, std::milli> ConnectionCompletionTime_{0.0};
|
||||||
std::atomic_flag Dead_=false;
|
std::atomic_flag Dead_ = false;
|
||||||
std::atomic_bool DeviceValidated_=false;
|
std::atomic_bool DeviceValidated_ = false;
|
||||||
std::atomic_bool Valid_=false;
|
std::atomic_bool Valid_ = false;
|
||||||
OpenWifi::GWObjects::DeviceRestrictions Restrictions_;
|
OpenWifi::GWObjects::DeviceRestrictions Restrictions_;
|
||||||
|
|
||||||
static inline std::atomic_uint64_t ConcurrentStartingDevices_=0;
|
static inline std::atomic_uint64_t ConcurrentStartingDevices_ = 0;
|
||||||
|
|
||||||
bool StartTelemetry(uint64_t RPCID, const std::vector<std::string> & TelemetryTypes);
|
bool StartTelemetry(uint64_t RPCID, const std::vector<std::string> &TelemetryTypes);
|
||||||
bool StopTelemetry(uint64_t RPCID);
|
bool StopTelemetry(uint64_t RPCID);
|
||||||
void UpdateCounts();
|
void UpdateCounts();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace OpenWifi
|
||||||
@@ -4,16 +4,16 @@
|
|||||||
#include "AP_WS_Connection.h"
|
#include "AP_WS_Connection.h"
|
||||||
#include "StorageService.h"
|
#include "StorageService.h"
|
||||||
|
|
||||||
#include "framework/ow_constants.h"
|
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
#include "framework/KafkaManager.h"
|
#include "framework/KafkaManager.h"
|
||||||
|
#include "framework/ow_constants.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
void AP_WS_Connection::Process_alarm(Poco::JSON::Object::Ptr ParamsObj) {
|
void AP_WS_Connection::Process_alarm(Poco::JSON::Object::Ptr ParamsObj) {
|
||||||
if (!State_.Connected) {
|
if (!State_.Connected) {
|
||||||
poco_warning(
|
poco_warning(Logger_,
|
||||||
Logger_,
|
fmt::format("INVALID-PROTOCOL({}): Device '{}' is not following protocol",
|
||||||
fmt::format("INVALID-PROTOCOL({}): Device '{}' is not following protocol", CId_, CN_));
|
CId_, CN_));
|
||||||
Errors_++;
|
Errors_++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -29,4 +29,4 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} // namespace OpenWifi
|
||||||
@@ -9,8 +9,9 @@
|
|||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
void AP_WS_Connection::Process_cfgpending(Poco::JSON::Object::Ptr ParamsObj) {
|
void AP_WS_Connection::Process_cfgpending(Poco::JSON::Object::Ptr ParamsObj) {
|
||||||
if (!State_.Connected) {
|
if (!State_.Connected) {
|
||||||
poco_warning(Logger_, fmt::format(
|
poco_warning(Logger_,
|
||||||
"INVALID-PROTOCOL({}): Device '{}' is not following protocol", CId_, CN_));
|
fmt::format("INVALID-PROTOCOL({}): Device '{}' is not following protocol",
|
||||||
|
CId_, CN_));
|
||||||
Errors_++;
|
Errors_++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -18,9 +19,10 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
[[maybe_unused]] uint64_t UUID = ParamsObj->get(uCentralProtocol::UUID);
|
[[maybe_unused]] uint64_t UUID = ParamsObj->get(uCentralProtocol::UUID);
|
||||||
[[maybe_unused]] uint64_t Active = ParamsObj->get(uCentralProtocol::ACTIVE);
|
[[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 {
|
} else {
|
||||||
poco_warning(Logger_, fmt::format("CFG-PENDING({}): Missing some parameters", CId_));
|
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_Connection.h"
|
||||||
#include "AP_WS_Server.h"
|
#include "AP_WS_Server.h"
|
||||||
#include "StorageService.h"
|
|
||||||
#include "FindCountry.h"
|
|
||||||
#include "Daemon.h"
|
|
||||||
#include "CentralConfig.h"
|
#include "CentralConfig.h"
|
||||||
|
#include "Daemon.h"
|
||||||
|
#include "FindCountry.h"
|
||||||
|
#include "StorageService.h"
|
||||||
|
|
||||||
#include "CommandManager.h"
|
#include "CommandManager.h"
|
||||||
|
|
||||||
@@ -19,13 +19,15 @@
|
|||||||
|
|
||||||
namespace OpenWifi {
|
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,
|
||||||
if(KafkaManager()->Enabled()) {
|
const std::string &OldFirmware,
|
||||||
|
const std::string &NewFirmware) {
|
||||||
|
if (KafkaManager()->Enabled()) {
|
||||||
Poco::JSON::Object EventDetails;
|
Poco::JSON::Object EventDetails;
|
||||||
EventDetails.set("oldFirmware", OldFirmware);
|
EventDetails.set("oldFirmware", OldFirmware);
|
||||||
EventDetails.set("newFirmware",NewFirmware);
|
EventDetails.set("newFirmware", NewFirmware);
|
||||||
Poco::JSON::Object Event;
|
Poco::JSON::Object Event;
|
||||||
Event.set("type","device.firmware_change");
|
Event.set("type", "device.firmware_change");
|
||||||
Event.set("timestamp", Utils::Now());
|
Event.set("timestamp", Utils::Now());
|
||||||
Event.set("payload", EventDetails);
|
Event.set("payload", EventDetails);
|
||||||
std::ostringstream OS;
|
std::ostringstream OS;
|
||||||
@@ -34,9 +36,9 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AP_WS_Connection::Process_connect(Poco::JSON::Object::Ptr ParamsObj, const std::string &Serial) {
|
void AP_WS_Connection::Process_connect(Poco::JSON::Object::Ptr ParamsObj,
|
||||||
if (ParamsObj->has(uCentralProtocol::UUID) &&
|
const std::string &Serial) {
|
||||||
ParamsObj->has(uCentralProtocol::FIRMWARE) &&
|
if (ParamsObj->has(uCentralProtocol::UUID) && ParamsObj->has(uCentralProtocol::FIRMWARE) &&
|
||||||
ParamsObj->has(uCentralProtocol::CAPABILITIES)) {
|
ParamsObj->has(uCentralProtocol::CAPABILITIES)) {
|
||||||
uint64_t UUID = ParamsObj->get(uCentralProtocol::UUID);
|
uint64_t UUID = ParamsObj->get(uCentralProtocol::UUID);
|
||||||
auto Firmware = ParamsObj->get(uCentralProtocol::FIRMWARE).toString();
|
auto Firmware = ParamsObj->get(uCentralProtocol::FIRMWARE).toString();
|
||||||
@@ -47,7 +49,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
CommandManager()->ClearQueue(SerialNumberInt_);
|
CommandManager()->ClearQueue(SerialNumberInt_);
|
||||||
|
|
||||||
AP_WS_Server()->SetSessionDetails(State_.sessionId,SerialNumberInt_);
|
AP_WS_Server()->SetSessionDetails(State_.sessionId, SerialNumberInt_);
|
||||||
|
|
||||||
std::lock_guard Lock(ConnectionMutex_);
|
std::lock_guard Lock(ConnectionMutex_);
|
||||||
Config::Capabilities Caps(Capabilities);
|
Config::Capabilities Caps(Capabilities);
|
||||||
@@ -61,12 +63,12 @@ namespace OpenWifi {
|
|||||||
CId_ = SerialNumber_ + "@" + CId_;
|
CId_ = SerialNumber_ + "@" + CId_;
|
||||||
|
|
||||||
auto IP = PeerAddress_.toString();
|
auto IP = PeerAddress_.toString();
|
||||||
if(IP.substr(0,7)=="::ffff:") {
|
if (IP.substr(0, 7) == "::ffff:") {
|
||||||
IP = IP.substr(7);
|
IP = IP.substr(7);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RestrictedDevice = false;
|
bool RestrictedDevice = false;
|
||||||
if(Capabilities->has("restrictions")){
|
if (Capabilities->has("restrictions")) {
|
||||||
RestrictedDevice = true;
|
RestrictedDevice = true;
|
||||||
Poco::JSON::Object::Ptr RestrictionObject = Capabilities->getObject("restrictions");
|
Poco::JSON::Object::Ptr RestrictionObject = Capabilities->getObject("restrictions");
|
||||||
Restrictions_.from_json(RestrictionObject);
|
Restrictions_.from_json(RestrictionObject);
|
||||||
@@ -74,15 +76,16 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
State_.locale = FindCountryFromIP()->Get(IP);
|
State_.locale = FindCountryFromIP()->Get(IP);
|
||||||
GWObjects::Device DeviceInfo;
|
GWObjects::Device DeviceInfo;
|
||||||
auto DeviceExists = StorageService()->GetDevice(SerialNumber_,DeviceInfo);
|
auto DeviceExists = StorageService()->GetDevice(SerialNumber_, DeviceInfo);
|
||||||
if (Daemon()->AutoProvisioning() && !DeviceExists) {
|
if (Daemon()->AutoProvisioning() && !DeviceExists) {
|
||||||
StorageService()->CreateDefaultDevice(SerialNumber_, Caps, Firmware, PeerAddress_);
|
StorageService()->CreateDefaultDevice(SerialNumber_, Caps, Firmware, PeerAddress_);
|
||||||
} else if (DeviceExists) {
|
} else if (DeviceExists) {
|
||||||
StorageService()->UpdateDeviceCapabilities(SerialNumber_, Caps );
|
StorageService()->UpdateDeviceCapabilities(SerialNumber_, Caps);
|
||||||
int Updated{0};
|
int Updated{0};
|
||||||
if(!Firmware.empty()) {
|
if (!Firmware.empty()) {
|
||||||
if(Firmware!=DeviceInfo.Firmware) {
|
if (Firmware != DeviceInfo.Firmware) {
|
||||||
DeviceFirmwareChangeKafkaEvent KEvent(SerialNumber_, Utils::Now(),DeviceInfo.Firmware, Firmware );
|
DeviceFirmwareChangeKafkaEvent KEvent(SerialNumber_, Utils::Now(),
|
||||||
|
DeviceInfo.Firmware, Firmware);
|
||||||
DeviceInfo.Firmware = Firmware;
|
DeviceInfo.Firmware = Firmware;
|
||||||
DeviceInfo.LastFWUpdate = Utils::Now();
|
DeviceInfo.LastFWUpdate = Utils::Now();
|
||||||
++Updated;
|
++Updated;
|
||||||
@@ -91,64 +94,70 @@ namespace OpenWifi {
|
|||||||
Notification.content.serialNumber = SerialNumber_;
|
Notification.content.serialNumber = SerialNumber_;
|
||||||
Notification.content.newFirmware = Firmware;
|
Notification.content.newFirmware = Firmware;
|
||||||
GWWebSocketNotifications::DeviceFirmwareUpdated(Notification);
|
GWWebSocketNotifications::DeviceFirmwareUpdated(Notification);
|
||||||
} else if(DeviceInfo.LastFWUpdate==0) {
|
} else if (DeviceInfo.LastFWUpdate == 0) {
|
||||||
DeviceInfo.LastFWUpdate = Utils::Now();
|
DeviceInfo.LastFWUpdate = Utils::Now();
|
||||||
++Updated;
|
++Updated;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(DeviceInfo.locale != State_.locale) {
|
if (DeviceInfo.locale != State_.locale) {
|
||||||
DeviceInfo.locale = State_.locale;
|
DeviceInfo.locale = State_.locale;
|
||||||
++Updated;
|
++Updated;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Compatible_ != DeviceInfo.DeviceType) {
|
if (Compatible_ != DeviceInfo.DeviceType) {
|
||||||
DeviceInfo.DeviceType = Compatible_;
|
DeviceInfo.DeviceType = Compatible_;
|
||||||
++Updated;
|
++Updated;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(RestrictedDevice != DeviceInfo.restrictedDevice) {
|
if (RestrictedDevice != DeviceInfo.restrictedDevice) {
|
||||||
DeviceInfo.restrictedDevice = RestrictedDevice;
|
DeviceInfo.restrictedDevice = RestrictedDevice;
|
||||||
++Updated;
|
++Updated;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Restrictions_ != DeviceInfo.restrictionDetails) {
|
if (Restrictions_ != DeviceInfo.restrictionDetails) {
|
||||||
DeviceInfo.restrictionDetails = Restrictions_;
|
DeviceInfo.restrictionDetails = Restrictions_;
|
||||||
++Updated;
|
++Updated;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Updated) {
|
if (Updated) {
|
||||||
StorageService()->UpdateDevice(DeviceInfo);
|
StorageService()->UpdateDevice(DeviceInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t UpgradedUUID=0;
|
uint64_t UpgradedUUID = 0;
|
||||||
LookForUpgrade(UUID,UpgradedUUID);
|
LookForUpgrade(UUID, UpgradedUUID);
|
||||||
State_.UUID = UpgradedUUID;
|
State_.UUID = UpgradedUUID;
|
||||||
}
|
}
|
||||||
|
|
||||||
State_.Compatible = Compatible_;
|
State_.Compatible = Compatible_;
|
||||||
State_.Connected = true;
|
State_.Connected = true;
|
||||||
ConnectionCompletionTime_ = std::chrono::high_resolution_clock::now() - ConnectionStart_;
|
ConnectionCompletionTime_ =
|
||||||
|
std::chrono::high_resolution_clock::now() - ConnectionStart_;
|
||||||
State_.connectionCompletionTime = ConnectionCompletionTime_.count();
|
State_.connectionCompletionTime = ConnectionCompletionTime_.count();
|
||||||
|
|
||||||
if(State_.VerifiedCertificate == GWObjects::VALID_CERTIFICATE) {
|
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_)) {
|
AP_WS_Server()->IsSimSerialNumber(CN_)) {
|
||||||
State_.VerifiedCertificate = GWObjects::VERIFIED;
|
State_.VerifiedCertificate = GWObjects::VERIFIED;
|
||||||
poco_information(Logger_, fmt::format("CONNECT({}): Fully validated and authenticated device. Session={} ConnectionCompletion Time={}",
|
poco_information(Logger_,
|
||||||
CId_,
|
fmt::format("CONNECT({}): Fully validated and authenticated "
|
||||||
State_.sessionId,
|
"device. Session={} ConnectionCompletion Time={}",
|
||||||
State_.connectionCompletionTime ));
|
CId_, State_.sessionId,
|
||||||
|
State_.connectionCompletionTime));
|
||||||
} else {
|
} else {
|
||||||
State_.VerifiedCertificate = GWObjects::MISMATCH_SERIAL;
|
State_.VerifiedCertificate = GWObjects::MISMATCH_SERIAL;
|
||||||
if(AP_WS_Server()->AllowSerialNumberMismatch()) {
|
if (AP_WS_Server()->AllowSerialNumberMismatch()) {
|
||||||
poco_information(
|
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,
|
CId_, CN_, SerialNumber_, State_.sessionId,
|
||||||
State_.connectionCompletionTime));
|
State_.connectionCompletionTime));
|
||||||
} else {
|
} else {
|
||||||
poco_information(
|
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));
|
CId_, CN_, SerialNumber_, State_.sessionId));
|
||||||
return EndConnection();
|
return EndConnection();
|
||||||
}
|
}
|
||||||
@@ -159,22 +168,26 @@ namespace OpenWifi {
|
|||||||
Notification.content.serialNumber = SerialNumber_;
|
Notification.content.serialNumber = SerialNumber_;
|
||||||
GWWebSocketNotifications::DeviceConnected(Notification);
|
GWWebSocketNotifications::DeviceConnected(Notification);
|
||||||
|
|
||||||
// std::cout << "Serial: " << SerialNumber_ << "Session: " << State_.sessionId << std::endl;
|
// std::cout << "Serial: " << SerialNumber_ << "Session: " << State_.sessionId <<
|
||||||
|
// std::endl;
|
||||||
|
|
||||||
if (KafkaManager()->Enabled()) {
|
if (KafkaManager()->Enabled()) {
|
||||||
Poco::JSON::Stringifier Stringify;
|
Poco::JSON::Stringifier Stringify;
|
||||||
|
|
||||||
ParamsObj->set(uCentralProtocol::CONNECTIONIP, CId_);
|
ParamsObj->set(uCentralProtocol::CONNECTIONIP, CId_);
|
||||||
ParamsObj->set("locale", State_.locale );
|
ParamsObj->set("locale", State_.locale);
|
||||||
ParamsObj->set(uCentralProtocol::TIMESTAMP, Utils::Now());
|
ParamsObj->set(uCentralProtocol::TIMESTAMP, Utils::Now());
|
||||||
std::ostringstream OS;
|
std::ostringstream OS;
|
||||||
Stringify.condense(ParamsObj, OS);
|
Stringify.condense(ParamsObj, OS);
|
||||||
KafkaManager()->PostMessage(KafkaTopics::CONNECTION, SerialNumber_, OS.str());
|
KafkaManager()->PostMessage(KafkaTopics::CONNECTION, SerialNumber_, OS.str());
|
||||||
}
|
}
|
||||||
} else {
|
} 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_++;
|
Errors_++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace OpenWifi
|
||||||
@@ -5,8 +5,8 @@
|
|||||||
#include "AP_WS_Connection.h"
|
#include "AP_WS_Connection.h"
|
||||||
#include "StorageService.h"
|
#include "StorageService.h"
|
||||||
|
|
||||||
#include "framework/ow_constants.h"
|
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
|
#include "framework/ow_constants.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
void AP_WS_Connection::Process_crashlog(Poco::JSON::Object::Ptr ParamsObj) {
|
void AP_WS_Connection::Process_crashlog(Poco::JSON::Object::Ptr ParamsObj) {
|
||||||
@@ -34,4 +34,4 @@ namespace OpenWifi {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} // namespace OpenWifi
|
||||||
@@ -9,10 +9,12 @@
|
|||||||
|
|
||||||
namespace OpenWifi {
|
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) {
|
if (!State_.Connected) {
|
||||||
poco_warning(Logger_, fmt::format(
|
poco_warning(Logger_,
|
||||||
"INVALID-PROTOCOL({}): Device '{}' is not following protocol", CId_, CN_));
|
fmt::format("INVALID-PROTOCOL({}): Device '{}' is not following protocol",
|
||||||
|
CId_, CN_));
|
||||||
Errors_++;
|
Errors_++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -20,8 +22,10 @@ namespace OpenWifi {
|
|||||||
auto Password = ParamsObj->get("currentPassword").toString();
|
auto Password = ParamsObj->get("currentPassword").toString();
|
||||||
|
|
||||||
StorageService()->SetDevicePassword(Serial, Password);
|
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 "AP_WS_Connection.h"
|
||||||
#include "StorageService.h"
|
#include "StorageService.h"
|
||||||
|
|
||||||
#include "framework/ow_constants.h"
|
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
#include "framework/KafkaManager.h"
|
#include "framework/KafkaManager.h"
|
||||||
|
#include "framework/ow_constants.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
void AP_WS_Connection::Process_event(Poco::JSON::Object::Ptr ParamsObj) {
|
void AP_WS_Connection::Process_event(Poco::JSON::Object::Ptr ParamsObj) {
|
||||||
if (!State_.Connected) {
|
if (!State_.Connected) {
|
||||||
poco_warning(
|
poco_warning(Logger_,
|
||||||
Logger_,
|
fmt::format("INVALID-PROTOCOL({}): Device '{}' is not following protocol",
|
||||||
fmt::format("INVALID-PROTOCOL({}): Device '{}' is not following protocol", CId_, CN_));
|
CId_, CN_));
|
||||||
Errors_++;
|
Errors_++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -41,10 +41,9 @@ namespace OpenWifi {
|
|||||||
OS.str());
|
OS.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch(const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
Logger_.log(E);
|
Logger_.log(E);
|
||||||
} catch(...) {
|
} catch (...) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} // namespace OpenWifi
|
||||||
@@ -5,16 +5,17 @@
|
|||||||
#include "AP_WS_Connection.h"
|
#include "AP_WS_Connection.h"
|
||||||
#include "StorageService.h"
|
#include "StorageService.h"
|
||||||
|
|
||||||
|
#include "fmt/format.h"
|
||||||
#include "framework/KafkaManager.h"
|
#include "framework/KafkaManager.h"
|
||||||
#include "framework/utils.h"
|
#include "framework/utils.h"
|
||||||
#include "fmt/format.h"
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
void AP_WS_Connection::Process_healthcheck(Poco::JSON::Object::Ptr ParamsObj) {
|
void AP_WS_Connection::Process_healthcheck(Poco::JSON::Object::Ptr ParamsObj) {
|
||||||
if (!State_.Connected) {
|
if (!State_.Connected) {
|
||||||
poco_warning(Logger_, fmt::format(
|
poco_warning(Logger_,
|
||||||
"INVALID-PROTOCOL({}): Device '{}' is not following protocol", CId_, CN_));
|
fmt::format("INVALID-PROTOCOL({}): Device '{}' is not following protocol",
|
||||||
|
CId_, CN_));
|
||||||
Errors_++;
|
Errors_++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -31,16 +32,14 @@ namespace OpenWifi {
|
|||||||
request_uuid = ParamsObj->get(uCentralProtocol::REQUEST_UUID).toString();
|
request_uuid = ParamsObj->get(uCentralProtocol::REQUEST_UUID).toString();
|
||||||
|
|
||||||
if (request_uuid.empty()) {
|
if (request_uuid.empty()) {
|
||||||
poco_trace(Logger_,
|
poco_trace(Logger_, fmt::format("HEALTHCHECK({}): UUID={} Updating.", CId_, UUID));
|
||||||
fmt::format("HEALTHCHECK({}): UUID={} Updating.", CId_, UUID));
|
|
||||||
} else {
|
} else {
|
||||||
poco_trace(Logger_,
|
poco_trace(Logger_, fmt::format("HEALTHCHECK({}): UUID={} Updating for CMD={}.",
|
||||||
fmt::format("HEALTHCHECK({}): UUID={} Updating for CMD={}.", CId_,
|
CId_, UUID, request_uuid));
|
||||||
UUID, request_uuid));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t UpgradedUUID;
|
uint64_t UpgradedUUID;
|
||||||
LookForUpgrade(UUID,UpgradedUUID);
|
LookForUpgrade(UUID, UpgradedUUID);
|
||||||
State_.UUID = UpgradedUUID;
|
State_.UUID = UpgradedUUID;
|
||||||
|
|
||||||
GWObjects::HealthCheck Check;
|
GWObjects::HealthCheck Check;
|
||||||
@@ -71,4 +70,4 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace OpenWifi
|
||||||
@@ -5,15 +5,15 @@
|
|||||||
#include "AP_WS_Connection.h"
|
#include "AP_WS_Connection.h"
|
||||||
#include "StorageService.h"
|
#include "StorageService.h"
|
||||||
|
|
||||||
#include "framework/ow_constants.h"
|
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
|
#include "framework/ow_constants.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
void AP_WS_Connection::Process_log(Poco::JSON::Object::Ptr ParamsObj) {
|
void AP_WS_Connection::Process_log(Poco::JSON::Object::Ptr ParamsObj) {
|
||||||
if (!State_.Connected) {
|
if (!State_.Connected) {
|
||||||
poco_warning(
|
poco_warning(Logger_,
|
||||||
Logger_,
|
fmt::format("INVALID-PROTOCOL({}): Device '{}' is not following protocol",
|
||||||
fmt::format("INVALID-PROTOCOL({}): Device '{}' is not following protocol", CId_, CN_));
|
CId_, CN_));
|
||||||
Errors_++;
|
Errors_++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -41,4 +41,4 @@ namespace OpenWifi {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} // namespace OpenWifi
|
||||||
@@ -15,4 +15,4 @@ namespace OpenWifi {
|
|||||||
poco_warning(Logger_, fmt::format("PING({}): Missing parameter.", CId_));
|
poco_warning(Logger_, fmt::format("PING({}): Missing parameter.", CId_));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} // namespace OpenWifi
|
||||||
@@ -3,12 +3,11 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "AP_WS_Connection.h"
|
#include "AP_WS_Connection.h"
|
||||||
#include "StorageService.h"
|
|
||||||
#include "CommandManager.h"
|
#include "CommandManager.h"
|
||||||
|
#include "StorageService.h"
|
||||||
|
|
||||||
#include "framework/ow_constants.h"
|
|
||||||
#include "framework/MicroServiceFuncs.h"
|
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
|
#include "framework/MicroServiceFuncs.h"
|
||||||
#include "framework/ow_constants.h"
|
#include "framework/ow_constants.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
@@ -52,16 +51,24 @@ namespace OpenWifi {
|
|||||||
Poco::JSON::Stringifier::stringify(Params, O);
|
Poco::JSON::Stringifier::stringify(Params, O);
|
||||||
Cmd.Details = O.str();
|
Cmd.Details = O.str();
|
||||||
bool Sent;
|
bool Sent;
|
||||||
CommandManager()->PostCommand(CommandManager()->Next_RPC_ID(), APCommands::Commands::reboot, SerialNumber_, Cmd.Command, Params, Cmd.UUID, Sent, false, false);
|
CommandManager()->PostCommand(CommandManager()->Next_RPC_ID(),
|
||||||
StorageService()->AddCommand(SerialNumber_, Cmd, Storage::CommandExecutionType::COMMAND_EXECUTED);
|
APCommands::Commands::reboot, SerialNumber_,
|
||||||
poco_information(Logger_, fmt::format("RECOVERY({}): Recovery mode received, need for a reboot.", CId_));
|
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 {
|
} else {
|
||||||
poco_information(Logger_, fmt::format(
|
poco_information(
|
||||||
"RECOVERY({}): Recovery mode received, no need for a reboot.", CId_));
|
Logger_,
|
||||||
|
fmt::format("RECOVERY({}): Recovery mode received, no need for a reboot.",
|
||||||
|
CId_));
|
||||||
}
|
}
|
||||||
} else {
|
} 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_));
|
CId_));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} // namespace OpenWifi
|
||||||
@@ -3,8 +3,8 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "AP_WS_Connection.h"
|
#include "AP_WS_Connection.h"
|
||||||
#include "StorageService.h"
|
|
||||||
#include "StateUtils.h"
|
#include "StateUtils.h"
|
||||||
|
#include "StorageService.h"
|
||||||
|
|
||||||
#include "UI_GW_WebSocketNotifications.h"
|
#include "UI_GW_WebSocketNotifications.h"
|
||||||
|
|
||||||
@@ -16,8 +16,9 @@
|
|||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
void AP_WS_Connection::Process_state(Poco::JSON::Object::Ptr ParamsObj) {
|
void AP_WS_Connection::Process_state(Poco::JSON::Object::Ptr ParamsObj) {
|
||||||
if (!State_.Connected) {
|
if (!State_.Connected) {
|
||||||
poco_warning(Logger_, fmt::format(
|
poco_warning(Logger_,
|
||||||
"INVALID-PROTOCOL({}): Device '{}' is not following protocol", CId_, CN_));
|
fmt::format("INVALID-PROTOCOL({}): Device '{}' is not following protocol",
|
||||||
|
CId_, CN_));
|
||||||
Errors_++;
|
Errors_++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -34,12 +35,12 @@ namespace OpenWifi {
|
|||||||
if (request_uuid.empty()) {
|
if (request_uuid.empty()) {
|
||||||
poco_trace(Logger_, fmt::format("STATE({}): UUID={} Updating.", CId_, UUID));
|
poco_trace(Logger_, fmt::format("STATE({}): UUID={} Updating.", CId_, UUID));
|
||||||
} else {
|
} else {
|
||||||
poco_trace(Logger_, fmt::format("STATE({}): UUID={} Updating for CMD={}.",
|
poco_trace(Logger_, fmt::format("STATE({}): UUID={} Updating for CMD={}.", CId_,
|
||||||
CId_, UUID, request_uuid));
|
UUID, request_uuid));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t UpgradedUUID;
|
uint64_t UpgradedUUID;
|
||||||
LookForUpgrade(UUID,UpgradedUUID);
|
LookForUpgrade(UUID, UpgradedUUID);
|
||||||
State_.UUID = UpgradedUUID;
|
State_.UUID = UpgradedUUID;
|
||||||
SetLastStats(StateStr);
|
SetLastStats(StateStr);
|
||||||
|
|
||||||
@@ -52,9 +53,7 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
StateUtils::ComputeAssociations(StateObj, State_.Associations_2G,
|
StateUtils::ComputeAssociations(StateObj, State_.Associations_2G,
|
||||||
State_.Associations_5G,
|
State_.Associations_5G, State_.Associations_6G);
|
||||||
State_.Associations_6G
|
|
||||||
);
|
|
||||||
|
|
||||||
if (KafkaManager()->Enabled()) {
|
if (KafkaManager()->Enabled()) {
|
||||||
Poco::JSON::Stringifier Stringify;
|
Poco::JSON::Stringifier Stringify;
|
||||||
@@ -68,7 +67,9 @@ namespace OpenWifi {
|
|||||||
GWWebSocketNotifications::DeviceStatistics(N);
|
GWWebSocketNotifications::DeviceStatistics(N);
|
||||||
|
|
||||||
} else {
|
} 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,37 +3,39 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "AP_WS_Connection.h"
|
#include "AP_WS_Connection.h"
|
||||||
#include "TelemetryStream.h"
|
|
||||||
#include "CommandManager.h"
|
#include "CommandManager.h"
|
||||||
|
#include "TelemetryStream.h"
|
||||||
|
|
||||||
|
#include "fmt/format.h"
|
||||||
#include "framework/KafkaManager.h"
|
#include "framework/KafkaManager.h"
|
||||||
#include "framework/utils.h"
|
#include "framework/utils.h"
|
||||||
#include "fmt/format.h"
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
void AP_WS_Connection::Process_telemetry(Poco::JSON::Object::Ptr ParamsObj) {
|
void AP_WS_Connection::Process_telemetry(Poco::JSON::Object::Ptr ParamsObj) {
|
||||||
if (!State_.Connected) {
|
if (!State_.Connected) {
|
||||||
poco_warning(Logger_, fmt::format(
|
poco_warning(Logger_,
|
||||||
"INVALID-PROTOCOL({}): Device '{}' is not following protocol", CId_, CN_));
|
fmt::format("INVALID-PROTOCOL({}): Device '{}' is not following protocol",
|
||||||
|
CId_, CN_));
|
||||||
Errors_++;
|
Errors_++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
poco_trace(Logger_,fmt::format("Telemetry data received for {}", SerialNumber_));
|
poco_trace(Logger_, fmt::format("Telemetry data received for {}", SerialNumber_));
|
||||||
if (TelemetryReporting_ || ParamsObj->has("adhoc")) {
|
if (TelemetryReporting_ || ParamsObj->has("adhoc")) {
|
||||||
if (ParamsObj->has("data")) {
|
if (ParamsObj->has("data")) {
|
||||||
auto Payload = ParamsObj->get("data").extract<Poco::JSON::Object::Ptr>();
|
auto Payload = ParamsObj->get("data").extract<Poco::JSON::Object::Ptr>();
|
||||||
Payload->set("timestamp", Utils::Now());
|
Payload->set("timestamp", Utils::Now());
|
||||||
std::ostringstream SS;
|
std::ostringstream SS;
|
||||||
Payload->stringify(SS);
|
Payload->stringify(SS);
|
||||||
auto now=Utils::Now();
|
auto now = Utils::Now();
|
||||||
if(ParamsObj->has("adhoc")) {
|
if (ParamsObj->has("adhoc")) {
|
||||||
KafkaManager()->PostMessage(KafkaTopics::DEVICE_TELEMETRY, SerialNumber_,
|
KafkaManager()->PostMessage(KafkaTopics::DEVICE_TELEMETRY, SerialNumber_,
|
||||||
SS.str());
|
SS.str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (TelemetryWebSocketRefCount_) {
|
if (TelemetryWebSocketRefCount_) {
|
||||||
if(now<TelemetryWebSocketTimer_) {
|
if (now < TelemetryWebSocketTimer_) {
|
||||||
// std::cout << SerialNumber_ << ": Updating WebSocket telemetry" << std::endl;
|
// std::cout << SerialNumber_ << ": Updating WebSocket telemetry" <<
|
||||||
|
// std::endl;
|
||||||
TelemetryWebSocketPackets_++;
|
TelemetryWebSocketPackets_++;
|
||||||
State_.websocketPackets = TelemetryWebSocketPackets_;
|
State_.websocketPackets = TelemetryWebSocketPackets_;
|
||||||
TelemetryStream()->NotifyEndPoint(SerialNumberInt_, SS.str());
|
TelemetryStream()->NotifyEndPoint(SerialNumberInt_, SS.str());
|
||||||
@@ -42,7 +44,7 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (TelemetryKafkaRefCount_) {
|
if (TelemetryKafkaRefCount_) {
|
||||||
if(KafkaManager()->Enabled() && now<TelemetryKafkaTimer_) {
|
if (KafkaManager()->Enabled() && now < TelemetryKafkaTimer_) {
|
||||||
// std::cout << SerialNumber_ << ": Updating Kafka telemetry" << std::endl;
|
// std::cout << SerialNumber_ << ": Updating Kafka telemetry" << std::endl;
|
||||||
TelemetryKafkaPackets_++;
|
TelemetryKafkaPackets_++;
|
||||||
State_.kafkaPackets = TelemetryKafkaPackets_;
|
State_.kafkaPackets = TelemetryKafkaPackets_;
|
||||||
@@ -53,12 +55,14 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
poco_debug(Logger_,fmt::format("TELEMETRY({}): Invalid telemetry packet.",SerialNumber_));
|
poco_debug(Logger_,
|
||||||
|
fmt::format("TELEMETRY({}): Invalid telemetry packet.", SerialNumber_));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// if we are ignoring telemetry, then close it down on the device.
|
// 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());
|
StopTelemetry(CommandManager()->Next_RPC_ID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} // namespace OpenWifi
|
||||||
@@ -7,11 +7,10 @@
|
|||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
void AP_WS_Connection::Process_venuebroadcast(Poco::JSON::Object::Ptr ParamsObj) {
|
void AP_WS_Connection::Process_venuebroadcast(Poco::JSON::Object::Ptr ParamsObj) {
|
||||||
if(ParamsObj->has("data") && ParamsObj->has("serial") && ParamsObj->has("timestamp")) {
|
if (ParamsObj->has("data") && ParamsObj->has("serial") && ParamsObj->has("timestamp")) {
|
||||||
VenueBroadcaster()->Broadcast(
|
VenueBroadcaster()->Broadcast(ParamsObj->get("serial").toString(),
|
||||||
ParamsObj->get("serial").toString(),
|
|
||||||
ParamsObj->get("data").toString(),
|
ParamsObj->get("data").toString(),
|
||||||
ParamsObj->get("timestamp"));
|
ParamsObj->get("timestamp"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} // namespace OpenWifi
|
||||||
@@ -4,16 +4,16 @@
|
|||||||
#include "AP_WS_Connection.h"
|
#include "AP_WS_Connection.h"
|
||||||
#include "StorageService.h"
|
#include "StorageService.h"
|
||||||
|
|
||||||
#include "framework/ow_constants.h"
|
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
#include "framework/KafkaManager.h"
|
#include "framework/KafkaManager.h"
|
||||||
|
#include "framework/ow_constants.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
void AP_WS_Connection::Process_wifiscan(Poco::JSON::Object::Ptr ParamsObj) {
|
void AP_WS_Connection::Process_wifiscan(Poco::JSON::Object::Ptr ParamsObj) {
|
||||||
if (!State_.Connected) {
|
if (!State_.Connected) {
|
||||||
poco_warning(
|
poco_warning(Logger_,
|
||||||
Logger_,
|
fmt::format("INVALID-PROTOCOL({}): Device '{}' is not following protocol",
|
||||||
fmt::format("INVALID-PROTOCOL({}): Device '{}' is not following protocol", CId_, CN_));
|
CId_, CN_));
|
||||||
Errors_++;
|
Errors_++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -29,4 +29,4 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} // namespace OpenWifi
|
||||||
@@ -4,11 +4,11 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <shared_mutex>
|
#include <shared_mutex>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "Poco/Net/SocketAcceptor.h"
|
|
||||||
#include "Poco/Environment.h"
|
#include "Poco/Environment.h"
|
||||||
|
#include "Poco/Net/SocketAcceptor.h"
|
||||||
|
|
||||||
#include "framework/utils.h"
|
#include "framework/utils.h"
|
||||||
|
|
||||||
@@ -16,14 +16,12 @@ namespace OpenWifi {
|
|||||||
class AP_WS_ReactorThreadPool {
|
class AP_WS_ReactorThreadPool {
|
||||||
public:
|
public:
|
||||||
explicit AP_WS_ReactorThreadPool() {
|
explicit AP_WS_ReactorThreadPool() {
|
||||||
NumberOfThreads_ = Poco::Environment::processorCount()*2;
|
NumberOfThreads_ = Poco::Environment::processorCount() * 2;
|
||||||
if(NumberOfThreads_==0)
|
if (NumberOfThreads_ == 0)
|
||||||
NumberOfThreads_=4;
|
NumberOfThreads_ = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
~ AP_WS_ReactorThreadPool() {
|
~AP_WS_ReactorThreadPool() { Stop(); }
|
||||||
Stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Start() {
|
void Start() {
|
||||||
for (uint64_t i = 0; i < NumberOfThreads_; ++i) {
|
for (uint64_t i = 0; i < NumberOfThreads_; ++i) {
|
||||||
@@ -31,7 +29,7 @@ namespace OpenWifi {
|
|||||||
auto NewThread = std::make_unique<Poco::Thread>();
|
auto NewThread = std::make_unique<Poco::Thread>();
|
||||||
NewThread->start(*NewReactor);
|
NewThread->start(*NewReactor);
|
||||||
std::string ThreadName{"ap:react:" + std::to_string(i)};
|
std::string ThreadName{"ap:react:" + std::to_string(i)};
|
||||||
Utils::SetThreadName(*NewThread,ThreadName.c_str());
|
Utils::SetThreadName(*NewThread, ThreadName.c_str());
|
||||||
Reactors_.emplace_back(std::move(NewReactor));
|
Reactors_.emplace_back(std::move(NewReactor));
|
||||||
Threads_.emplace_back(std::move(NewThread));
|
Threads_.emplace_back(std::move(NewThread));
|
||||||
}
|
}
|
||||||
@@ -61,4 +59,4 @@ namespace OpenWifi {
|
|||||||
std::vector<std::unique_ptr<Poco::Net::SocketReactor>> Reactors_;
|
std::vector<std::unique_ptr<Poco::Net::SocketReactor>> Reactors_;
|
||||||
std::vector<std::unique_ptr<Poco::Thread>> Threads_;
|
std::vector<std::unique_ptr<Poco::Thread>> Threads_;
|
||||||
};
|
};
|
||||||
}
|
} // namespace OpenWifi
|
||||||
@@ -6,35 +6,41 @@
|
|||||||
// Arilia Wireless Inc.
|
// Arilia Wireless Inc.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "Poco/Net/HTTPHeaderStream.h"
|
|
||||||
#include "Poco/Net/Context.h"
|
#include "Poco/Net/Context.h"
|
||||||
|
#include "Poco/Net/HTTPHeaderStream.h"
|
||||||
#include "Poco/Net/HTTPServerRequest.h"
|
#include "Poco/Net/HTTPServerRequest.h"
|
||||||
|
|
||||||
#include "AP_WS_Server.h"
|
|
||||||
#include "AP_WS_Connection.h"
|
#include "AP_WS_Connection.h"
|
||||||
|
#include "AP_WS_Server.h"
|
||||||
#include "ConfigurationCache.h"
|
#include "ConfigurationCache.h"
|
||||||
#include "TelemetryStream.h"
|
#include "TelemetryStream.h"
|
||||||
|
|
||||||
#include "framework/MicroServiceFuncs.h"
|
|
||||||
#include "framework/utils.h"
|
|
||||||
#include "UI_GW_WebSocketNotifications.h"
|
#include "UI_GW_WebSocketNotifications.h"
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
|
#include "framework/MicroServiceFuncs.h"
|
||||||
|
#include "framework/utils.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
void AP_WS_RequestHandler::handleRequest(Poco::Net::HTTPServerRequest &request,
|
void AP_WS_RequestHandler::handleRequest(Poco::Net::HTTPServerRequest &request,
|
||||||
Poco::Net::HTTPServerResponse &response) {
|
Poco::Net::HTTPServerResponse &response) {
|
||||||
try {
|
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 (...) {
|
} catch (...) {
|
||||||
poco_warning(Logger_,"Exception during WS creation");
|
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,
|
||||||
if(IsCertOk()) {
|
const Poco::Crypto::X509Certificate &Certificate) {
|
||||||
if(!Certificate.issuedBy(*IssuerCert_)) {
|
if (IsCertOk()) {
|
||||||
poco_warning(Logger(),fmt::format("CERTIFICATE({}): issuer mismatch. Local='{}' Incoming='{}'", ConnectionId, IssuerCert_->issuerName(), Certificate.issuerName()));
|
if (!Certificate.issuedBy(*IssuerCert_)) {
|
||||||
|
poco_warning(
|
||||||
|
Logger(),
|
||||||
|
fmt::format("CERTIFICATE({}): issuer mismatch. Local='{}' Incoming='{}'",
|
||||||
|
ConnectionId, IssuerCert_->issuerName(), Certificate.issuerName()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -44,15 +50,17 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
int AP_WS_Server::Start() {
|
int AP_WS_Server::Start() {
|
||||||
|
|
||||||
AllowSerialNumberMismatch_ = MicroServiceConfigGetBool("openwifi.certificates.allowmismatch",true);
|
AllowSerialNumberMismatch_ =
|
||||||
MismatchDepth_ = MicroServiceConfigGetInt("openwifi.certificates.mismatchdepth",2);
|
MicroServiceConfigGetBool("openwifi.certificates.allowmismatch", true);
|
||||||
|
MismatchDepth_ = MicroServiceConfigGetInt("openwifi.certificates.mismatchdepth", 2);
|
||||||
|
|
||||||
Reactor_pool_ = std::make_unique<AP_WS_ReactorThreadPool>();
|
Reactor_pool_ = std::make_unique<AP_WS_ReactorThreadPool>();
|
||||||
Reactor_pool_->Start();
|
Reactor_pool_->Start();
|
||||||
|
|
||||||
for(const auto & Svr : ConfigServersList_ ) {
|
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.Port(), Svr.KeyFile(), Svr.CertFile()));
|
||||||
|
|
||||||
Svr.LogCert(Logger());
|
Svr.LogCert(Logger());
|
||||||
@@ -61,8 +69,8 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
if (!IsCertOk()) {
|
if (!IsCertOk()) {
|
||||||
IssuerCert_ = std::make_unique<Poco::Crypto::X509Certificate>(Svr.IssuerCertFile());
|
IssuerCert_ = std::make_unique<Poco::Crypto::X509Certificate>(Svr.IssuerCertFile());
|
||||||
poco_information(Logger(),
|
poco_information(
|
||||||
fmt::format("Certificate Issuer Name:{}", IssuerCert_->issuerName()));
|
Logger(), fmt::format("Certificate Issuer Name:{}", IssuerCert_->issuerName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Poco::Net::Context::Params P;
|
Poco::Net::Context::Params P;
|
||||||
@@ -74,7 +82,8 @@ namespace OpenWifi {
|
|||||||
P.dhUse2048Bits = true;
|
P.dhUse2048Bits = true;
|
||||||
P.caLocation = Svr.Cas();
|
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 Cert(Svr.CertFile());
|
||||||
Poco::Crypto::X509Certificate Root(Svr.RootCA());
|
Poco::Crypto::X509Certificate Root(Svr.RootCA());
|
||||||
@@ -96,7 +105,8 @@ namespace OpenWifi {
|
|||||||
Context->enableSessionCache(true);
|
Context->enableSessionCache(true);
|
||||||
Context->enableExtendedCertificateVerification(false);
|
Context->enableExtendedCertificateVerification(false);
|
||||||
// Context->disableStatelessSessionResumption();
|
// 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;
|
auto WebServerHttpParams = new Poco::Net::HTTPServerParams;
|
||||||
WebServerHttpParams->setMaxThreads(50);
|
WebServerHttpParams->setMaxThreads(50);
|
||||||
@@ -110,25 +120,29 @@ namespace OpenWifi {
|
|||||||
: Poco::Net::AddressFamily::IPv4));
|
: Poco::Net::AddressFamily::IPv4));
|
||||||
Poco::Net::SocketAddress SockAddr(Addr, Svr.Port());
|
Poco::Net::SocketAddress SockAddr(Addr, Svr.Port());
|
||||||
auto NewWebServer = std::make_unique<Poco::Net::HTTPServer>(
|
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));
|
WebServers_.push_back(std::move(NewWebServer));
|
||||||
} else {
|
} else {
|
||||||
Poco::Net::IPAddress Addr(Svr.Address());
|
Poco::Net::IPAddress Addr(Svr.Address());
|
||||||
Poco::Net::SocketAddress SockAddr(Addr, Svr.Port());
|
Poco::Net::SocketAddress SockAddr(Addr, Svr.Port());
|
||||||
auto NewWebServer = std::make_unique<Poco::Net::HTTPServer>(
|
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));
|
WebServers_.push_back(std::move(NewWebServer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto &server:WebServers_) {
|
for (auto &server : WebServers_) {
|
||||||
server->start();
|
server->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
ReactorThread_.start(Reactor_);
|
ReactorThread_.start(Reactor_);
|
||||||
|
|
||||||
auto ProvString = MicroServiceConfigGetString("autoprovisioning.process","default");
|
auto ProvString = MicroServiceConfigGetString("autoprovisioning.process", "default");
|
||||||
if(ProvString!="default") {
|
if (ProvString != "default") {
|
||||||
auto Tokens = Poco::StringTokenizer(ProvString, ",");
|
auto Tokens = Poco::StringTokenizer(ProvString, ",");
|
||||||
for (const auto &i : Tokens) {
|
for (const auto &i : Tokens) {
|
||||||
if (i == "prov")
|
if (i == "prov")
|
||||||
@@ -140,11 +154,12 @@ namespace OpenWifi {
|
|||||||
UseDefaultConfig_ = true;
|
UseDefaultConfig_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
SimulatorId_ = MicroServiceConfigGetString("simulatorid","");
|
SimulatorId_ = MicroServiceConfigGetString("simulatorid", "");
|
||||||
SimulatorEnabled_ = !SimulatorId_.empty();
|
SimulatorEnabled_ = !SimulatorId_.empty();
|
||||||
Utils::SetThreadName(ReactorThread_,"dev:react:head");
|
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_.setStartInterval(10 * 1000);
|
||||||
Timer_.setPeriodicInterval(5 * 1000); // every minute
|
Timer_.setPeriodicInterval(5 * 1000); // every minute
|
||||||
Timer_.start(*GarbageCollectorCallback_, MicroServiceTimerPool());
|
Timer_.start(*GarbageCollectorCallback_, MicroServiceTimerPool());
|
||||||
@@ -155,7 +170,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
void AP_WS_Server::onGarbageCollecting([[maybe_unused]] Poco::Timer &timer) {
|
void AP_WS_Server::onGarbageCollecting([[maybe_unused]] Poco::Timer &timer) {
|
||||||
std::lock_guard Lock(WSServerMutex_);
|
std::lock_guard Lock(WSServerMutex_);
|
||||||
if(!Garbage_.empty()) {
|
if (!Garbage_.empty()) {
|
||||||
Garbage_.clear();
|
Garbage_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,11 +179,11 @@ namespace OpenWifi {
|
|||||||
NumberOfConnectedDevices_ = 0;
|
NumberOfConnectedDevices_ = 0;
|
||||||
NumberOfConnectingDevices_ = 0;
|
NumberOfConnectingDevices_ = 0;
|
||||||
AverageDeviceConnectionTime_ = 0;
|
AverageDeviceConnectionTime_ = 0;
|
||||||
uint64_t total_connected_time=0;
|
uint64_t total_connected_time = 0;
|
||||||
|
|
||||||
auto now = Utils::Now();
|
auto now = Utils::Now();
|
||||||
for (const auto & connection:SerialNumbers_) {
|
for (const auto &connection : SerialNumbers_) {
|
||||||
if(connection.second.second == nullptr) {
|
if (connection.second.second == nullptr) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (connection.second.second->State_.Connected) {
|
if (connection.second.second->State_.Connected) {
|
||||||
@@ -179,12 +194,16 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AverageDeviceConnectionTime_ = (NumberOfConnectedDevices_!=0) ? total_connected_time/NumberOfConnectedDevices_ : 0;
|
AverageDeviceConnectionTime_ =
|
||||||
if((now-last_log)>120) {
|
(NumberOfConnectedDevices_ != 0) ? total_connected_time / NumberOfConnectedDevices_ : 0;
|
||||||
|
if ((now - last_log) > 120) {
|
||||||
last_log = now;
|
last_log = now;
|
||||||
poco_information(Logger(),
|
poco_information(
|
||||||
fmt::format("Active AP connections: {} Connecting: {} Average connection time: {} seconds",
|
Logger(),
|
||||||
NumberOfConnectedDevices_, NumberOfConnectingDevices_, AverageDeviceConnectionTime_));
|
fmt::format(
|
||||||
|
"Active AP connections: {} Connecting: {} Average connection time: {} seconds",
|
||||||
|
NumberOfConnectedDevices_, NumberOfConnectingDevices_,
|
||||||
|
AverageDeviceConnectionTime_));
|
||||||
}
|
}
|
||||||
|
|
||||||
GWWebSocketNotifications::NumberOfConnection_t Notification;
|
GWWebSocketNotifications::NumberOfConnection_t Notification;
|
||||||
@@ -195,18 +214,18 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AP_WS_Server::Stop() {
|
void AP_WS_Server::Stop() {
|
||||||
poco_information(Logger(),"Stopping...");
|
poco_information(Logger(), "Stopping...");
|
||||||
Running_ = false;
|
Running_ = false;
|
||||||
|
|
||||||
Timer_.stop();
|
Timer_.stop();
|
||||||
|
|
||||||
for(auto &server:WebServers_) {
|
for (auto &server : WebServers_) {
|
||||||
server->stopAll();
|
server->stopAll();
|
||||||
}
|
}
|
||||||
Reactor_pool_->Stop();
|
Reactor_pool_->Stop();
|
||||||
Reactor_.stop();
|
Reactor_.stop();
|
||||||
ReactorThread_.join();
|
ReactorThread_.join();
|
||||||
poco_information(Logger(),"Stopped...");
|
poco_information(Logger(), "Stopped...");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AP_WS_Server::GetStatistics(uint64_t SerialNumber, std::string &Statistics) const {
|
bool AP_WS_Server::GetStatistics(uint64_t SerialNumber, std::string &Statistics) const {
|
||||||
@@ -223,7 +242,7 @@ namespace OpenWifi {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AP_WS_Server::GetState(uint64_t SerialNumber, GWObjects::ConnectionState & State) const {
|
bool AP_WS_Server::GetState(uint64_t SerialNumber, GWObjects::ConnectionState &State) const {
|
||||||
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||||
{
|
{
|
||||||
std::lock_guard Lock(WSServerMutex_);
|
std::lock_guard Lock(WSServerMutex_);
|
||||||
@@ -237,7 +256,8 @@ namespace OpenWifi {
|
|||||||
return true;
|
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::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||||
{
|
{
|
||||||
std::lock_guard Lock(WSServerMutex_);
|
std::lock_guard Lock(WSServerMutex_);
|
||||||
@@ -255,12 +275,12 @@ namespace OpenWifi {
|
|||||||
std::lock_guard Lock(WSServerMutex_);
|
std::lock_guard Lock(WSServerMutex_);
|
||||||
|
|
||||||
auto Conn = Sessions_.find(connection_id);
|
auto Conn = Sessions_.find(connection_id);
|
||||||
if(Conn == end(Sessions_))
|
if (Conn == end(Sessions_))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto CurrentSerialNumber = SerialNumbers_.find(SerialNumber);
|
auto CurrentSerialNumber = SerialNumbers_.find(SerialNumber);
|
||||||
if( (CurrentSerialNumber==SerialNumbers_.end()) ||
|
if ((CurrentSerialNumber == SerialNumbers_.end()) ||
|
||||||
(CurrentSerialNumber->second.first<connection_id)) {
|
(CurrentSerialNumber->second.first < connection_id)) {
|
||||||
SerialNumbers_[SerialNumber] = std::make_pair(connection_id, Conn->second);
|
SerialNumbers_[SerialNumber] = std::make_pair(connection_id, Conn->second);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -270,7 +290,7 @@ namespace OpenWifi {
|
|||||||
std::lock_guard G(WSServerMutex_);
|
std::lock_guard G(WSServerMutex_);
|
||||||
|
|
||||||
auto Session = Sessions_.find(session_id);
|
auto Session = Sessions_.find(session_id);
|
||||||
if(Session==end(Sessions_))
|
if (Session == end(Sessions_))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Garbage_.push_back(Session->second);
|
Garbage_.push_back(Session->second);
|
||||||
@@ -281,7 +301,7 @@ namespace OpenWifi {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Device->second.first==session_id) {
|
if (Device->second.first == session_id) {
|
||||||
Sessions_.erase(Session);
|
Sessions_.erase(Session);
|
||||||
SerialNumbers_.erase(Device);
|
SerialNumbers_.erase(Device);
|
||||||
return true;
|
return true;
|
||||||
@@ -291,7 +311,8 @@ namespace OpenWifi {
|
|||||||
return false;
|
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::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||||
{
|
{
|
||||||
std::lock_guard Lock(WSServerMutex_);
|
std::lock_guard Lock(WSServerMutex_);
|
||||||
@@ -318,7 +339,7 @@ namespace OpenWifi {
|
|||||||
return DevicePtr->State_.Connected;
|
return DevicePtr->State_.Connected;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AP_WS_Server::SendFrame(uint64_t SerialNumber, const std::string & Payload) const {
|
bool AP_WS_Server::SendFrame(uint64_t SerialNumber, const std::string &Payload) const {
|
||||||
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||||
{
|
{
|
||||||
std::lock_guard Lock(WSServerMutex_);
|
std::lock_guard Lock(WSServerMutex_);
|
||||||
@@ -331,7 +352,8 @@ namespace OpenWifi {
|
|||||||
try {
|
try {
|
||||||
return DevicePtr->Send(Payload);
|
return DevicePtr->Send(Payload);
|
||||||
} catch (...) {
|
} 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;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -350,7 +372,10 @@ namespace OpenWifi {
|
|||||||
DevicePtr->StopWebSocketTelemetry(RPCID);
|
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::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||||
{
|
{
|
||||||
std::lock_guard Lock(WSServerMutex_);
|
std::lock_guard Lock(WSServerMutex_);
|
||||||
@@ -363,7 +388,9 @@ namespace OpenWifi {
|
|||||||
DevicePtr->SetWebSocketTelemetryReporting(RPCID, Interval, Lifetime, TelemetryTypes);
|
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::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||||
{
|
{
|
||||||
std::lock_guard Lock(WSServerMutex_);
|
std::lock_guard Lock(WSServerMutex_);
|
||||||
@@ -389,14 +416,11 @@ namespace OpenWifi {
|
|||||||
DevicePtr->StopKafkaTelemetry(RPCID);
|
DevicePtr->StopKafkaTelemetry(RPCID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AP_WS_Server::GetTelemetryParameters(uint64_t SerialNumber , bool & TelemetryRunning,
|
void AP_WS_Server::GetTelemetryParameters(
|
||||||
uint64_t & TelemetryInterval,
|
uint64_t SerialNumber, bool &TelemetryRunning, uint64_t &TelemetryInterval,
|
||||||
uint64_t & TelemetryWebSocketTimer,
|
uint64_t &TelemetryWebSocketTimer, uint64_t &TelemetryKafkaTimer,
|
||||||
uint64_t & TelemetryKafkaTimer,
|
uint64_t &TelemetryWebSocketCount, uint64_t &TelemetryKafkaCount,
|
||||||
uint64_t & TelemetryWebSocketCount,
|
uint64_t &TelemetryWebSocketPackets, uint64_t &TelemetryKafkaPackets) {
|
||||||
uint64_t & TelemetryKafkaCount,
|
|
||||||
uint64_t & TelemetryWebSocketPackets,
|
|
||||||
uint64_t & TelemetryKafkaPackets) {
|
|
||||||
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||||
{
|
{
|
||||||
std::lock_guard Lock(WSServerMutex_);
|
std::lock_guard Lock(WSServerMutex_);
|
||||||
@@ -406,13 +430,14 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
DevicePtr = Device->second.second;
|
DevicePtr = Device->second.second;
|
||||||
}
|
}
|
||||||
DevicePtr->GetTelemetryParameters(
|
DevicePtr->GetTelemetryParameters(TelemetryRunning, TelemetryInterval,
|
||||||
TelemetryRunning, TelemetryInterval, TelemetryWebSocketTimer, TelemetryKafkaTimer,
|
TelemetryWebSocketTimer, TelemetryKafkaTimer,
|
||||||
TelemetryWebSocketCount, TelemetryKafkaCount, TelemetryWebSocketPackets,
|
TelemetryWebSocketCount, TelemetryKafkaCount,
|
||||||
TelemetryKafkaPackets);
|
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::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||||
{
|
{
|
||||||
std::lock_guard Lock(WSServerMutex_);
|
std::lock_guard Lock(WSServerMutex_);
|
||||||
@@ -424,14 +449,18 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return DevicePtr->SendRadiusAccountingData(buffer,size);
|
return DevicePtr->SendRadiusAccountingData(buffer, size);
|
||||||
} catch (...) {
|
} 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;
|
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::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||||
{
|
{
|
||||||
std::lock_guard Lock(WSServerMutex_);
|
std::lock_guard Lock(WSServerMutex_);
|
||||||
@@ -443,14 +472,18 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return DevicePtr->SendRadiusAuthenticationData(buffer,size);
|
return DevicePtr->SendRadiusAuthenticationData(buffer, size);
|
||||||
} catch (...) {
|
} 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;
|
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::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||||
{
|
{
|
||||||
std::lock_guard Lock(WSServerMutex_);
|
std::lock_guard Lock(WSServerMutex_);
|
||||||
@@ -462,11 +495,13 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return DevicePtr->SendRadiusCoAData(buffer,size);
|
return DevicePtr->SendRadiusCoAData(buffer, size);
|
||||||
} catch (...) {
|
} 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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
} //namespace
|
} // namespace OpenWifi
|
||||||
@@ -8,62 +8,59 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <mutex>
|
|
||||||
#include <thread>
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
#include <mutex>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
#include "Poco/AutoPtr.h"
|
#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/HTTPRequestHandler.h"
|
||||||
#include "Poco/Net/HTTPRequestHandlerFactory.h"
|
#include "Poco/Net/HTTPRequestHandlerFactory.h"
|
||||||
#include "Poco/Net/HTTPServer.h"
|
#include "Poco/Net/HTTPServer.h"
|
||||||
#include "Poco/Net/HTTPServerRequest.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_Connection.h"
|
||||||
#include "AP_WS_ReactorPool.h"
|
#include "AP_WS_ReactorPool.h"
|
||||||
|
|
||||||
#include "framework/utils.h"
|
|
||||||
#include "framework/SubSystemServer.h"
|
#include "framework/SubSystemServer.h"
|
||||||
|
#include "framework/utils.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
class AP_WS_RequestHandler : public Poco::Net::HTTPRequestHandler {
|
class AP_WS_RequestHandler : public Poco::Net::HTTPRequestHandler {
|
||||||
public:
|
public:
|
||||||
explicit AP_WS_RequestHandler(Poco::Logger &L, uint64_t id)
|
explicit AP_WS_RequestHandler(Poco::Logger &L, uint64_t id) : Logger_(L), id_(id){};
|
||||||
: Logger_(L),
|
|
||||||
id_(id){
|
|
||||||
};
|
|
||||||
|
|
||||||
void handleRequest(Poco::Net::HTTPServerRequest &request,
|
void handleRequest(Poco::Net::HTTPServerRequest &request,
|
||||||
Poco::Net::HTTPServerResponse &response) override;
|
Poco::Net::HTTPServerResponse &response) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Poco::Logger &Logger_;
|
Poco::Logger &Logger_;
|
||||||
uint64_t id_=0;
|
uint64_t id_ = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AP_WS_RequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
|
class AP_WS_RequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
|
||||||
public:
|
public:
|
||||||
inline explicit AP_WS_RequestHandlerFactory(Poco::Logger &L)
|
inline explicit AP_WS_RequestHandlerFactory(Poco::Logger &L) : Logger_(L) {}
|
||||||
: Logger_(L) {
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Poco::Net::HTTPRequestHandler *
|
inline Poco::Net::HTTPRequestHandler *
|
||||||
createRequestHandler(const Poco::Net::HTTPServerRequest &request) override {
|
createRequestHandler(const Poco::Net::HTTPServerRequest &request) override {
|
||||||
if (request.find("Upgrade") != request.end() &&
|
if (request.find("Upgrade") != request.end() &&
|
||||||
Poco::icompare(request["Upgrade"], "websocket") == 0) {
|
Poco::icompare(request["Upgrade"], "websocket") == 0) {
|
||||||
Utils::SetThreadName("ws:conn-init");
|
Utils::SetThreadName("ws:conn-init");
|
||||||
return new AP_WS_RequestHandler(Logger_,id_++);
|
return new AP_WS_RequestHandler(Logger_, id_++);
|
||||||
} else {
|
} else {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Poco::Logger &Logger_;
|
Poco::Logger &Logger_;
|
||||||
inline static uint64_t id_=1;
|
inline static uint64_t id_ = 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AP_WS_Server : public SubSystemServer {
|
class AP_WS_Server : public SubSystemServer {
|
||||||
@@ -75,37 +72,36 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
int Start() override;
|
int Start() override;
|
||||||
void Stop() override;
|
void Stop() override;
|
||||||
bool IsCertOk() { return IssuerCert_!= nullptr; }
|
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(); }
|
// Poco::Net::SocketReactor & GetNextReactor() { return ReactorPool_.NextReactor(); }
|
||||||
|
|
||||||
inline bool IsSimSerialNumber(const std::string & SerialNumber) const {
|
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) {
|
inline static bool IsSim(const std::string &SerialNumber) {
|
||||||
return SerialNumber.substr(0,6) == "53494d";
|
return SerialNumber.substr(0, 6) == "53494d";
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsSimEnabled() const {
|
inline bool IsSimEnabled() const { return SimulatorEnabled_; }
|
||||||
return SimulatorEnabled_;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool AllowSerialNumberMismatch() const {
|
inline bool AllowSerialNumberMismatch() const { return AllowSerialNumberMismatch_; }
|
||||||
return AllowSerialNumberMismatch_;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint64_t MismatchDepth() const {
|
inline uint64_t MismatchDepth() const { return MismatchDepth_; }
|
||||||
return MismatchDepth_;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool UseProvisioning() const { return LookAtProvisioning_; }
|
inline bool UseProvisioning() const { return LookAtProvisioning_; }
|
||||||
inline bool UseDefaults() const { return UseDefaultConfig_; }
|
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_; }
|
[[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_);
|
std::lock_guard Lock(WSServerMutex_);
|
||||||
Sessions_[session_id] = std::move(Connection);
|
Sessions_[session_id] = std::move(Connection);
|
||||||
}
|
}
|
||||||
@@ -114,58 +110,67 @@ namespace OpenWifi {
|
|||||||
std::lock_guard Lock(WSServerMutex_);
|
std::lock_guard Lock(WSServerMutex_);
|
||||||
|
|
||||||
auto Connection = Sessions_.find(session_id);
|
auto Connection = Sessions_.find(session_id);
|
||||||
if(Connection!=end(Sessions_))
|
if (Connection != end(Sessions_))
|
||||||
return Connection->second;
|
return Connection->second;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool GetStatistics(const std::string &SerialNumber, std::string & Statistics) const {
|
inline bool GetStatistics(const std::string &SerialNumber, std::string &Statistics) const {
|
||||||
return GetStatistics(Utils::SerialNumberToInt(SerialNumber),Statistics);
|
return GetStatistics(Utils::SerialNumberToInt(SerialNumber), Statistics);
|
||||||
}
|
}
|
||||||
bool GetStatistics(uint64_t SerialNumber, std::string & Statistics) const ;
|
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);
|
return GetState(Utils::SerialNumberToInt(SerialNumber), State);
|
||||||
}
|
}
|
||||||
bool GetState(uint64_t SerialNumber, GWObjects::ConnectionState & State) const;
|
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);
|
return GetHealthcheck(Utils::SerialNumberToInt(SerialNumber), CheckData);
|
||||||
}
|
}
|
||||||
bool GetHealthcheck(uint64_t SerialNumber, GWObjects::HealthCheck & CheckData) const ;
|
bool GetHealthcheck(uint64_t SerialNumber, GWObjects::HealthCheck &CheckData) const;
|
||||||
|
|
||||||
bool Connected(uint64_t SerialNumber, GWObjects::DeviceRestrictions & Restrictions) const ;
|
bool Connected(uint64_t SerialNumber, GWObjects::DeviceRestrictions &Restrictions) const;
|
||||||
bool Connected(uint64_t SerialNumber) const ;
|
bool Connected(uint64_t SerialNumber) const;
|
||||||
|
|
||||||
inline bool SendFrame(const std::string & SerialNumber, const std::string & Payload) const {
|
inline bool SendFrame(const std::string &SerialNumber, const std::string &Payload) const {
|
||||||
return SendFrame(Utils::SerialNumberToInt(SerialNumber), Payload);
|
return SendFrame(Utils::SerialNumberToInt(SerialNumber), Payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SendFrame(uint64_t SerialNumber, const std::string & Payload) const ;
|
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 SendRadiusAuthenticationData(const std::string &SerialNumber,
|
||||||
bool SendRadiusAccountingData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size);
|
const unsigned char *buffer, std::size_t size);
|
||||||
bool SendRadiusCoAData(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);
|
void SetSessionDetails(uint64_t connection_id, uint64_t SerialNumber);
|
||||||
bool EndSession(uint64_t connection_id, uint64_t serial_number);
|
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 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 StopKafkaTelemetry(uint64_t RPCID, uint64_t SerialNumber);
|
||||||
void GetTelemetryParameters(uint64_t SerialNumber , bool & TelemetryRunning,
|
void GetTelemetryParameters(uint64_t SerialNumber, bool &TelemetryRunning,
|
||||||
uint64_t & TelemetryInterval,
|
uint64_t &TelemetryInterval, uint64_t &TelemetryWebSocketTimer,
|
||||||
uint64_t & TelemetryWebSocketTimer,
|
uint64_t &TelemetryKafkaTimer,
|
||||||
uint64_t & TelemetryKafkaTimer,
|
uint64_t &TelemetryWebSocketCount,
|
||||||
uint64_t & TelemetryWebSocketCount,
|
uint64_t &TelemetryKafkaCount,
|
||||||
uint64_t & TelemetryKafkaCount,
|
uint64_t &TelemetryWebSocketPackets,
|
||||||
uint64_t & TelemetryWebSocketPackets,
|
uint64_t &TelemetryKafkaPackets);
|
||||||
uint64_t & TelemetryKafkaPackets);
|
|
||||||
|
|
||||||
void onGarbageCollecting(Poco::Timer & timer);
|
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_;
|
Connections = NumberOfConnectedDevices_;
|
||||||
AverageConnectionTime = AverageDeviceConnectionTime_;
|
AverageConnectionTime = AverageDeviceConnectionTime_;
|
||||||
NumberOfConnectingDevices = NumberOfConnectingDevices_;
|
NumberOfConnectingDevices = NumberOfConnectingDevices_;
|
||||||
@@ -181,18 +186,18 @@ namespace OpenWifi {
|
|||||||
Poco::ThreadPool DeviceConnectionPool_{"ws:dev-pool", 2, 64};
|
Poco::ThreadPool DeviceConnectionPool_{"ws:dev-pool", 2, 64};
|
||||||
bool LookAtProvisioning_ = false;
|
bool LookAtProvisioning_ = false;
|
||||||
bool UseDefaultConfig_ = true;
|
bool UseDefaultConfig_ = true;
|
||||||
bool SimulatorEnabled_=false;
|
bool SimulatorEnabled_ = false;
|
||||||
std::unique_ptr<AP_WS_ReactorThreadPool> Reactor_pool_;
|
std::unique_ptr<AP_WS_ReactorThreadPool> Reactor_pool_;
|
||||||
std::atomic_bool Running_=false;
|
std::atomic_bool Running_ = false;
|
||||||
// std::map<uint64_t, std::pair<std::shared_ptr<AP_WS_Connection>,bool>> Sessions_;
|
// std::map<uint64_t, std::pair<std::shared_ptr<AP_WS_Connection>,bool>> Sessions_;
|
||||||
std::map<std::uint64_t, std::shared_ptr<AP_WS_Connection>> Sessions_;
|
std::map<std::uint64_t, std::shared_ptr<AP_WS_Connection>> Sessions_;
|
||||||
std::map<uint64_t, std::pair<uint64_t,std::shared_ptr<AP_WS_Connection>>> SerialNumbers_;
|
std::map<uint64_t, std::pair<uint64_t, std::shared_ptr<AP_WS_Connection>>> SerialNumbers_;
|
||||||
std::atomic_bool AllowSerialNumberMismatch_=true;
|
std::atomic_bool AllowSerialNumberMismatch_ = true;
|
||||||
std::atomic_uint64_t MismatchDepth_=2;
|
std::atomic_uint64_t MismatchDepth_ = 2;
|
||||||
|
|
||||||
std::atomic_uint64_t NumberOfConnectedDevices_=0;
|
std::atomic_uint64_t NumberOfConnectedDevices_ = 0;
|
||||||
std::atomic_uint64_t AverageDeviceConnectionTime_=0;
|
std::atomic_uint64_t AverageDeviceConnectionTime_ = 0;
|
||||||
std::atomic_uint64_t NumberOfConnectingDevices_=0;
|
std::atomic_uint64_t NumberOfConnectingDevices_ = 0;
|
||||||
|
|
||||||
std::vector<std::shared_ptr<AP_WS_Connection>> Garbage_;
|
std::vector<std::shared_ptr<AP_WS_Connection>> Garbage_;
|
||||||
|
|
||||||
@@ -200,11 +205,10 @@ namespace OpenWifi {
|
|||||||
Poco::Timer Timer_;
|
Poco::Timer Timer_;
|
||||||
Poco::Thread GarbageCollector_;
|
Poco::Thread GarbageCollector_;
|
||||||
|
|
||||||
AP_WS_Server() noexcept:
|
AP_WS_Server() noexcept
|
||||||
SubSystemServer("WebSocketServer", "WS-SVR", "ucentral.websocket") {
|
: SubSystemServer("WebSocketServer", "WS-SVR", "ucentral.websocket") {}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline auto AP_WS_Server() { return AP_WS_Server::instance(); }
|
inline auto AP_WS_Server() { return AP_WS_Server::instance(); }
|
||||||
|
|
||||||
} //namespace
|
} // namespace OpenWifi
|
||||||
@@ -4,52 +4,51 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <fstream>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <fstream>
|
#include <string>
|
||||||
|
|
||||||
#include "framework/MicroServiceFuncs.h"
|
#include "framework/MicroServiceFuncs.h"
|
||||||
|
|
||||||
#include "nlohmann/json.hpp"
|
|
||||||
#include "CentralConfig.h"
|
#include "CentralConfig.h"
|
||||||
|
#include "nlohmann/json.hpp"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
const std::string PlatformCacheFileName{"/plat_cache.json"};
|
const std::string PlatformCacheFileName{"/plat_cache.json"};
|
||||||
const std::string CapabilitiesCacheFileName{"/caps_cache.json"};
|
const std::string CapabilitiesCacheFileName{"/caps_cache.json"};
|
||||||
|
|
||||||
typedef std::map<std::string,nlohmann::json> CapabilitiesCache_t;
|
typedef std::map<std::string, nlohmann::json> CapabilitiesCache_t;
|
||||||
|
|
||||||
class CapabilitiesCache {
|
class CapabilitiesCache {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static auto instance() {
|
static auto instance() {
|
||||||
static auto instance = new CapabilitiesCache;
|
static auto instance = new CapabilitiesCache;
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Add(const Config::Capabilities &Caps) {
|
inline void Add(const Config::Capabilities &Caps) {
|
||||||
if(Caps.Compatible().empty() || Caps.Platform().empty())
|
if (Caps.Compatible().empty() || Caps.Platform().empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::lock_guard G(Mutex_);
|
std::lock_guard G(Mutex_);
|
||||||
if(!PlatformsLoaded_)
|
if (!PlatformsLoaded_)
|
||||||
LoadPlatforms();
|
LoadPlatforms();
|
||||||
auto P = Poco::toUpper(Caps.Platform());
|
auto P = Poco::toUpper(Caps.Platform());
|
||||||
auto Hint = Platforms_.find(Caps.Compatible());
|
auto Hint = Platforms_.find(Caps.Compatible());
|
||||||
if(Hint==Platforms_.end()) {
|
if (Hint == Platforms_.end()) {
|
||||||
Platforms_.insert(std::make_pair(Caps.Compatible(),P));
|
Platforms_.insert(std::make_pair(Caps.Compatible(), P));
|
||||||
SavePlatforms();
|
SavePlatforms();
|
||||||
} else if(Hint->second != P) {
|
} else if (Hint->second != P) {
|
||||||
Hint->second = P;
|
Hint->second = P;
|
||||||
SavePlatforms();
|
SavePlatforms();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!CapabilitiesLoaded_)
|
if (!CapabilitiesLoaded_)
|
||||||
LoadCapabilities();
|
LoadCapabilities();
|
||||||
|
|
||||||
auto CapHint = Capabilities_.find(Caps.Compatible());
|
auto CapHint = Capabilities_.find(Caps.Compatible());
|
||||||
if(CapHint==Capabilities_.end()) {
|
if (CapHint == Capabilities_.end()) {
|
||||||
auto C = nlohmann::json::parse(Caps.AsString());
|
auto C = nlohmann::json::parse(Caps.AsString());
|
||||||
C.erase("restrictions");
|
C.erase("restrictions");
|
||||||
Capabilities_[Caps.Compatible()] = nlohmann::json::parse(Caps.AsString());
|
Capabilities_[Caps.Compatible()] = nlohmann::json::parse(Caps.AsString());
|
||||||
@@ -60,35 +59,35 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string GetPlatform(const std::string & DeviceType) {
|
inline std::string GetPlatform(const std::string &DeviceType) {
|
||||||
std::lock_guard G(Mutex_);
|
std::lock_guard G(Mutex_);
|
||||||
|
|
||||||
if(!PlatformsLoaded_) {
|
if (!PlatformsLoaded_) {
|
||||||
LoadPlatforms();
|
LoadPlatforms();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Hint = Platforms_.find(DeviceType);
|
auto Hint = Platforms_.find(DeviceType);
|
||||||
if(Hint==Platforms_.end())
|
if (Hint == Platforms_.end())
|
||||||
return "AP";
|
return "AP";
|
||||||
return Hint->second;
|
return Hint->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline nlohmann::json GetCapabilities(const std::string & DeviceType) {
|
inline nlohmann::json GetCapabilities(const std::string &DeviceType) {
|
||||||
std::lock_guard G(Mutex_);
|
std::lock_guard G(Mutex_);
|
||||||
|
|
||||||
if(!CapabilitiesLoaded_) {
|
if (!CapabilitiesLoaded_) {
|
||||||
LoadCapabilities();
|
LoadCapabilities();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Hint = Capabilities_.find(DeviceType);
|
auto Hint = Capabilities_.find(DeviceType);
|
||||||
if(Hint==Capabilities_.end())
|
if (Hint == Capabilities_.end())
|
||||||
return nlohmann::json{};
|
return nlohmann::json{};
|
||||||
return Hint->second;
|
return Hint->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const CapabilitiesCache_t & AllCapabilities() {
|
inline const CapabilitiesCache_t &AllCapabilities() {
|
||||||
std::lock_guard G(Mutex_);
|
std::lock_guard G(Mutex_);
|
||||||
if(!CapabilitiesLoaded_) {
|
if (!CapabilitiesLoaded_) {
|
||||||
LoadCapabilities();
|
LoadCapabilities();
|
||||||
}
|
}
|
||||||
return Capabilities_;
|
return Capabilities_;
|
||||||
@@ -96,12 +95,13 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::recursive_mutex Mutex_;
|
std::recursive_mutex Mutex_;
|
||||||
std::atomic_bool PlatformsLoaded_=false;
|
std::atomic_bool PlatformsLoaded_ = false;
|
||||||
std::atomic_bool CapabilitiesLoaded_=false;
|
std::atomic_bool CapabilitiesLoaded_ = false;
|
||||||
std::map<std::string,std::string> Platforms_;
|
std::map<std::string, std::string> Platforms_;
|
||||||
CapabilitiesCache_t Capabilities_;
|
CapabilitiesCache_t Capabilities_;
|
||||||
std::string PlatformCacheFileName_{ MicroServiceDataDirectory()+PlatformCacheFileName };
|
std::string PlatformCacheFileName_{MicroServiceDataDirectory() + PlatformCacheFileName};
|
||||||
std::string CapabilitiesCacheFileName_{ MicroServiceDataDirectory()+CapabilitiesCacheFileName };
|
std::string CapabilitiesCacheFileName_{MicroServiceDataDirectory() +
|
||||||
|
CapabilitiesCacheFileName};
|
||||||
|
|
||||||
inline void LoadPlatforms() {
|
inline void LoadPlatforms() {
|
||||||
try {
|
try {
|
||||||
@@ -109,11 +109,10 @@ namespace OpenWifi {
|
|||||||
nlohmann::json cache;
|
nlohmann::json cache;
|
||||||
i >> cache;
|
i >> cache;
|
||||||
|
|
||||||
for(const auto &[Type,Platform]:cache.items()) {
|
for (const auto &[Type, Platform] : cache.items()) {
|
||||||
Platforms_[Type] = Platform;
|
Platforms_[Type] = Platform;
|
||||||
}
|
}
|
||||||
} catch(...) {
|
} catch (...) {
|
||||||
|
|
||||||
}
|
}
|
||||||
PlatformsLoaded_ = true;
|
PlatformsLoaded_ = true;
|
||||||
}
|
}
|
||||||
@@ -124,36 +123,35 @@ namespace OpenWifi {
|
|||||||
nlohmann::json cache(Platforms_);
|
nlohmann::json cache(Platforms_);
|
||||||
i << cache;
|
i << cache;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void LoadCapabilities() {
|
inline void LoadCapabilities() {
|
||||||
try {
|
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;
|
nlohmann::json cache;
|
||||||
i >> cache;
|
i >> cache;
|
||||||
|
|
||||||
for(const auto &[Type,Caps]:cache.items()) {
|
for (const auto &[Type, Caps] : cache.items()) {
|
||||||
Capabilities_[Type] = Caps;
|
Capabilities_[Type] = Caps;
|
||||||
}
|
}
|
||||||
} catch(...) {
|
} catch (...) {
|
||||||
|
|
||||||
}
|
}
|
||||||
CapabilitiesLoaded_ = true;
|
CapabilitiesLoaded_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void SaveCapabilities() {
|
inline void SaveCapabilities() {
|
||||||
try {
|
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_);
|
nlohmann::json cache(Capabilities_);
|
||||||
i << cache;
|
i << cache;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline auto CapabilitiesCache() { return CapabilitiesCache::instance(); };
|
inline auto CapabilitiesCache() { return CapabilitiesCache::instance(); };
|
||||||
|
|
||||||
}
|
} // namespace OpenWifi
|
||||||
@@ -7,17 +7,17 @@
|
|||||||
//
|
//
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
|
#include "Poco/File.h"
|
||||||
#include "Poco/JSON/Object.h"
|
#include "Poco/JSON/Object.h"
|
||||||
#include "Poco/JSON/Parser.h"
|
#include "Poco/JSON/Parser.h"
|
||||||
#include "Poco/File.h"
|
|
||||||
|
|
||||||
#include "CentralConfig.h"
|
#include "CentralConfig.h"
|
||||||
#include "Daemon.h"
|
#include "Daemon.h"
|
||||||
|
|
||||||
namespace OpenWifi::Config {
|
namespace OpenWifi::Config {
|
||||||
|
|
||||||
const static std::string BasicConfig {
|
const static std::string BasicConfig{
|
||||||
R"lit(
|
R"lit(
|
||||||
{
|
{
|
||||||
"interfaces": [
|
"interfaces": [
|
||||||
{
|
{
|
||||||
@@ -150,9 +150,10 @@ R"lit(
|
|||||||
|
|
||||||
void Config::SetBasicConfigFile() {
|
void Config::SetBasicConfigFile() {
|
||||||
try {
|
try {
|
||||||
Poco::File DefaultConfigFileName{MicroService::instance().DataDir() + "/default_config.json"};
|
Poco::File DefaultConfigFileName{MicroService::instance().DataDir() +
|
||||||
|
"/default_config.json"};
|
||||||
DefaultConfiguration_ = BasicConfig;
|
DefaultConfiguration_ = BasicConfig;
|
||||||
std::ofstream OS(DefaultConfigFileName.path(), std::ios::binary | std::ios::trunc );
|
std::ofstream OS(DefaultConfigFileName.path(), std::ios::binary | std::ios::trunc);
|
||||||
std::istringstream IS(DefaultConfiguration_);
|
std::istringstream IS(DefaultConfiguration_);
|
||||||
Poco::StreamCopier::copyStream(IS, OS);
|
Poco::StreamCopier::copyStream(IS, OS);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
@@ -161,22 +162,23 @@ R"lit(
|
|||||||
}
|
}
|
||||||
|
|
||||||
Config::Config() {
|
Config::Config() {
|
||||||
if(DefaultConfiguration_.empty())
|
if (DefaultConfiguration_.empty())
|
||||||
Init();
|
Init();
|
||||||
Config_ = DefaultConfiguration_;
|
Config_ = DefaultConfiguration_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Config::Init() {
|
void Config::Init() {
|
||||||
if(DefaultConfiguration_.empty()) {
|
if (DefaultConfiguration_.empty()) {
|
||||||
// open the file
|
// open the file
|
||||||
try {
|
try {
|
||||||
Poco::File DefaultConfigFileName{MicroService::instance().DataDir()+"/default_config.json"};
|
Poco::File DefaultConfigFileName{MicroService::instance().DataDir() +
|
||||||
|
"/default_config.json"};
|
||||||
if (!DefaultConfigFileName.exists()) {
|
if (!DefaultConfigFileName.exists()) {
|
||||||
SetBasicConfigFile();
|
SetBasicConfigFile();
|
||||||
} else {
|
} else {
|
||||||
std::ifstream F(DefaultConfigFileName.path(),std::ios::binary | std::ios::in);
|
std::ifstream F(DefaultConfigFileName.path(), std::ios::binary | std::ios::in);
|
||||||
std::ostringstream C;
|
std::ostringstream C;
|
||||||
Poco::StreamCopier::copyStream(F,C);
|
Poco::StreamCopier::copyStream(F, C);
|
||||||
DefaultConfiguration_ = C.str();
|
DefaultConfiguration_ = C.str();
|
||||||
}
|
}
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
@@ -195,10 +197,9 @@ R"lit(
|
|||||||
Stringifier.condense(Object, NewConfig);
|
Stringifier.condense(Object, NewConfig);
|
||||||
Config_ = NewConfig.str();
|
Config_ = NewConfig.str();
|
||||||
return true;
|
return true;
|
||||||
}
|
} catch (const Poco::Exception &E) {
|
||||||
catch(const Poco::Exception &E)
|
std::cout << __func__ << ": new Configuration failed with " << E.displayText()
|
||||||
{
|
<< std::endl;
|
||||||
std::cout << __func__ << ": new Configuration failed with " << E.displayText() << std::endl;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -207,12 +208,10 @@ R"lit(
|
|||||||
try {
|
try {
|
||||||
Poco::JSON::Parser Parser;
|
Poco::JSON::Parser Parser;
|
||||||
auto object = Parser.parse(Config_).extract<Poco::JSON::Object::Ptr>();
|
auto object = Parser.parse(Config_).extract<Poco::JSON::Object::Ptr>();
|
||||||
if(object->has("uuid"))
|
if (object->has("uuid"))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
} catch (...) {
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -223,13 +222,14 @@ R"lit(
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string Config::Default() {
|
std::string Config::Default() {
|
||||||
if(DefaultConfiguration_.empty())
|
if (DefaultConfiguration_.empty())
|
||||||
Init();
|
Init();
|
||||||
return DefaultConfiguration_;
|
return DefaultConfiguration_;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* std::string Capabilities::Default() {
|
/* 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"}},
|
"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,
|
"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"}],
|
"want_untag":true},{"num":1,"role":"lan"},{"num":2,"role":"lan"},{"num":3,"role":"lan"},{"num":4,"role":"lan"}],
|
||||||
@@ -242,44 +242,34 @@ R"lit(
|
|||||||
"platform/soc/a800000.wifi":{"band":["5l"],"ht_capa":6639,"vht_capa":865687986,"htmode":["HT20","HT40","VHT20","VHT40","VHT80"],
|
"platform/soc/a800000.wifi":{"band":["5l"],"ht_capa":6639,"vht_capa":865687986,"htmode":["HT20","HT40","VHT20","VHT40","VHT80"],
|
||||||
"tx_ant":3,"rx_ant":3,"channels":[36,40,44,48,52,56,60,64]}}})lit");
|
"tx_ant":3,"rx_ant":3,"channels":[36,40,44,48,52,56,60,64]}}})lit");
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Capabilities::Capabilities(const Poco::JSON::Object::Ptr &Caps) {
|
Capabilities::Capabilities(const Poco::JSON::Object::Ptr &Caps) {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
if(Caps->has("compatible"))
|
if (Caps->has("compatible"))
|
||||||
Compatible_ = Caps->get("compatible").toString();
|
Compatible_ = Caps->get("compatible").toString();
|
||||||
|
|
||||||
if(Caps->has("model"))
|
if (Caps->has("model"))
|
||||||
Model_ = Caps->get("model").toString();
|
Model_ = Caps->get("model").toString();
|
||||||
|
|
||||||
if(Caps->has("platform"))
|
if (Caps->has("platform"))
|
||||||
Platform_ = Caps->get("platform").toString();
|
Platform_ = Caps->get("platform").toString();
|
||||||
|
|
||||||
std::ostringstream OS;
|
std::ostringstream OS;
|
||||||
Caps->stringify(OS);
|
Caps->stringify(OS);
|
||||||
AsString_ = OS.str();
|
AsString_ = OS.str();
|
||||||
}
|
} catch (const Poco::Exception &E) {
|
||||||
catch ( const Poco::Exception & E )
|
|
||||||
{
|
|
||||||
Daemon()->logger().log(E);
|
Daemon()->logger().log(E);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string & Capabilities::Compatible() const {
|
const std::string &Capabilities::Compatible() const { return Compatible_; }
|
||||||
return Compatible_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string & Capabilities::Model() const {
|
const std::string &Capabilities::Model() const { return Model_; }
|
||||||
return Model_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string & Capabilities::Platform() const {
|
const std::string &Capabilities::Platform() const { return Platform_; }
|
||||||
return Platform_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string & Capabilities::AsString() const {
|
const std::string &Capabilities::AsString() const { return AsString_; }
|
||||||
return AsString_;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace OpenWifi::Config
|
||||||
|
|||||||
@@ -8,16 +8,14 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include "Poco/JSON/Object.h"
|
#include "Poco/JSON/Object.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace OpenWifi::Config {
|
namespace OpenWifi::Config {
|
||||||
|
|
||||||
class Config {
|
class Config {
|
||||||
public:
|
public:
|
||||||
explicit Config(const std::string &Config)
|
explicit Config(const std::string &Config) : Config_(Config) {}
|
||||||
:Config_(Config) {
|
|
||||||
}
|
|
||||||
|
|
||||||
Config();
|
Config();
|
||||||
bool SetUUID(uint64_t UUID);
|
bool SetUUID(uint64_t UUID);
|
||||||
@@ -37,7 +35,7 @@ namespace OpenWifi::Config {
|
|||||||
public:
|
public:
|
||||||
explicit Capabilities(const Poco::JSON::Object::Ptr &Caps);
|
explicit Capabilities(const Poco::JSON::Object::Ptr &Caps);
|
||||||
|
|
||||||
/* Capabilities()
|
/* Capabilities()
|
||||||
{
|
{
|
||||||
Capabilities_ = Default();
|
Capabilities_ = Default();
|
||||||
}
|
}
|
||||||
@@ -45,12 +43,12 @@ namespace OpenWifi::Config {
|
|||||||
static std::string Default();
|
static std::string Default();
|
||||||
|
|
||||||
[[nodiscard]] const std::string & Get() const { return Capabilities_; };
|
[[nodiscard]] const std::string & Get() const { return Capabilities_; };
|
||||||
*/
|
*/
|
||||||
|
|
||||||
[[nodiscard]] const std::string & Compatible() const;
|
[[nodiscard]] const std::string &Compatible() const;
|
||||||
[[nodiscard]] const std::string & Model() const;
|
[[nodiscard]] const std::string &Model() const;
|
||||||
[[nodiscard]] const std::string & Platform() const;
|
[[nodiscard]] const std::string &Platform() const;
|
||||||
[[nodiscard]] const std::string & AsString() const;
|
[[nodiscard]] const std::string &AsString() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string Compatible_;
|
std::string Compatible_;
|
||||||
@@ -61,5 +59,4 @@ namespace OpenWifi::Config {
|
|||||||
void Parse();
|
void Parse();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace OpenWifi::Config
|
||||||
|
|
||||||
|
|||||||
@@ -10,11 +10,11 @@
|
|||||||
|
|
||||||
#include "Poco/JSON/Parser.h"
|
#include "Poco/JSON/Parser.h"
|
||||||
|
|
||||||
#include "CommandManager.h"
|
|
||||||
#include "AP_WS_Server.h"
|
#include "AP_WS_Server.h"
|
||||||
|
#include "CommandManager.h"
|
||||||
#include "StorageService.h"
|
#include "StorageService.h"
|
||||||
#include "framework/ow_constants.h"
|
|
||||||
#include "framework/MicroServiceFuncs.h"
|
#include "framework/MicroServiceFuncs.h"
|
||||||
|
#include "framework/ow_constants.h"
|
||||||
#include "framework/utils.h"
|
#include "framework/utils.h"
|
||||||
|
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
@@ -35,43 +35,50 @@ namespace OpenWifi {
|
|||||||
std::string SerialNumberStr = Utils::IntToSerialNumber(Resp->SerialNumber_);
|
std::string SerialNumberStr = Utils::IntToSerialNumber(Resp->SerialNumber_);
|
||||||
|
|
||||||
if (!Payload->has(uCentralProtocol::ID)) {
|
if (!Payload->has(uCentralProtocol::ID)) {
|
||||||
poco_error(Logger(), fmt::format("({}): Invalid RPC response.", SerialNumberStr));
|
poco_error(Logger(),
|
||||||
|
fmt::format("({}): Invalid RPC response.", SerialNumberStr));
|
||||||
} else {
|
} else {
|
||||||
uint64_t ID = Payload->get(uCentralProtocol::ID);
|
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) {
|
if (ID > 1) {
|
||||||
std::lock_guard Lock(LocalMutex_);
|
std::lock_guard Lock(LocalMutex_);
|
||||||
auto RPC = OutStandingRequests_.find(ID);
|
auto RPC = OutStandingRequests_.find(ID);
|
||||||
if (RPC == OutStandingRequests_.end()) {
|
if (RPC == OutStandingRequests_.end()) {
|
||||||
// std::cout << __LINE__ << std::endl;
|
// std::cout << __LINE__ << std::endl;
|
||||||
poco_debug(Logger(),
|
poco_debug(Logger(), fmt::format("({}): RPC {} cannot be found.",
|
||||||
fmt::format("({}): RPC {} cannot be found.", SerialNumberStr, ID));
|
SerialNumberStr, ID));
|
||||||
} else if(RPC->second.SerialNumber != Resp->SerialNumber_) {
|
} else if (RPC->second.SerialNumber != Resp->SerialNumber_) {
|
||||||
// std::cout << __LINE__ << std::endl;
|
// std::cout << __LINE__ << std::endl;
|
||||||
poco_debug(Logger(),
|
poco_debug(
|
||||||
fmt::format("({}): RPC {} serial number mismatch {}!={}.", SerialNumberStr, ID, RPC->second.SerialNumber, Resp->SerialNumber_));
|
Logger(),
|
||||||
|
fmt::format("({}): RPC {} serial number mismatch {}!={}.",
|
||||||
|
SerialNumberStr, ID, RPC->second.SerialNumber,
|
||||||
|
Resp->SerialNumber_));
|
||||||
} else {
|
} else {
|
||||||
std::shared_ptr<promise_type_t> TmpRpcEntry;
|
std::shared_ptr<promise_type_t> TmpRpcEntry;
|
||||||
std::chrono::duration<double, std::milli> rpc_execution_time =
|
std::chrono::duration<double, std::milli> rpc_execution_time =
|
||||||
std::chrono::high_resolution_clock::now() -
|
std::chrono::high_resolution_clock::now() -
|
||||||
RPC->second.submitted;
|
RPC->second.submitted;
|
||||||
// std::cout << __LINE__ << std::endl;
|
// std::cout << __LINE__ << std::endl;
|
||||||
poco_debug(Logger(),
|
poco_debug(Logger(),
|
||||||
fmt::format("({}): Received RPC answer {}. Command={}",
|
fmt::format("({}): Received RPC answer {}. Command={}",
|
||||||
SerialNumberStr, ID, APCommands::to_string(RPC->second.Command)));
|
SerialNumberStr, ID,
|
||||||
if(RPC->second.Command==APCommands::Commands::script) {
|
APCommands::to_string(RPC->second.Command)));
|
||||||
|
if (RPC->second.Command == APCommands::Commands::script) {
|
||||||
CompleteScriptCommand(RPC->second, Payload, rpc_execution_time);
|
CompleteScriptCommand(RPC->second, Payload, rpc_execution_time);
|
||||||
} else if(RPC->second.Command!=APCommands::Commands::telemetry) {
|
} else if (RPC->second.Command != APCommands::Commands::telemetry) {
|
||||||
CompleteTelemetryCommand(RPC->second, Payload, rpc_execution_time);
|
CompleteTelemetryCommand(RPC->second, Payload,
|
||||||
|
rpc_execution_time);
|
||||||
} else {
|
} else {
|
||||||
StorageService()->CommandCompleted(
|
StorageService()->CommandCompleted(RPC->second.UUID, Payload,
|
||||||
RPC->second.UUID, Payload, rpc_execution_time, true);
|
rpc_execution_time, true);
|
||||||
if (RPC->second.rpc_entry) {
|
if (RPC->second.rpc_entry) {
|
||||||
TmpRpcEntry = RPC->second.rpc_entry;
|
TmpRpcEntry = RPC->second.rpc_entry;
|
||||||
}
|
}
|
||||||
RPC->second.State = 0 ;
|
RPC->second.State = 0;
|
||||||
OutStandingRequests_.erase(ID);
|
OutStandingRequests_.erase(ID);
|
||||||
if(TmpRpcEntry != nullptr)
|
if (TmpRpcEntry != nullptr)
|
||||||
TmpRpcEntry->set_value(Payload);
|
TmpRpcEntry->set_value(Payload);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -81,14 +88,16 @@ namespace OpenWifi {
|
|||||||
} catch (const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
Logger().log(E);
|
Logger().log(E);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
poco_warning(Logger(),"Exception occurred during run.");
|
poco_warning(Logger(), "Exception occurred during run.");
|
||||||
}
|
}
|
||||||
NextMsg = ResponseQueue_.waitDequeueNotification();
|
NextMsg = ResponseQueue_.waitDequeueNotification();
|
||||||
}
|
}
|
||||||
poco_information(Logger(),"RPC Command processor stopping.");
|
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;
|
std::shared_ptr<promise_type_t> TmpRpcEntry;
|
||||||
|
|
||||||
StorageService()->CommandCompleted(Command.UUID, Payload, rpc_execution_time, true);
|
StorageService()->CommandCompleted(Command.UUID, Payload, rpc_execution_time, true);
|
||||||
@@ -96,23 +105,25 @@ namespace OpenWifi {
|
|||||||
if (Command.rpc_entry) {
|
if (Command.rpc_entry) {
|
||||||
TmpRpcEntry = Command.rpc_entry;
|
TmpRpcEntry = Command.rpc_entry;
|
||||||
}
|
}
|
||||||
Command.State = 0 ;
|
Command.State = 0;
|
||||||
|
|
||||||
OutStandingRequests_.erase(Command.Id);
|
OutStandingRequests_.erase(Command.Id);
|
||||||
if(TmpRpcEntry != nullptr)
|
if (TmpRpcEntry != nullptr)
|
||||||
TmpRpcEntry->set_value(Payload);
|
TmpRpcEntry->set_value(Payload);
|
||||||
return true;
|
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;
|
bool Reply = true;
|
||||||
std::shared_ptr<promise_type_t> TmpRpcEntry;
|
std::shared_ptr<promise_type_t> TmpRpcEntry;
|
||||||
|
|
||||||
if (Command.rpc_entry) {
|
if (Command.rpc_entry) {
|
||||||
TmpRpcEntry = Command.rpc_entry;
|
TmpRpcEntry = Command.rpc_entry;
|
||||||
}
|
}
|
||||||
// std::cout << __LINE__ << " State=" << Command.State << std::endl;
|
// std::cout << __LINE__ << " State=" << Command.State << std::endl;
|
||||||
if(Command.State==2) {
|
if (Command.State == 2) {
|
||||||
// look at the payload to see if we should continue or not...
|
// look at the payload to see if we should continue or not...
|
||||||
if (Payload->has("result")) {
|
if (Payload->has("result")) {
|
||||||
auto Result = Payload->getObject("result");
|
auto Result = Payload->getObject("result");
|
||||||
@@ -120,45 +131,47 @@ namespace OpenWifi {
|
|||||||
auto Status = Result->getObject("status");
|
auto Status = Result->getObject("status");
|
||||||
|
|
||||||
std::uint64_t Error = Status->get("error");
|
std::uint64_t Error = Status->get("error");
|
||||||
if(Error==0) {
|
if (Error == 0) {
|
||||||
// std::cout << __LINE__ << std::endl;
|
// std::cout << __LINE__ << std::endl;
|
||||||
StorageService()->CommandCompleted(Command.UUID, Payload, rpc_execution_time, true);
|
StorageService()->CommandCompleted(Command.UUID, Payload,
|
||||||
Command.State = 1 ;
|
rpc_execution_time, true);
|
||||||
|
Command.State = 1;
|
||||||
} else {
|
} else {
|
||||||
// std::cout << __LINE__ << std::endl;
|
// 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");
|
std::string ErrorTxt = Status->get("result");
|
||||||
StorageService()->CancelWaitFile(Command.UUID, ErrorTxt);
|
StorageService()->CancelWaitFile(Command.UUID, ErrorTxt);
|
||||||
Command.State = 0 ;
|
Command.State = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// std::cout << __LINE__ << std::endl;
|
// std::cout << __LINE__ << std::endl;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// std::cout << __LINE__ << std::endl;
|
// std::cout << __LINE__ << std::endl;
|
||||||
Command.State=0;
|
Command.State = 0;
|
||||||
}
|
}
|
||||||
} else if (Command.State==1) {
|
} else if (Command.State == 1) {
|
||||||
// std::cout << "Completing script 2 phase commit." << std::endl;
|
// std::cout << "Completing script 2 phase commit." << std::endl;
|
||||||
StorageService()->CommandCompleted(Command.UUID, Payload, rpc_execution_time, true);
|
StorageService()->CommandCompleted(Command.UUID, Payload, rpc_execution_time, true);
|
||||||
if(Command.Deferred) {
|
if (Command.Deferred) {
|
||||||
Reply = false;
|
Reply = false;
|
||||||
}
|
}
|
||||||
Command.State=0;
|
Command.State = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Command.State==0) {
|
if (Command.State == 0) {
|
||||||
// std::cout << __LINE__ << " State=" << Command.State << std::endl;
|
// std::cout << __LINE__ << " State=" << Command.State << std::endl;
|
||||||
OutStandingRequests_.erase(Command.Id);
|
OutStandingRequests_.erase(Command.Id);
|
||||||
}
|
}
|
||||||
if(Reply && TmpRpcEntry != nullptr)
|
if (Reply && TmpRpcEntry != nullptr)
|
||||||
TmpRpcEntry->set_value(Payload);
|
TmpRpcEntry->set_value(Payload);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CommandManager::Start() {
|
int CommandManager::Start() {
|
||||||
poco_notice(Logger(),"Starting...");
|
poco_notice(Logger(), "Starting...");
|
||||||
|
|
||||||
commandTimeOut_ = MicroServiceConfigGetInt("command.timeout", 4 * 60 * 60);
|
commandTimeOut_ = MicroServiceConfigGetInt("command.timeout", 4 * 60 * 60);
|
||||||
commandRetry_ = MicroServiceConfigGetInt("command.retry", 120);
|
commandRetry_ = MicroServiceConfigGetInt("command.retry", 120);
|
||||||
@@ -167,13 +180,15 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
ManagerThread.start(*this);
|
ManagerThread.start(*this);
|
||||||
|
|
||||||
JanitorCallback_ = std::make_unique<Poco::TimerCallback<CommandManager>>(*this,&CommandManager::onJanitorTimer);
|
JanitorCallback_ = std::make_unique<Poco::TimerCallback<CommandManager>>(
|
||||||
JanitorTimer_.setStartInterval( 10000 );
|
*this, &CommandManager::onJanitorTimer);
|
||||||
JanitorTimer_.setPeriodicInterval(janitorInterval_* 1000); // 1 hours
|
JanitorTimer_.setStartInterval(10000);
|
||||||
|
JanitorTimer_.setPeriodicInterval(janitorInterval_ * 1000); // 1 hours
|
||||||
JanitorTimer_.start(*JanitorCallback_, MicroServiceTimerPool());
|
JanitorTimer_.start(*JanitorCallback_, MicroServiceTimerPool());
|
||||||
|
|
||||||
CommandRunnerCallback_ = std::make_unique<Poco::TimerCallback<CommandManager>>(*this,&CommandManager::onCommandRunnerTimer);
|
CommandRunnerCallback_ = std::make_unique<Poco::TimerCallback<CommandManager>>(
|
||||||
CommandRunnerTimer_.setStartInterval( 10000 );
|
*this, &CommandManager::onCommandRunnerTimer);
|
||||||
|
CommandRunnerTimer_.setStartInterval(10000);
|
||||||
CommandRunnerTimer_.setPeriodicInterval(queueInterval_ * 1000); // 1 hours
|
CommandRunnerTimer_.setPeriodicInterval(queueInterval_ * 1000); // 1 hours
|
||||||
CommandRunnerTimer_.start(*CommandRunnerCallback_, MicroServiceTimerPool());
|
CommandRunnerTimer_.start(*CommandRunnerCallback_, MicroServiceTimerPool());
|
||||||
|
|
||||||
@@ -181,44 +196,46 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CommandManager::Stop() {
|
void CommandManager::Stop() {
|
||||||
poco_notice(Logger(),"Stopping...");
|
poco_notice(Logger(), "Stopping...");
|
||||||
Running_ = false;
|
Running_ = false;
|
||||||
JanitorTimer_.stop();
|
JanitorTimer_.stop();
|
||||||
CommandRunnerTimer_.stop();
|
CommandRunnerTimer_.stop();
|
||||||
ResponseQueue_.wakeUpAll();
|
ResponseQueue_.wakeUpAll();
|
||||||
ManagerThread.wakeUp();
|
ManagerThread.wakeUp();
|
||||||
ManagerThread.join();
|
ManagerThread.join();
|
||||||
poco_notice(Logger(),"Stopped...");
|
poco_notice(Logger(), "Stopped...");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandManager::WakeUp() {
|
void CommandManager::WakeUp() {
|
||||||
poco_notice(Logger(),"Waking up...");
|
poco_notice(Logger(), "Waking up...");
|
||||||
ManagerThread.wakeUp();
|
ManagerThread.wakeUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandManager::onJanitorTimer([[maybe_unused]] Poco::Timer & timer) {
|
void CommandManager::onJanitorTimer([[maybe_unused]] Poco::Timer &timer) {
|
||||||
std::lock_guard Lock(LocalMutex_);
|
std::lock_guard Lock(LocalMutex_);
|
||||||
Utils::SetThreadName("cmd:janitor");
|
Utils::SetThreadName("cmd:janitor");
|
||||||
Poco::Logger & MyLogger = Poco::Logger::get("CMD-MGR-JANITOR");
|
Poco::Logger &MyLogger = Poco::Logger::get("CMD-MGR-JANITOR");
|
||||||
std::string TimeOutError("No response.");
|
std::string TimeOutError("No response.");
|
||||||
|
|
||||||
auto now = std::chrono::high_resolution_clock::now();
|
auto now = std::chrono::high_resolution_clock::now();
|
||||||
for(auto request=OutStandingRequests_.begin();request!=OutStandingRequests_.end();) {
|
for (auto request = OutStandingRequests_.begin(); request != OutStandingRequests_.end();) {
|
||||||
std::chrono::duration<double, std::milli> delta = now - request->second.submitted;
|
std::chrono::duration<double, std::milli> delta = now - request->second.submitted;
|
||||||
if(delta > 10min) {
|
if (delta > 10min) {
|
||||||
// std::cout << __LINE__ << " -->> " << request->second.Id << std::endl;
|
// std::cout << __LINE__ << " -->> " << request->second.Id <<
|
||||||
MyLogger.debug(fmt::format("{}: Command={} for {} Timed out.",
|
//std::endl;
|
||||||
request->second.UUID,
|
MyLogger.debug(fmt::format("{}: Command={} for {} Timed out.", request->second.UUID,
|
||||||
APCommands::to_string(request->second.Command),
|
APCommands::to_string(request->second.Command),
|
||||||
Utils::IntToSerialNumber(request->second.SerialNumber)));
|
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)) {
|
(request->second.Command == APCommands::Commands::trace)) {
|
||||||
StorageService()->CancelWaitFile(request->second.UUID, TimeOutError);
|
StorageService()->CancelWaitFile(request->second.UUID, TimeOutError);
|
||||||
}
|
}
|
||||||
StorageService()->SetCommandTimedOut(request->second.UUID);
|
StorageService()->SetCommandTimedOut(request->second.UUID);
|
||||||
request = OutStandingRequests_.erase(request);
|
request = OutStandingRequests_.erase(request);
|
||||||
} else {
|
} else {
|
||||||
// std::cout << __LINE__ << " -->> " << request->second.Id << std::endl;
|
// std::cout << __LINE__ << " -->> " << request->second.Id <<
|
||||||
|
//std::endl;
|
||||||
++request;
|
++request;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -228,15 +245,16 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
bool CommandManager::IsCommandRunning(const std::string &C) {
|
bool CommandManager::IsCommandRunning(const std::string &C) {
|
||||||
std::lock_guard Lock(LocalMutex_);
|
std::lock_guard Lock(LocalMutex_);
|
||||||
return std::any_of(OutStandingRequests_.begin(),OutStandingRequests_.end(),
|
return std::any_of(
|
||||||
[C](const std::pair<std::uint64_t , CommandInfo> &r) { return r.second.UUID==C;});
|
OutStandingRequests_.begin(), OutStandingRequests_.end(),
|
||||||
|
[C](const std::pair<std::uint64_t, CommandInfo> &r) { return r.second.UUID == C; });
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandManager::onCommandRunnerTimer([[maybe_unused]] Poco::Timer &timer) {
|
void CommandManager::onCommandRunnerTimer([[maybe_unused]] Poco::Timer &timer) {
|
||||||
Utils::SetThreadName("cmd:schdlr");
|
Utils::SetThreadName("cmd:schdlr");
|
||||||
Poco::Logger &MyLogger = Poco::Logger::get("CMD-MGR-SCHEDULER");
|
Poco::Logger &MyLogger = Poco::Logger::get("CMD-MGR-SCHEDULER");
|
||||||
|
|
||||||
poco_trace(MyLogger,"Scheduler starting.");
|
poco_trace(MyLogger, "Scheduler starting.");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
@@ -245,27 +263,28 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
std::vector<GWObjects::CommandDetails> Commands;
|
std::vector<GWObjects::CommandDetails> Commands;
|
||||||
if (StorageService()->GetReadyToExecuteCommands(0, 200, 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) {
|
for (auto &Cmd : Commands) {
|
||||||
if (!Running_) {
|
if (!Running_) {
|
||||||
poco_warning(MyLogger,"Scheduler quitting because service is stopping.");
|
poco_warning(MyLogger, "Scheduler quitting because service is stopping.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
poco_trace(
|
poco_trace(MyLogger,
|
||||||
MyLogger, fmt::format("{}: Serial={} Command={} Starting processing.",
|
fmt::format("{}: Serial={} Command={} Starting processing.",
|
||||||
Cmd.UUID, Cmd.SerialNumber, Cmd.Command));
|
Cmd.UUID, Cmd.SerialNumber, Cmd.Command));
|
||||||
try {
|
try {
|
||||||
|
|
||||||
// Skip an already running command
|
// Skip an already running command
|
||||||
if(IsCommandRunning(Cmd.UUID)) {
|
if (IsCommandRunning(Cmd.UUID)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto now = Utils::Now();
|
auto now = Utils::Now();
|
||||||
// 2 hour timeout for commands
|
// 2 hour timeout for commands
|
||||||
if ((now - Cmd.Submitted) > commandTimeOut_) {
|
if ((now - Cmd.Submitted) > commandTimeOut_) {
|
||||||
poco_information(
|
poco_information(MyLogger,
|
||||||
MyLogger, fmt::format("{}: Serial={} Command={} has expired.",
|
fmt::format("{}: Serial={} Command={} has expired.",
|
||||||
Cmd.UUID, Cmd.SerialNumber, Cmd.Command));
|
Cmd.UUID, Cmd.SerialNumber, Cmd.Command));
|
||||||
StorageService()->SetCommandTimedOut(Cmd.UUID);
|
StorageService()->SetCommandTimedOut(Cmd.UUID);
|
||||||
continue;
|
continue;
|
||||||
@@ -275,37 +294,39 @@ namespace OpenWifi {
|
|||||||
if (!AP_WS_Server()->Connected(SerialNumberInt)) {
|
if (!AP_WS_Server()->Connected(SerialNumberInt)) {
|
||||||
poco_trace(
|
poco_trace(
|
||||||
MyLogger,
|
MyLogger,
|
||||||
fmt::format(
|
fmt::format("{}: Serial={} Command={} Device is not connected.",
|
||||||
"{}: Serial={} Command={} Device is not connected.",
|
|
||||||
Cmd.UUID, Cmd.SerialNumber, Cmd.Command));
|
Cmd.UUID, Cmd.SerialNumber, Cmd.Command));
|
||||||
StorageService()->SetCommandLastTry(Cmd.UUID);
|
StorageService()->SetCommandLastTry(Cmd.UUID);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ExecutingUUID;
|
std::string ExecutingUUID;
|
||||||
APCommands::Commands ExecutingCommand=APCommands::Commands::unknown;
|
APCommands::Commands ExecutingCommand = APCommands::Commands::unknown;
|
||||||
if (CommandRunningForDevice(SerialNumberInt,
|
if (CommandRunningForDevice(SerialNumberInt, ExecutingUUID,
|
||||||
ExecutingUUID, ExecutingCommand)) {
|
ExecutingCommand)) {
|
||||||
poco_trace(
|
poco_trace(
|
||||||
MyLogger,
|
MyLogger,
|
||||||
fmt::format(
|
fmt::format("{}: Serial={} Command={} Device is already busy "
|
||||||
"{}: Serial={} Command={} Device is already busy with command {} (Command={})."
|
"with command {} (Command={}).",
|
||||||
, Cmd.UUID, Cmd.SerialNumber, Cmd.Command, ExecutingUUID, APCommands::to_string(ExecutingCommand)));
|
Cmd.UUID, Cmd.SerialNumber, Cmd.Command, ExecutingUUID,
|
||||||
|
APCommands::to_string(ExecutingCommand)));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Poco::JSON::Parser P;
|
Poco::JSON::Parser P;
|
||||||
bool Sent;
|
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));
|
Cmd.UUID, Cmd.SerialNumber, Cmd.Command));
|
||||||
auto Params = P.parse(Cmd.Details).extract<Poco::JSON::Object::Ptr>();
|
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,
|
auto Result = PostCommandDisk(
|
||||||
*Params, Cmd.UUID, Sent);
|
Next_RPC_ID(), APCommands::to_apcommand(Cmd.Command.c_str()),
|
||||||
|
Cmd.SerialNumber, Cmd.Command, *Params, Cmd.UUID, Sent);
|
||||||
if (Sent) {
|
if (Sent) {
|
||||||
StorageService()->SetCommandExecuted(Cmd.UUID);
|
StorageService()->SetCommandExecuted(Cmd.UUID);
|
||||||
poco_debug(MyLogger,
|
poco_debug(MyLogger,
|
||||||
fmt::format("{}: Serial={} Command={} Sent.",
|
fmt::format("{}: Serial={} Command={} Sent.", Cmd.UUID,
|
||||||
Cmd.UUID, Cmd.SerialNumber, Cmd.Command));
|
Cmd.SerialNumber, Cmd.Command));
|
||||||
} else {
|
} else {
|
||||||
poco_debug(MyLogger,
|
poco_debug(MyLogger,
|
||||||
fmt::format("{}: Serial={} Command={} Re-queued command.",
|
fmt::format("{}: Serial={} Command={} Re-queued command.",
|
||||||
@@ -313,14 +334,16 @@ namespace OpenWifi {
|
|||||||
StorageService()->SetCommandLastTry(Cmd.UUID);
|
StorageService()->SetCommandLastTry(Cmd.UUID);
|
||||||
}
|
}
|
||||||
} catch (const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
poco_debug(MyLogger,
|
poco_debug(
|
||||||
fmt::format("{}: Serial={} Command={} Failed. Command marked as completed.",
|
MyLogger,
|
||||||
|
fmt::format(
|
||||||
|
"{}: Serial={} Command={} Failed. Command marked as completed.",
|
||||||
Cmd.UUID, Cmd.SerialNumber, Cmd.Command));
|
Cmd.UUID, Cmd.SerialNumber, Cmd.Command));
|
||||||
MyLogger.log(E);
|
MyLogger.log(E);
|
||||||
StorageService()->SetCommandExecuted(Cmd.UUID);
|
StorageService()->SetCommandExecuted(Cmd.UUID);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
poco_debug(MyLogger,
|
poco_debug(MyLogger, fmt::format("{}: Serial={} Command={} Hard failure. "
|
||||||
fmt::format("{}: Serial={} Command={} Hard failure. Command marked as completed.",
|
"Command marked as completed.",
|
||||||
Cmd.UUID, Cmd.SerialNumber, Cmd.Command));
|
Cmd.UUID, Cmd.SerialNumber, Cmd.Command));
|
||||||
StorageService()->SetCommandExecuted(Cmd.UUID);
|
StorageService()->SetCommandExecuted(Cmd.UUID);
|
||||||
}
|
}
|
||||||
@@ -329,26 +352,18 @@ namespace OpenWifi {
|
|||||||
} catch (Poco::Exception &E) {
|
} catch (Poco::Exception &E) {
|
||||||
MyLogger.log(E);
|
MyLogger.log(E);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
poco_warning(MyLogger,"Exception during command processing.");
|
poco_warning(MyLogger, "Exception during command processing.");
|
||||||
}
|
}
|
||||||
poco_trace(MyLogger,"Scheduler done.");
|
poco_trace(MyLogger, "Scheduler done.");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<CommandManager::promise_type_t> CommandManager::PostCommand(
|
std::shared_ptr<CommandManager::promise_type_t> CommandManager::PostCommand(
|
||||||
uint64_t RPC_ID,
|
uint64_t RPC_ID, APCommands::Commands Command, const std::string &SerialNumber,
|
||||||
APCommands::Commands Command,
|
const std::string &CommandStr, const Poco::JSON::Object &Params, const std::string &UUID,
|
||||||
const std::string &SerialNumber,
|
bool oneway_rpc, [[maybe_unused]] bool disk_only, bool &Sent, bool rpc, bool Deferred) {
|
||||||
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);
|
auto SerialNumberInt = Utils::SerialNumberToInt(SerialNumber);
|
||||||
Sent=false;
|
Sent = false;
|
||||||
|
|
||||||
std::stringstream ToSend;
|
std::stringstream ToSend;
|
||||||
|
|
||||||
@@ -358,7 +373,7 @@ namespace OpenWifi {
|
|||||||
CInfo.Command = Command;
|
CInfo.Command = Command;
|
||||||
CInfo.Deferred = Deferred;
|
CInfo.Deferred = Deferred;
|
||||||
CInfo.UUID = UUID;
|
CInfo.UUID = UUID;
|
||||||
if(Command == APCommands::Commands::script && Deferred) {
|
if (Command == APCommands::Commands::script && Deferred) {
|
||||||
CInfo.State = 2;
|
CInfo.State = 2;
|
||||||
} else {
|
} else {
|
||||||
CInfo.State = 1;
|
CInfo.State = 1;
|
||||||
@@ -372,16 +387,17 @@ namespace OpenWifi {
|
|||||||
Poco::JSON::Stringifier::stringify(CompleteRPC, ToSend);
|
Poco::JSON::Stringifier::stringify(CompleteRPC, ToSend);
|
||||||
CInfo.rpc_entry = rpc ? std::make_shared<CommandManager::promise_type_t>() : nullptr;
|
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));
|
poco_debug(Logger(), fmt::format("{}: Sending command {} to {}. ID: {}", UUID, CommandStr,
|
||||||
// Do not change the order. It is possible that an RPC completes before it is entered in the map. So we insert it
|
SerialNumber, RPC_ID));
|
||||||
// first, even if we may need to remove it later upon failure.
|
// Do not change the order. It is possible that an RPC completes before it is entered in
|
||||||
if(!oneway_rpc) {
|
//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_);
|
std::lock_guard M(Mutex_);
|
||||||
OutStandingRequests_[RPC_ID] = CInfo;
|
OutStandingRequests_[RPC_ID] = CInfo;
|
||||||
}
|
}
|
||||||
if(AP_WS_Server()->SendFrame(SerialNumber, ToSend.str())) {
|
if (AP_WS_Server()->SendFrame(SerialNumber, ToSend.str())) {
|
||||||
poco_debug(Logger(), fmt::format("{}: Sent command. ID: {}", UUID, RPC_ID));
|
poco_debug(Logger(), fmt::format("{}: Sent command. ID: {}", UUID, RPC_ID));
|
||||||
Sent=true;
|
Sent = true;
|
||||||
return CInfo.rpc_entry;
|
return CInfo.rpc_entry;
|
||||||
} else if (!oneway_rpc) {
|
} else if (!oneway_rpc) {
|
||||||
std::lock_guard M(Mutex_);
|
std::lock_guard M(Mutex_);
|
||||||
@@ -391,4 +407,4 @@ namespace OpenWifi {
|
|||||||
poco_warning(Logger(), fmt::format("{}: Failed to send command. ID: {}", UUID, RPC_ID));
|
poco_warning(Logger(), fmt::format("{}: Failed to send command. ID: {}", UUID, RPC_ID));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace OpenWifi
|
||||||
@@ -9,54 +9,49 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <functional>
|
||||||
#include <future>
|
#include <future>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <utility>
|
|
||||||
#include <functional>
|
|
||||||
#include <shared_mutex>
|
#include <shared_mutex>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include "Poco/JSON/Object.h"
|
#include "Poco/JSON/Object.h"
|
||||||
#include "Poco/Net/HTTPServerRequest.h"
|
#include "Poco/Net/HTTPServerRequest.h"
|
||||||
#include "Poco/Net/HTTPServerResponse.h"
|
#include "Poco/Net/HTTPServerResponse.h"
|
||||||
#include "Poco/Timer.h"
|
|
||||||
#include "Poco/Notification.h"
|
#include "Poco/Notification.h"
|
||||||
#include "Poco/NotificationQueue.h"
|
#include "Poco/NotificationQueue.h"
|
||||||
|
#include "Poco/Timer.h"
|
||||||
|
|
||||||
#include "framework/SubSystemServer.h"
|
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
|
#include "framework/SubSystemServer.h"
|
||||||
|
|
||||||
#include "RESTObjects/RESTAPI_GWobjects.h"
|
#include "RESTObjects/RESTAPI_GWobjects.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
class RPCResponseNotification: public Poco::Notification {
|
class RPCResponseNotification : public Poco::Notification {
|
||||||
public:
|
public:
|
||||||
RPCResponseNotification(std::uint64_t ser,
|
RPCResponseNotification(std::uint64_t ser, Poco::JSON::Object::Ptr pl)
|
||||||
Poco::JSON::Object::Ptr pl) :
|
: SerialNumber_(ser), Payload_(std::move(pl)) {}
|
||||||
SerialNumber_(ser),
|
|
||||||
Payload_(std::move(pl))
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
std::uint64_t SerialNumber_;
|
std::uint64_t SerialNumber_;
|
||||||
Poco::JSON::Object::Ptr Payload_;
|
Poco::JSON::Object::Ptr Payload_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class CommandManager : public SubSystemServer, Poco::Runnable {
|
class CommandManager : public SubSystemServer, Poco::Runnable {
|
||||||
public:
|
public:
|
||||||
using objtype_t = Poco::JSON::Object::Ptr;
|
using objtype_t = Poco::JSON::Object::Ptr;
|
||||||
using promise_type_t = std::promise<objtype_t>;
|
using promise_type_t = std::promise<objtype_t>;
|
||||||
|
|
||||||
struct CommandInfo {
|
struct CommandInfo {
|
||||||
std::uint64_t Id=0;
|
std::uint64_t Id = 0;
|
||||||
std::uint64_t SerialNumber=0;
|
std::uint64_t SerialNumber = 0;
|
||||||
APCommands::Commands Command;
|
APCommands::Commands Command;
|
||||||
std::string UUID;
|
std::string UUID;
|
||||||
std::uint64_t State=1;
|
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;
|
std::shared_ptr<promise_type_t> rpc_entry;
|
||||||
bool Deferred=false;
|
bool Deferred = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RPCResponse {
|
struct RPCResponse {
|
||||||
@@ -64,17 +59,16 @@ namespace OpenWifi {
|
|||||||
Poco::JSON::Object::Ptr payload;
|
Poco::JSON::Object::Ptr payload;
|
||||||
|
|
||||||
explicit RPCResponse(std::uint64_t ser, Poco::JSON::Object::Ptr pl)
|
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;
|
int Start() override;
|
||||||
void Stop() override;
|
void Stop() override;
|
||||||
void WakeUp();
|
void WakeUp();
|
||||||
inline void PostCommandResult(const std::string &SerialNumber, Poco::JSON::Object::Ptr Obj) {
|
inline void PostCommandResult(const std::string &SerialNumber,
|
||||||
ResponseQueue_.enqueueNotification(new RPCResponseNotification(Utils::SerialNumberToInt(SerialNumber),std::move(Obj)));
|
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,
|
std::shared_ptr<promise_type_t> PostCommandOneWayDisk(uint64_t RPC_ID,
|
||||||
@@ -82,74 +76,33 @@ namespace OpenWifi {
|
|||||||
const std::string &SerialNumber,
|
const std::string &SerialNumber,
|
||||||
const std::string &Method,
|
const std::string &Method,
|
||||||
const Poco::JSON::Object &Params,
|
const Poco::JSON::Object &Params,
|
||||||
const std::string &UUID,
|
const std::string &UUID, bool &Sent) {
|
||||||
bool & Sent) {
|
return PostCommand(RPC_ID, Command, SerialNumber, Method, Params, UUID, true, true,
|
||||||
return PostCommand(RPC_ID,
|
Sent, false);
|
||||||
Command,
|
|
||||||
SerialNumber,
|
|
||||||
Method,
|
|
||||||
Params,
|
|
||||||
UUID,
|
|
||||||
true, true, Sent , false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<promise_type_t> PostCommandDisk(
|
std::shared_ptr<promise_type_t>
|
||||||
uint64_t RPC_ID,
|
PostCommandDisk(uint64_t RPC_ID, APCommands::Commands Command,
|
||||||
APCommands::Commands Command,
|
const std::string &SerialNumber, const std::string &Method,
|
||||||
const std::string &SerialNumber,
|
const Poco::JSON::Object &Params, const std::string &UUID, bool &Sent) {
|
||||||
const std::string &Method,
|
return PostCommand(RPC_ID, Command, SerialNumber, Method, Params, UUID, false, true,
|
||||||
const Poco::JSON::Object &Params,
|
Sent, false);
|
||||||
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(
|
std::shared_ptr<promise_type_t>
|
||||||
uint64_t RPC_ID,
|
PostCommand(uint64_t RPC_ID, APCommands::Commands Command, const std::string &SerialNumber,
|
||||||
APCommands::Commands Command,
|
const std::string &Method, const Poco::JSON::Object &Params,
|
||||||
const std::string &SerialNumber,
|
const std::string &UUID, bool &Sent, bool rpc, bool Deferred) {
|
||||||
const std::string &Method,
|
return PostCommand(RPC_ID, Command, SerialNumber, Method, Params, UUID, false, false,
|
||||||
const Poco::JSON::Object &Params,
|
Sent, rpc, Deferred);
|
||||||
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(
|
std::shared_ptr<promise_type_t>
|
||||||
uint64_t RPC_ID,
|
PostCommandOneWay(uint64_t RPC_ID, APCommands::Commands Command,
|
||||||
APCommands::Commands Command,
|
const std::string &SerialNumber, const std::string &Method,
|
||||||
const std::string &SerialNumber,
|
const Poco::JSON::Object &Params, const std::string &UUID, bool &Sent) {
|
||||||
const std::string &Method,
|
return PostCommand(RPC_ID, Command, SerialNumber, Method, Params, UUID, true, false,
|
||||||
const Poco::JSON::Object &Params,
|
Sent, false);
|
||||||
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);
|
bool IsCommandRunning(const std::string &C);
|
||||||
@@ -162,8 +115,8 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline bool Running() const { return Running_; }
|
inline bool Running() const { return Running_; }
|
||||||
void onJanitorTimer(Poco::Timer & timer);
|
void onJanitorTimer(Poco::Timer &timer);
|
||||||
void onCommandRunnerTimer(Poco::Timer & timer);
|
void onCommandRunnerTimer(Poco::Timer &timer);
|
||||||
inline uint64_t Next_RPC_ID() { return ++Id_; }
|
inline uint64_t Next_RPC_ID() { return ++Id_; }
|
||||||
|
|
||||||
void RemovePendingCommand(std::uint64_t Id) {
|
void RemovePendingCommand(std::uint64_t Id) {
|
||||||
@@ -171,11 +124,12 @@ namespace OpenWifi {
|
|||||||
OutStandingRequests_.erase(Id);
|
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_);
|
std::lock_guard Lock(LocalMutex_);
|
||||||
|
|
||||||
for(const auto &[Request,Command]:OutStandingRequests_) {
|
for (const auto &[Request, Command] : OutStandingRequests_) {
|
||||||
if(Command.SerialNumber==SerialNumber) {
|
if (Command.SerialNumber == SerialNumber) {
|
||||||
uuid = Command.UUID;
|
uuid = Command.UUID;
|
||||||
command = Command.Command;
|
command = Command.Command;
|
||||||
return true;
|
return true;
|
||||||
@@ -186,8 +140,9 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
inline void ClearQueue(std::uint64_t SerialNumber) {
|
inline void ClearQueue(std::uint64_t SerialNumber) {
|
||||||
std::lock_guard Lock(LocalMutex_);
|
std::lock_guard Lock(LocalMutex_);
|
||||||
for(auto Request = OutStandingRequests_.begin(); Request != OutStandingRequests_.end() ; ) {
|
for (auto Request = OutStandingRequests_.begin();
|
||||||
if(Request->second.SerialNumber==SerialNumber)
|
Request != OutStandingRequests_.end();) {
|
||||||
|
if (Request->second.SerialNumber == SerialNumber)
|
||||||
Request = OutStandingRequests_.erase(Request);
|
Request = OutStandingRequests_.erase(Request);
|
||||||
else
|
else
|
||||||
++Request;
|
++Request;
|
||||||
@@ -196,8 +151,8 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
inline void RemoveCommand(const std::string &UUID) {
|
inline void RemoveCommand(const std::string &UUID) {
|
||||||
std::lock_guard Lock(LocalMutex_);
|
std::lock_guard Lock(LocalMutex_);
|
||||||
for(const auto &[Id,Cmd]:OutStandingRequests_) {
|
for (const auto &[Id, Cmd] : OutStandingRequests_) {
|
||||||
if(Cmd.UUID==UUID) {
|
if (Cmd.UUID == UUID) {
|
||||||
OutStandingRequests_.erase(Id);
|
OutStandingRequests_.erase(Id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -211,40 +166,33 @@ namespace OpenWifi {
|
|||||||
mutable std::recursive_mutex LocalMutex_;
|
mutable std::recursive_mutex LocalMutex_;
|
||||||
std::atomic_bool Running_ = false;
|
std::atomic_bool Running_ = false;
|
||||||
Poco::Thread ManagerThread;
|
Poco::Thread ManagerThread;
|
||||||
std::atomic_uint64_t Id_=3; // do not start @1. We ignore ID=1 & 0 is illegal..
|
std::atomic_uint64_t Id_ = 3; // do not start @1. We ignore ID=1 & 0 is illegal..
|
||||||
std::map<std::uint64_t , CommandInfo> OutStandingRequests_;
|
std::map<std::uint64_t, CommandInfo> OutStandingRequests_;
|
||||||
Poco::Timer JanitorTimer_;
|
Poco::Timer JanitorTimer_;
|
||||||
std::unique_ptr<Poco::TimerCallback<CommandManager>> JanitorCallback_;
|
std::unique_ptr<Poco::TimerCallback<CommandManager>> JanitorCallback_;
|
||||||
Poco::Timer CommandRunnerTimer_;
|
Poco::Timer CommandRunnerTimer_;
|
||||||
std::unique_ptr<Poco::TimerCallback<CommandManager>> CommandRunnerCallback_;
|
std::unique_ptr<Poco::TimerCallback<CommandManager>> CommandRunnerCallback_;
|
||||||
Poco::NotificationQueue ResponseQueue_;
|
Poco::NotificationQueue ResponseQueue_;
|
||||||
std::uint64_t commandTimeOut_=0;
|
std::uint64_t commandTimeOut_ = 0;
|
||||||
std::uint64_t commandRetry_=0;
|
std::uint64_t commandRetry_ = 0;
|
||||||
std::uint64_t janitorInterval_=0;
|
std::uint64_t janitorInterval_ = 0;
|
||||||
std::uint64_t queueInterval_=0;
|
std::uint64_t queueInterval_ = 0;
|
||||||
|
|
||||||
std::shared_ptr<promise_type_t> PostCommand(
|
std::shared_ptr<promise_type_t>
|
||||||
uint64_t RPCID,
|
PostCommand(uint64_t RPCID, APCommands::Commands Command, const std::string &SerialNumber,
|
||||||
APCommands::Commands Command,
|
const std::string &Method, const Poco::JSON::Object &Params,
|
||||||
const std::string &SerialNumber,
|
const std::string &UUID, bool oneway_rpc, bool disk_only, bool &Sent,
|
||||||
const std::string &Method,
|
bool rpc_call, bool Deferred = false);
|
||||||
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 CompleteScriptCommand(CommandInfo &Command, const Poco::JSON::Object::Ptr &Payload,
|
||||||
bool CompleteTelemetryCommand(CommandInfo &Command, const Poco::JSON::Object::Ptr &Payload, std::chrono::duration<double, std::milli> rpc_execution_time);
|
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:
|
CommandManager() noexcept
|
||||||
SubSystemServer("CommandManager", "CMD-MGR", "command.manager") {
|
: SubSystemServer("CommandManager", "CMD-MGR", "command.manager") {}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline auto CommandManager() { return CommandManager::instance(); }
|
inline auto CommandManager() { return CommandManager::instance(); }
|
||||||
|
|
||||||
} // namespace
|
} // namespace OpenWifi
|
||||||
|
|
||||||
|
|||||||
@@ -5,14 +5,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
class ConfigurationCache {
|
class ConfigurationCache {
|
||||||
public:
|
public:
|
||||||
|
static ConfigurationCache &instance() {
|
||||||
static ConfigurationCache & instance() {
|
|
||||||
static ConfigurationCache instance;
|
static ConfigurationCache instance;
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
@@ -20,30 +19,30 @@ namespace OpenWifi {
|
|||||||
inline uint64_t CurrentConfig(uint64_t SerialNumber) {
|
inline uint64_t CurrentConfig(uint64_t SerialNumber) {
|
||||||
std::lock_guard G(Mutex_);
|
std::lock_guard G(Mutex_);
|
||||||
const auto Hint = Cache_.find(SerialNumber);
|
const auto Hint = Cache_.find(SerialNumber);
|
||||||
if(Hint==end(Cache_))
|
if (Hint == end(Cache_))
|
||||||
return 0;
|
return 0;
|
||||||
return Hint->second;
|
return Hint->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Add(uint64_t SerialNumber, uint64_t Id) {
|
inline void Add(uint64_t SerialNumber, uint64_t Id) {
|
||||||
std::lock_guard G(Mutex_);
|
std::lock_guard G(Mutex_);
|
||||||
Cache_[SerialNumber]=Id;
|
Cache_[SerialNumber] = Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::recursive_mutex Mutex_;
|
std::recursive_mutex Mutex_;
|
||||||
std::map<uint64_t,uint64_t> Cache_;
|
std::map<uint64_t, uint64_t> Cache_;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline uint64_t GetCurrentConfigurationID(uint64_t SerialNumber) {
|
inline uint64_t GetCurrentConfigurationID(uint64_t SerialNumber) {
|
||||||
return ConfigurationCache::instance().CurrentConfig(SerialNumber);
|
return ConfigurationCache::instance().CurrentConfig(SerialNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void SetCurrentConfigurationID(const std::string & SerialNumber, uint64_t ID) {
|
inline void SetCurrentConfigurationID(const std::string &SerialNumber, uint64_t ID) {
|
||||||
return ConfigurationCache::instance().Add(Utils::SerialNumberToInt(SerialNumber), ID);
|
return ConfigurationCache::instance().Add(Utils::SerialNumberToInt(SerialNumber), ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void SetCurrentConfigurationID(uint64_t SerialNumber, uint64_t ID) {
|
inline void SetCurrentConfigurationID(uint64_t SerialNumber, uint64_t ID) {
|
||||||
return ConfigurationCache::instance().Add(SerialNumber, ID);
|
return ConfigurationCache::instance().Add(SerialNumber, ID);
|
||||||
}
|
}
|
||||||
}
|
} // namespace OpenWifi
|
||||||
|
|||||||
118
src/Daemon.cpp
118
src/Daemon.cpp
@@ -6,11 +6,10 @@
|
|||||||
// Arilia Wireless Inc.
|
// Arilia Wireless Inc.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "Poco/Util/Application.h"
|
|
||||||
#include "Poco/Util/Option.h"
|
|
||||||
#include "Poco/Environment.h"
|
#include "Poco/Environment.h"
|
||||||
#include "Poco/Net/SSLManager.h"
|
#include "Poco/Net/SSLManager.h"
|
||||||
|
#include "Poco/Util/Application.h"
|
||||||
|
#include "Poco/Util/Option.h"
|
||||||
|
|
||||||
#include "AP_WS_Server.h"
|
#include "AP_WS_Server.h"
|
||||||
#include "CommandManager.h"
|
#include "CommandManager.h"
|
||||||
@@ -19,90 +18,73 @@
|
|||||||
#include "FindCountry.h"
|
#include "FindCountry.h"
|
||||||
#include "OUIServer.h"
|
#include "OUIServer.h"
|
||||||
#include "RADIUS_proxy_server.h"
|
#include "RADIUS_proxy_server.h"
|
||||||
|
#include "ScriptManager.h"
|
||||||
#include "SerialNumberCache.h"
|
#include "SerialNumberCache.h"
|
||||||
|
#include "SignatureMgr.h"
|
||||||
#include "StorageArchiver.h"
|
#include "StorageArchiver.h"
|
||||||
#include "StorageService.h"
|
#include "StorageService.h"
|
||||||
#include "TelemetryStream.h"
|
#include "TelemetryStream.h"
|
||||||
|
#include "UI_GW_WebSocketNotifications.h"
|
||||||
#include "VenueBroadcaster.h"
|
#include "VenueBroadcaster.h"
|
||||||
#include "framework/ConfigurationValidator.h"
|
#include "framework/ConfigurationValidator.h"
|
||||||
#include "rttys/RTTYS_server.h"
|
|
||||||
#include "framework/UI_WebSocketClientServer.h"
|
#include "framework/UI_WebSocketClientServer.h"
|
||||||
#include "UI_GW_WebSocketNotifications.h"
|
#include "rttys/RTTYS_server.h"
|
||||||
#include "ScriptManager.h"
|
|
||||||
#include "SignatureMgr.h"
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
class Daemon *Daemon::instance() {
|
class Daemon *Daemon::instance() {
|
||||||
static Daemon instance(vDAEMON_PROPERTIES_FILENAME,
|
static Daemon instance(
|
||||||
vDAEMON_ROOT_ENV_VAR,
|
vDAEMON_PROPERTIES_FILENAME, vDAEMON_ROOT_ENV_VAR, vDAEMON_CONFIG_ENV_VAR,
|
||||||
vDAEMON_CONFIG_ENV_VAR,
|
vDAEMON_APP_NAME, vDAEMON_BUS_TIMER,
|
||||||
vDAEMON_APP_NAME,
|
SubSystemVec{StorageService(), SerialNumberCache(), ConfigurationValidator(),
|
||||||
vDAEMON_BUS_TIMER,
|
UI_WebSocketClientServer(), OUIServer(), FindCountryFromIP(),
|
||||||
SubSystemVec{
|
CommandManager(), FileUploader(), StorageArchiver(), TelemetryStream(),
|
||||||
StorageService(),
|
RTTYS_server(), RADIUS_proxy_server(), VenueBroadcaster(), ScriptManager(),
|
||||||
SerialNumberCache(),
|
SignatureManager(), AP_WS_Server()});
|
||||||
ConfigurationValidator(),
|
|
||||||
UI_WebSocketClientServer(),
|
|
||||||
OUIServer(),
|
|
||||||
FindCountryFromIP(),
|
|
||||||
CommandManager(),
|
|
||||||
FileUploader(),
|
|
||||||
StorageArchiver(),
|
|
||||||
TelemetryStream(),
|
|
||||||
RTTYS_server(),
|
|
||||||
RADIUS_proxy_server(),
|
|
||||||
VenueBroadcaster(),
|
|
||||||
ScriptManager(),
|
|
||||||
SignatureManager(),
|
|
||||||
AP_WS_Server()
|
|
||||||
});
|
|
||||||
return &instance;
|
return &instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const std::vector<std::pair<std::string,std::string>> DefaultDeviceTypes{
|
static const std::vector<std::pair<std::string, std::string>> DefaultDeviceTypes{
|
||||||
{"cig_wf160d","AP"},
|
{"cig_wf160d", "AP"},
|
||||||
{"cig_wf188","AP"},
|
{"cig_wf188", "AP"},
|
||||||
{"cig_wf188n","AP"},
|
{"cig_wf188n", "AP"},
|
||||||
{"cig_wf194c","AP"},
|
{"cig_wf194c", "AP"},
|
||||||
{"cig_wf194c4","AP"},
|
{"cig_wf194c4", "AP"},
|
||||||
{"edgecore_eap101","AP"},
|
{"edgecore_eap101", "AP"},
|
||||||
{"edgecore_eap102","AP"},
|
{"edgecore_eap102", "AP"},
|
||||||
{"edgecore_ecs4100-12ph","AP"},
|
{"edgecore_ecs4100-12ph", "AP"},
|
||||||
{"edgecore_ecw5211","AP"},
|
{"edgecore_ecw5211", "AP"},
|
||||||
{"edgecore_ecw5410","AP"},
|
{"edgecore_ecw5410", "AP"},
|
||||||
{"edgecore_oap100","AP"},
|
{"edgecore_oap100", "AP"},
|
||||||
{"edgecore_spw2ac1200","SWITCH"},
|
{"edgecore_spw2ac1200", "SWITCH"},
|
||||||
{"edgecore_spw2ac1200-lan-poe","SWITCH"},
|
{"edgecore_spw2ac1200-lan-poe", "SWITCH"},
|
||||||
{"edgecore_ssw2ac2600","SWITCH"},
|
{"edgecore_ssw2ac2600", "SWITCH"},
|
||||||
{"hfcl_ion4","AP"},
|
{"hfcl_ion4", "AP"},
|
||||||
{"indio_um-305ac","AP"},
|
{"indio_um-305ac", "AP"},
|
||||||
{"linksys_e8450-ubi","AP"},
|
{"linksys_e8450-ubi", "AP"},
|
||||||
{"linksys_ea6350","AP"},
|
{"linksys_ea6350", "AP"},
|
||||||
{"linksys_ea6350-v4","AP"},
|
{"linksys_ea6350-v4", "AP"},
|
||||||
{"linksys_ea8300","AP"},
|
{"linksys_ea8300", "AP"},
|
||||||
{"mikrotik_nand","AP"},
|
{"mikrotik_nand", "AP"},
|
||||||
{"tp-link_ec420-g1","AP"},
|
{"tp-link_ec420-g1", "AP"},
|
||||||
{"tplink_cpe210_v3","AP"},
|
{"tplink_cpe210_v3", "AP"},
|
||||||
{"tplink_cpe510_v3","AP"},
|
{"tplink_cpe510_v3", "AP"},
|
||||||
{"tplink_eap225_outdoor_v1","AP"},
|
{"tplink_eap225_outdoor_v1", "AP"},
|
||||||
{"tplink_ec420","AP"},
|
{"tplink_ec420", "AP"},
|
||||||
{"tplink_ex227","AP"},
|
{"tplink_ex227", "AP"},
|
||||||
{"tplink_ex228","AP"},
|
{"tplink_ex228", "AP"},
|
||||||
{"tplink_ex447","AP"},
|
{"tplink_ex447", "AP"},
|
||||||
{"wallys_dr40x9","AP"}
|
{"wallys_dr40x9", "AP"}};
|
||||||
};
|
|
||||||
|
|
||||||
void Daemon::PostInitialization([[maybe_unused]] Poco::Util::Application &self) {
|
void Daemon::PostInitialization([[maybe_unused]] Poco::Util::Application &self) {
|
||||||
AutoProvisioning_ = config().getBool("openwifi.autoprovisioning",false);
|
AutoProvisioning_ = config().getBool("openwifi.autoprovisioning", false);
|
||||||
DeviceTypes_ = DefaultDeviceTypes;
|
DeviceTypes_ = DefaultDeviceTypes;
|
||||||
|
|
||||||
WebSocketProcessor_ = std::make_unique<GwWebSocketClient>(logger());
|
WebSocketProcessor_ = std::make_unique<GwWebSocketClient>(logger());
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] std::string Daemon::IdentifyDevice(const std::string & Id ) const {
|
[[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)
|
||||||
if(Id == DeviceType)
|
|
||||||
return Type;
|
return Type;
|
||||||
}
|
}
|
||||||
return "AP";
|
return "AP";
|
||||||
@@ -112,7 +94,7 @@ namespace OpenWifi {
|
|||||||
Daemon()->PostInitialization(self);
|
Daemon()->PostInitialization(self);
|
||||||
GWWebSocketNotifications::Register();
|
GWWebSocketNotifications::Register();
|
||||||
}
|
}
|
||||||
}
|
} // namespace OpenWifi
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
int ExitCode;
|
int ExitCode;
|
||||||
|
|||||||
43
src/Daemon.h
43
src/Daemon.h
@@ -9,50 +9,47 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <iostream>
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <vector>
|
#include <iostream>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "framework/MicroServiceNames.h"
|
|
||||||
#include "framework/MicroService.h"
|
#include "framework/MicroService.h"
|
||||||
|
#include "framework/MicroServiceNames.h"
|
||||||
|
|
||||||
#include "Dashboard.h"
|
#include "Dashboard.h"
|
||||||
#include "framework/OpenWifiTypes.h"
|
|
||||||
#include "GwWebSocketClient.h"
|
#include "GwWebSocketClient.h"
|
||||||
|
#include "framework/OpenWifiTypes.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
[[maybe_unused]] static const char * vDAEMON_PROPERTIES_FILENAME = "owgw.properties";
|
[[maybe_unused]] static const char *vDAEMON_PROPERTIES_FILENAME = "owgw.properties";
|
||||||
[[maybe_unused]] static const char * vDAEMON_ROOT_ENV_VAR = "OWGW_ROOT";
|
[[maybe_unused]] static const char *vDAEMON_ROOT_ENV_VAR = "OWGW_ROOT";
|
||||||
[[maybe_unused]] static const char * vDAEMON_CONFIG_ENV_VAR = "OWGW_CONFIG";
|
[[maybe_unused]] static const char *vDAEMON_CONFIG_ENV_VAR = "OWGW_CONFIG";
|
||||||
[[maybe_unused]] static const char * vDAEMON_APP_NAME = uSERVICE_GATEWAY.c_str();
|
[[maybe_unused]] static const char *vDAEMON_APP_NAME = uSERVICE_GATEWAY.c_str();
|
||||||
[[maybe_unused]] static const uint64_t vDAEMON_BUS_TIMER = 10000;
|
[[maybe_unused]] static const uint64_t vDAEMON_BUS_TIMER = 10000;
|
||||||
|
|
||||||
class Daemon : public MicroService {
|
class Daemon : public MicroService {
|
||||||
public:
|
public:
|
||||||
explicit Daemon(const std::string & PropFile,
|
explicit Daemon(const std::string &PropFile, const std::string &RootEnv,
|
||||||
const std::string & RootEnv,
|
const std::string &ConfigEnv, const std::string &AppName, uint64_t BusTimer,
|
||||||
const std::string & ConfigEnv,
|
const SubSystemVec &SubSystems)
|
||||||
const std::string & AppName,
|
: MicroService(PropFile, RootEnv, ConfigEnv, AppName, BusTimer, SubSystems){};
|
||||||
uint64_t BusTimer,
|
|
||||||
const SubSystemVec & SubSystems) :
|
|
||||||
MicroService( PropFile, RootEnv, ConfigEnv, AppName, BusTimer, SubSystems) {};
|
|
||||||
|
|
||||||
bool AutoProvisioning() const { return AutoProvisioning_ ; }
|
bool AutoProvisioning() const { return AutoProvisioning_; }
|
||||||
[[nodiscard]] std::string IdentifyDevice(const std::string & Compatible) const;
|
[[nodiscard]] std::string IdentifyDevice(const std::string &Compatible) const;
|
||||||
static Daemon *instance();
|
static Daemon *instance();
|
||||||
inline DeviceDashboard & GetDashboard() { return DB_; }
|
inline DeviceDashboard &GetDashboard() { return DB_; }
|
||||||
Poco::Logger & Log() { return Poco::Logger::get(AppName()); }
|
Poco::Logger &Log() { return Poco::Logger::get(AppName()); }
|
||||||
void PostInitialization(Poco::Util::Application &self);
|
void PostInitialization(Poco::Util::Application &self);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool AutoProvisioning_ = false;
|
bool AutoProvisioning_ = false;
|
||||||
std::vector<std::pair<std::string,std::string>> DeviceTypes_;
|
std::vector<std::pair<std::string, std::string>> DeviceTypes_;
|
||||||
DeviceDashboard DB_;
|
DeviceDashboard DB_;
|
||||||
std::unique_ptr<GwWebSocketClient> WebSocketProcessor_;
|
std::unique_ptr<GwWebSocketClient> WebSocketProcessor_;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Daemon * Daemon() { return Daemon::instance(); }
|
inline Daemon *Daemon() { return Daemon::instance(); }
|
||||||
void DaemonPostInitialization(Poco::Util::Application &self);
|
void DaemonPostInitialization(Poco::Util::Application &self);
|
||||||
}
|
} // namespace OpenWifi
|
||||||
|
|
||||||
|
|||||||
@@ -8,9 +8,9 @@
|
|||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
bool DeviceDashboard::Get(GWObjects::Dashboard &D, Poco::Logger & Logger) {
|
bool DeviceDashboard::Get(GWObjects::Dashboard &D, Poco::Logger &Logger) {
|
||||||
uint64_t Now = Utils::Now();
|
uint64_t Now = Utils::Now();
|
||||||
if(!ValidDashboard_ || LastRun_==0 || (Now-LastRun_)>120) {
|
if (!ValidDashboard_ || LastRun_ == 0 || (Now - LastRun_) > 120) {
|
||||||
Generate(D, Logger);
|
Generate(D, Logger);
|
||||||
} else {
|
} else {
|
||||||
std::lock_guard G(DataMutex_);
|
std::lock_guard G(DataMutex_);
|
||||||
@@ -19,10 +19,10 @@ namespace OpenWifi {
|
|||||||
return ValidDashboard_;
|
return ValidDashboard_;
|
||||||
};
|
};
|
||||||
|
|
||||||
void DeviceDashboard::Generate(GWObjects::Dashboard &D, Poco::Logger & Logger ) {
|
void DeviceDashboard::Generate(GWObjects::Dashboard &D, Poco::Logger &Logger) {
|
||||||
if (GeneratingDashboard_.load()) {
|
if (GeneratingDashboard_.load()) {
|
||||||
// std::cout << "Trying to generate dashboard but already being generated" << std::endl;
|
// std::cout << "Trying to generate dashboard but already being generated" << std::endl;
|
||||||
while(GeneratingDashboard_.load()) {
|
while (GeneratingDashboard_.load()) {
|
||||||
Poco::Thread::trySleep(100);
|
Poco::Thread::trySleep(100);
|
||||||
}
|
}
|
||||||
std::lock_guard G(DataMutex_);
|
std::lock_guard G(DataMutex_);
|
||||||
@@ -41,11 +41,10 @@ namespace OpenWifi {
|
|||||||
D = NewData;
|
D = NewData;
|
||||||
std::lock_guard G(DataMutex_);
|
std::lock_guard G(DataMutex_);
|
||||||
DB_ = NewData;
|
DB_ = NewData;
|
||||||
ValidDashboard_=true;
|
ValidDashboard_ = true;
|
||||||
} catch(...) {
|
} catch (...) {
|
||||||
|
|
||||||
}
|
}
|
||||||
GeneratingDashboard_ = false;
|
GeneratingDashboard_ = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} // namespace OpenWifi
|
||||||
|
|||||||
@@ -6,22 +6,22 @@
|
|||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
|
#include "Poco/Logger.h"
|
||||||
#include "RESTObjects//RESTAPI_GWobjects.h"
|
#include "RESTObjects//RESTAPI_GWobjects.h"
|
||||||
#include "framework/OpenWifiTypes.h"
|
#include "framework/OpenWifiTypes.h"
|
||||||
#include "Poco/Logger.h"
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
class DeviceDashboard {
|
class DeviceDashboard {
|
||||||
public:
|
public:
|
||||||
bool Get(GWObjects::Dashboard &D, Poco::Logger & Logger);
|
bool Get(GWObjects::Dashboard &D, Poco::Logger &Logger);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::mutex DataMutex_;
|
std::mutex DataMutex_;
|
||||||
volatile std::atomic_bool GeneratingDashboard_=false;
|
volatile std::atomic_bool GeneratingDashboard_ = false;
|
||||||
volatile bool ValidDashboard_=false;
|
volatile bool ValidDashboard_ = false;
|
||||||
GWObjects::Dashboard DB_;
|
GWObjects::Dashboard DB_;
|
||||||
uint64_t LastRun_=0;
|
uint64_t LastRun_ = 0;
|
||||||
|
|
||||||
void Generate(GWObjects::Dashboard &D, Poco::Logger & Logger);
|
void Generate(GWObjects::Dashboard &D, Poco::Logger &Logger);
|
||||||
};
|
};
|
||||||
}
|
} // namespace OpenWifi
|
||||||
|
|
||||||
|
|||||||
@@ -8,16 +8,16 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#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/CountingStream.h"
|
||||||
#include "Poco/StreamCopier.h"
|
#include "Poco/DynamicAny.h"
|
||||||
#include "Poco/Exception.h"
|
#include "Poco/Exception.h"
|
||||||
#include "Poco/File.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 "Poco/StringTokenizer.h"
|
||||||
|
|
||||||
#include "framework/MicroServiceFuncs.h"
|
#include "framework/MicroServiceFuncs.h"
|
||||||
@@ -33,11 +33,11 @@ namespace OpenWifi {
|
|||||||
static const std::string URI_BASE{"/v1/upload/"};
|
static const std::string URI_BASE{"/v1/upload/"};
|
||||||
|
|
||||||
int FileUploader::Start() {
|
int FileUploader::Start() {
|
||||||
poco_notice(Logger(),"Starting.");
|
poco_notice(Logger(), "Starting.");
|
||||||
|
|
||||||
Poco::File UploadsDir(MicroServiceConfigPath("openwifi.fileuploader.path","/tmp"));
|
Poco::File UploadsDir(MicroServiceConfigPath("openwifi.fileuploader.path", "/tmp"));
|
||||||
Path_ = UploadsDir.path();
|
Path_ = UploadsDir.path();
|
||||||
if(!UploadsDir.exists()) {
|
if (!UploadsDir.exists()) {
|
||||||
try {
|
try {
|
||||||
UploadsDir.createDirectory();
|
UploadsDir.createDirectory();
|
||||||
} catch (const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
@@ -46,9 +46,9 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(const auto & Svr: ConfigServersList_) {
|
for (const auto &Svr : ConfigServersList_) {
|
||||||
if(MicroServiceNoAPISecurity()) {
|
if (MicroServiceNoAPISecurity()) {
|
||||||
poco_notice(Logger(), fmt::format("Starting: {}:{}",Svr.Address(),Svr.Port()));
|
poco_notice(Logger(), fmt::format("Starting: {}:{}", Svr.Address(), Svr.Port()));
|
||||||
|
|
||||||
auto Sock{Svr.CreateSocket(Logger())};
|
auto Sock{Svr.CreateSocket(Logger())};
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ namespace OpenWifi {
|
|||||||
} else {
|
} else {
|
||||||
FullName_ = TmpName + URI_BASE;
|
FullName_ = TmpName + URI_BASE;
|
||||||
}
|
}
|
||||||
poco_information(Logger(),fmt::format("Uploader URI base is '{}'", FullName_));
|
poco_information(Logger(), fmt::format("Uploader URI base is '{}'", FullName_));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto NewServer = std::make_unique<Poco::Net::HTTPServer>(
|
auto NewServer = std::make_unique<Poco::Net::HTTPServer>(
|
||||||
@@ -77,7 +77,7 @@ namespace OpenWifi {
|
|||||||
} else {
|
} else {
|
||||||
std::string l{"Starting: " + Svr.Address() + ":" + std::to_string(Svr.Port()) +
|
std::string l{"Starting: " + Svr.Address() + ":" + std::to_string(Svr.Port()) +
|
||||||
" key:" + Svr.KeyFile() + " cert:" + Svr.CertFile()};
|
" key:" + Svr.KeyFile() + " cert:" + Svr.CertFile()};
|
||||||
poco_information(Logger(),l);
|
poco_information(Logger(), l);
|
||||||
|
|
||||||
auto Sock{Svr.CreateSecureSocket(Logger())};
|
auto Sock{Svr.CreateSecureSocket(Logger())};
|
||||||
|
|
||||||
@@ -116,57 +116,53 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
void FileUploader::reinitialize([[maybe_unused]] Poco::Util::Application &self) {
|
void FileUploader::reinitialize([[maybe_unused]] Poco::Util::Application &self) {
|
||||||
MicroServiceLoadConfigurationFile();
|
MicroServiceLoadConfigurationFile();
|
||||||
poco_information(Logger(),"Reinitializing.");
|
poco_information(Logger(), "Reinitializing.");
|
||||||
Stop();
|
Stop();
|
||||||
Start();
|
Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string & FileUploader::FullName() {
|
const std::string &FileUploader::FullName() { return FullName_; }
|
||||||
return FullName_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if you pass in an empty UUID, it will just clean the list and not add it.
|
// 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_);
|
std::lock_guard Guard(Mutex_);
|
||||||
|
|
||||||
uint64_t now = Utils::Now();
|
uint64_t now = Utils::Now();
|
||||||
auto Func=[now](const UploadId &I) -> bool {
|
auto Func = [now](const UploadId &I) -> bool { return (now > I.Expires); };
|
||||||
return (now > I.Expires);
|
OutStandingUploads_.erase(
|
||||||
};
|
std::remove_if(OutStandingUploads_.begin(), OutStandingUploads_.end(), Func),
|
||||||
OutStandingUploads_.erase(std::remove_if(OutStandingUploads_.begin(),OutStandingUploads_.end(),Func),OutStandingUploads_.end());
|
OutStandingUploads_.end());
|
||||||
OutStandingUploads_.emplace_back(UploadId{UUID, now + WaitTimeInSeconds.count(), Type});
|
OutStandingUploads_.emplace_back(UploadId{UUID, now + WaitTimeInSeconds.count(), Type});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileUploader::ValidRequest(const std::string &UUID) {
|
bool FileUploader::ValidRequest(const std::string &UUID) {
|
||||||
std::lock_guard Guard(Mutex_);
|
std::lock_guard Guard(Mutex_);
|
||||||
auto Func = [UUID](const UploadId &P) -> bool {
|
auto Func = [UUID](const UploadId &P) -> bool { return (P.UUID == UUID); };
|
||||||
return (P.UUID==UUID);
|
return std::find_if(OutStandingUploads_.begin(), OutStandingUploads_.end(), Func) !=
|
||||||
};
|
end(OutStandingUploads_);
|
||||||
return std::find_if(OutStandingUploads_.begin(), OutStandingUploads_.end(), Func) != end(OutStandingUploads_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileUploader::RemoveRequest(const std::string &UUID) {
|
void FileUploader::RemoveRequest(const std::string &UUID) {
|
||||||
std::lock_guard Guard(Mutex_);
|
std::lock_guard Guard(Mutex_);
|
||||||
auto Func = [UUID](const UploadId &P) -> bool {
|
auto Func = [UUID](const UploadId &P) -> bool { return (P.UUID == UUID); };
|
||||||
return (P.UUID==UUID);
|
OutStandingUploads_.erase(
|
||||||
};
|
std::remove_if(OutStandingUploads_.begin(), OutStandingUploads_.end(), Func),
|
||||||
OutStandingUploads_.erase(std::remove_if(OutStandingUploads_.begin(),OutStandingUploads_.end(),Func),OutStandingUploads_.end());
|
OutStandingUploads_.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
class FileUploaderPartHandler2 : public Poco::Net::PartHandler {
|
class FileUploaderPartHandler2 : public Poco::Net::PartHandler {
|
||||||
public:
|
public:
|
||||||
FileUploaderPartHandler2(std::string Id, Poco::Logger &Logger, std::stringstream & ofs) :
|
FileUploaderPartHandler2(std::string Id, Poco::Logger &Logger, std::stringstream &ofs)
|
||||||
Id_(std::move(Id)),
|
: Id_(std::move(Id)), Logger_(Logger), OutputStream_(ofs) {}
|
||||||
Logger_(Logger),
|
|
||||||
OutputStream_(ofs){
|
|
||||||
}
|
|
||||||
void handlePart(const Poco::Net::MessageHeader &Header, std::istream &Stream) {
|
void handlePart(const Poco::Net::MessageHeader &Header, std::istream &Stream) {
|
||||||
FileType_ = Header.get(RESTAPI::Protocol::CONTENTTYPE, RESTAPI::Protocol::UNSPECIFIED);
|
FileType_ = Header.get(RESTAPI::Protocol::CONTENTTYPE, RESTAPI::Protocol::UNSPECIFIED);
|
||||||
if (Header.has(RESTAPI::Protocol::CONTENTDISPOSITION)) {
|
if (Header.has(RESTAPI::Protocol::CONTENTDISPOSITION)) {
|
||||||
std::string Disposition;
|
std::string Disposition;
|
||||||
Poco::Net::NameValueCollection Parameters;
|
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);
|
Name_ = Parameters.get(RESTAPI::Protocol::NAME, RESTAPI::Protocol::UNNAMED);
|
||||||
}
|
}
|
||||||
Poco::CountingInputStream InputStream(Stream);
|
Poco::CountingInputStream InputStream(Stream);
|
||||||
@@ -185,26 +181,23 @@ namespace OpenWifi {
|
|||||||
Poco::Logger &Logger_;
|
Poco::Logger &Logger_;
|
||||||
std::stringstream &OutputStream_;
|
std::stringstream &OutputStream_;
|
||||||
|
|
||||||
inline Poco::Logger & Logger() { return Logger_; };
|
inline Poco::Logger &Logger() { return Logger_; };
|
||||||
};
|
};
|
||||||
|
|
||||||
class FormRequestHandler: public Poco::Net::HTTPRequestHandler
|
class FormRequestHandler : public Poco::Net::HTTPRequestHandler {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
explicit FormRequestHandler(std::string UUID, Poco::Logger & L, const std::string &Type):
|
explicit FormRequestHandler(std::string UUID, Poco::Logger &L, const std::string &Type)
|
||||||
UUID_(std::move(UUID)),
|
: UUID_(std::move(UUID)), Logger_(L), Type_(Type) {}
|
||||||
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");
|
Utils::SetThreadName("FileUploader");
|
||||||
const auto ContentType = Request.getContentType();
|
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_debug(Logger(), fmt::format("{}: Preparing to upload trace file.", UUID_));
|
||||||
Poco::JSON::Object Answer;
|
Poco::JSON::Object Answer;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -229,8 +222,9 @@ namespace OpenWifi {
|
|||||||
Poco::StreamCopier::copyStream(Reader.stream(), FileContent);
|
Poco::StreamCopier::copyStream(Reader.stream(), FileContent);
|
||||||
Answer.set("filename", UUID_);
|
Answer.set("filename", UUID_);
|
||||||
Answer.set("error", 0);
|
Answer.set("error", 0);
|
||||||
poco_debug(Logger(),fmt::format("{}: File uploaded.", UUID_));
|
poco_debug(Logger(), fmt::format("{}: File uploaded.", UUID_));
|
||||||
StorageService()->AttachFileDataToCommand(UUID_, FileContent, Type_);
|
StorageService()->AttachFileDataToCommand(UUID_, FileContent,
|
||||||
|
Type_);
|
||||||
std::ostream &ResponseStream = Response.send();
|
std::ostream &ResponseStream = Response.send();
|
||||||
Poco::JSON::Stringifier::stringify(Answer, ResponseStream);
|
Poco::JSON::Stringifier::stringify(Answer, ResponseStream);
|
||||||
return;
|
return;
|
||||||
@@ -247,10 +241,10 @@ namespace OpenWifi {
|
|||||||
} catch (const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
Logger().log(E);
|
Logger().log(E);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
poco_debug(Logger(),"Exception while receiving trace file.");
|
poco_debug(Logger(), "Exception while receiving trace file.");
|
||||||
}
|
}
|
||||||
|
|
||||||
poco_debug(Logger(),fmt::format("{}: Failed to upload trace file.",UUID_));
|
poco_debug(Logger(), fmt::format("{}: Failed to upload trace file.", UUID_));
|
||||||
std::string Error{"Trace file rejected"};
|
std::string Error{"Trace file rejected"};
|
||||||
StorageService()->CancelWaitFile(UUID_, Error);
|
StorageService()->CancelWaitFile(UUID_, Error);
|
||||||
Answer.set("filename", UUID_);
|
Answer.set("filename", UUID_);
|
||||||
@@ -261,40 +255,42 @@ namespace OpenWifi {
|
|||||||
Poco::JSON::Stringifier::stringify(Answer, ResponseStream);
|
Poco::JSON::Stringifier::stringify(Answer, ResponseStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Poco::Logger & Logger() { return Logger_; }
|
inline Poco::Logger &Logger() { return Logger_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string UUID_;
|
std::string UUID_;
|
||||||
Poco::Logger & Logger_;
|
Poco::Logger &Logger_;
|
||||||
std::string Type_;
|
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 ||
|
if (Request.getMethod() != Poco::Net::HTTPRequest::HTTP_POST ||
|
||||||
Request.getURI().size()<(URI_BASE.size()+36)) {
|
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;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The UUID should be after the /v1/upload/ part...
|
// The UUID should be after the /v1/upload/ part...
|
||||||
auto UUIDLocation = Request.getURI().find_first_of(URI_BASE);
|
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());
|
||||||
auto UUID = Request.getURI().substr(UUIDLocation+URI_BASE.size());
|
|
||||||
|
|
||||||
FileUploader::UploadId E;
|
FileUploader::UploadId E;
|
||||||
if(FileUploader()->Find(UUID,E))
|
if (FileUploader()->Find(UUID, E)) {
|
||||||
{
|
|
||||||
FileUploader()->RemoveRequest(UUID);
|
FileUploader()->RemoveRequest(UUID);
|
||||||
return new FormRequestHandler(UUID,Logger(),E.Type);
|
return new FormRequestHandler(UUID, Logger(), E.Type);
|
||||||
}
|
} else {
|
||||||
else
|
poco_warning(Logger(), fmt::format("Unknown UUID={}", UUID));
|
||||||
{
|
|
||||||
poco_warning(Logger(),fmt::format("Unknown UUID={}",UUID));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -302,7 +298,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
bool FileUploader::Find(const std::string &UUID, UploadId &V) {
|
bool FileUploader::Find(const std::string &UUID, UploadId &V) {
|
||||||
std::lock_guard G(Mutex_);
|
std::lock_guard G(Mutex_);
|
||||||
for(const auto &E:OutStandingUploads_) {
|
for (const auto &E : OutStandingUploads_) {
|
||||||
if (E.UUID == UUID) {
|
if (E.UUID == UUID) {
|
||||||
V = E;
|
V = E;
|
||||||
return true;
|
return true;
|
||||||
@@ -312,11 +308,11 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void FileUploader::Stop() {
|
void FileUploader::Stop() {
|
||||||
poco_notice(Logger(),"Stopping...");
|
poco_notice(Logger(), "Stopping...");
|
||||||
for( const auto & svr : Servers_ )
|
for (const auto &svr : Servers_)
|
||||||
svr->stopAll(true);
|
svr->stopAll(true);
|
||||||
Servers_.clear();
|
Servers_.clear();
|
||||||
poco_notice(Logger(),"Stopped...");
|
poco_notice(Logger(), "Stopped...");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // Namespace
|
} // namespace OpenWifi
|
||||||
@@ -19,7 +19,6 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
class FileUploader : public SubSystemServer {
|
class FileUploader : public SubSystemServer {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
struct UploadId {
|
struct UploadId {
|
||||||
std::string UUID;
|
std::string UUID;
|
||||||
std::uint64_t Expires;
|
std::uint64_t Expires;
|
||||||
@@ -29,11 +28,12 @@ namespace OpenWifi {
|
|||||||
int Start() override;
|
int Start() override;
|
||||||
void Stop() override;
|
void Stop() override;
|
||||||
void reinitialize(Poco::Util::Application &self) override;
|
void reinitialize(Poco::Util::Application &self) override;
|
||||||
const std::string & FullName();
|
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,
|
||||||
bool ValidRequest(const std::string & UUID);
|
const std::string &Type);
|
||||||
|
bool ValidRequest(const std::string &UUID);
|
||||||
void RemoveRequest(const std::string &UUID);
|
void RemoveRequest(const std::string &UUID);
|
||||||
const std::string & Path() { return Path_; };
|
const std::string &Path() { return Path_; };
|
||||||
|
|
||||||
static auto instance() {
|
static auto instance() {
|
||||||
static auto instance_ = new FileUploader;
|
static auto instance_ = new FileUploader;
|
||||||
@@ -43,33 +43,29 @@ namespace OpenWifi {
|
|||||||
[[nodiscard]] inline uint64_t MaxSize() const { return MaxSize_; }
|
[[nodiscard]] inline uint64_t MaxSize() const { return MaxSize_; }
|
||||||
|
|
||||||
bool Find(const std::string &UUID, UploadId &V);
|
bool Find(const std::string &UUID, UploadId &V);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<std::unique_ptr<Poco::Net::HTTPServer>> Servers_;
|
std::vector<std::unique_ptr<Poco::Net::HTTPServer>> Servers_;
|
||||||
std::string FullName_;
|
std::string FullName_;
|
||||||
std::list<UploadId> OutStandingUploads_;
|
std::list<UploadId> OutStandingUploads_;
|
||||||
std::string Path_;
|
std::string Path_;
|
||||||
uint64_t MaxSize_=10000000;
|
uint64_t MaxSize_ = 10000000;
|
||||||
|
|
||||||
explicit FileUploader() noexcept:
|
explicit FileUploader() noexcept
|
||||||
SubSystemServer("FileUploader", "FILE-UPLOAD", "openwifi.fileuploader")
|
: SubSystemServer("FileUploader", "FILE-UPLOAD", "openwifi.fileuploader") {}
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class FileUpLoaderRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
|
class FileUpLoaderRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
|
||||||
public:
|
public:
|
||||||
explicit FileUpLoaderRequestHandlerFactory(Poco::Logger &L) :
|
explicit FileUpLoaderRequestHandlerFactory(Poco::Logger &L) : 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:
|
private:
|
||||||
Poco::Logger & Logger_;
|
Poco::Logger &Logger_;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline auto FileUploader() { return FileUploader::instance(); }
|
inline auto FileUploader() { return FileUploader::instance(); }
|
||||||
} // namespace
|
} // namespace OpenWifi
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
#include "Poco/Net/IPAddress.h"
|
#include "Poco/Net/IPAddress.h"
|
||||||
|
|
||||||
#include "framework/SubSystemServer.h"
|
|
||||||
#include "framework/MicroServiceFuncs.h"
|
#include "framework/MicroServiceFuncs.h"
|
||||||
|
#include "framework/SubSystemServer.h"
|
||||||
|
|
||||||
#include "nlohmann/json.hpp"
|
#include "nlohmann/json.hpp"
|
||||||
|
|
||||||
@@ -15,11 +15,10 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
class IPToCountryProvider {
|
class IPToCountryProvider {
|
||||||
public:
|
public:
|
||||||
virtual bool Init() = 0 ;
|
virtual bool Init() = 0;
|
||||||
virtual Poco::URI URI(const std::string & IPAddress) = 0;
|
virtual Poco::URI URI(const std::string &IPAddress) = 0;
|
||||||
virtual std::string Country( const std::string & Response ) = 0 ;
|
virtual std::string Country(const std::string &Response) = 0;
|
||||||
virtual ~IPToCountryProvider() {
|
virtual ~IPToCountryProvider(){};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class IPInfo : public IPToCountryProvider {
|
class IPInfo : public IPToCountryProvider {
|
||||||
@@ -30,28 +29,26 @@ namespace OpenWifi {
|
|||||||
return !Key_.empty();
|
return !Key_.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] inline Poco::URI URI(const std::string & IPAddress) override {
|
[[nodiscard]] inline Poco::URI URI(const std::string &IPAddress) override {
|
||||||
Poco::URI U("https://ipinfo.io");
|
Poco::URI U("https://ipinfo.io");
|
||||||
U.setPath("/" + IPAddress);
|
U.setPath("/" + IPAddress);
|
||||||
U.addQueryParameter("token",Key_);
|
U.addQueryParameter("token", Key_);
|
||||||
return U;
|
return U;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string Country( const std::string & Response ) override {
|
inline std::string Country(const std::string &Response) override {
|
||||||
try {
|
try {
|
||||||
nlohmann::json IPInfo = nlohmann::json::parse(Response);
|
nlohmann::json IPInfo = nlohmann::json::parse(Response);
|
||||||
if (IPInfo.contains("country") && IPInfo["country"].is_string()) {
|
if (IPInfo.contains("country") && IPInfo["country"].is_string()) {
|
||||||
return IPInfo["country"];
|
return IPInfo["country"];
|
||||||
}
|
}
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string Key_;
|
std::string Key_;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class IPData : public IPToCountryProvider {
|
class IPData : public IPToCountryProvider {
|
||||||
@@ -62,24 +59,24 @@ namespace OpenWifi {
|
|||||||
return !Key_.empty();
|
return !Key_.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] inline Poco::URI URI(const std::string & IPAddress) override {
|
[[nodiscard]] inline Poco::URI URI(const std::string &IPAddress) override {
|
||||||
Poco::URI U("https://api.ipdata.co");
|
Poco::URI U("https://api.ipdata.co");
|
||||||
U.setPath("/" + IPAddress);
|
U.setPath("/" + IPAddress);
|
||||||
U.addQueryParameter("api-key",Key_);
|
U.addQueryParameter("api-key", Key_);
|
||||||
return U;
|
return U;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string Country( const std::string & Response ) override {
|
inline std::string Country(const std::string &Response) override {
|
||||||
try {
|
try {
|
||||||
nlohmann::json IPInfo = nlohmann::json::parse(Response);
|
nlohmann::json IPInfo = nlohmann::json::parse(Response);
|
||||||
if (IPInfo.contains("country_code") && IPInfo["country_code"].is_string()) {
|
if (IPInfo.contains("country_code") && IPInfo["country_code"].is_string()) {
|
||||||
return IPInfo["country_code"];
|
return IPInfo["country_code"];
|
||||||
}
|
}
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string Key_;
|
std::string Key_;
|
||||||
};
|
};
|
||||||
@@ -92,33 +89,33 @@ namespace OpenWifi {
|
|||||||
return !Key_.empty();
|
return !Key_.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] inline Poco::URI URI(const std::string & IPAddress) override {
|
[[nodiscard]] inline Poco::URI URI(const std::string &IPAddress) override {
|
||||||
Poco::URI U("https://api.ip2location.com/v2");
|
Poco::URI U("https://api.ip2location.com/v2");
|
||||||
U.setPath("/");
|
U.setPath("/");
|
||||||
U.addQueryParameter("ip", IPAddress);
|
U.addQueryParameter("ip", IPAddress);
|
||||||
U.addQueryParameter("package", "WS1");
|
U.addQueryParameter("package", "WS1");
|
||||||
U.addQueryParameter("key",Key_);
|
U.addQueryParameter("key", Key_);
|
||||||
return U;
|
return U;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string Country( const std::string & Response ) override {
|
inline std::string Country(const std::string &Response) override {
|
||||||
try {
|
try {
|
||||||
nlohmann::json IPInfo = nlohmann::json::parse(Response);
|
nlohmann::json IPInfo = nlohmann::json::parse(Response);
|
||||||
if (IPInfo.contains("country_code") && IPInfo["country_code"].is_string()) {
|
if (IPInfo.contains("country_code") && IPInfo["country_code"].is_string()) {
|
||||||
return IPInfo["country_code"];
|
return IPInfo["country_code"];
|
||||||
}
|
}
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string Key_;
|
std::string Key_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename BaseClass, typename T, typename... Args>
|
template <typename BaseClass, typename T, typename... Args>
|
||||||
std::unique_ptr<BaseClass> IPLocationProvider(const std::string & RequestProvider ) {
|
std::unique_ptr<BaseClass> IPLocationProvider(const std::string &RequestProvider) {
|
||||||
if(T::Name()==RequestProvider) {
|
if (T::Name() == RequestProvider) {
|
||||||
return std::make_unique<T>();
|
return std::make_unique<T>();
|
||||||
}
|
}
|
||||||
if constexpr (sizeof...(Args) == 0) {
|
if constexpr (sizeof...(Args) == 0) {
|
||||||
@@ -136,11 +133,12 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline int Start() final {
|
inline int Start() final {
|
||||||
poco_notice(Logger(),"Starting...");
|
poco_notice(Logger(), "Starting...");
|
||||||
ProviderName_ = MicroServiceConfigGetString("iptocountry.provider","");
|
ProviderName_ = MicroServiceConfigGetString("iptocountry.provider", "");
|
||||||
if(!ProviderName_.empty()) {
|
if (!ProviderName_.empty()) {
|
||||||
Provider_ = IPLocationProvider<IPToCountryProvider, IPInfo, IPData, IP2Location>(ProviderName_);
|
Provider_ = IPLocationProvider<IPToCountryProvider, IPInfo, IPData, IP2Location>(
|
||||||
if(Provider_!= nullptr) {
|
ProviderName_);
|
||||||
|
if (Provider_ != nullptr) {
|
||||||
Enabled_ = Provider_->Init();
|
Enabled_ = Provider_->Init();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -149,28 +147,26 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline void Stop() final {
|
inline void Stop() final {
|
||||||
poco_notice(Logger(),"Stopping...");
|
poco_notice(Logger(), "Stopping...");
|
||||||
// Nothing to do - just to provide the same look at the others.
|
// Nothing to do - just to provide the same look at the others.
|
||||||
poco_notice(Logger(),"Stopped...");
|
poco_notice(Logger(), "Stopped...");
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] static inline std::string ReformatAddress(const std::string & I )
|
[[nodiscard]] static inline std::string ReformatAddress(const std::string &I) {
|
||||||
{
|
if (I.substr(0, 7) == "::ffff:") {
|
||||||
if(I.substr(0,7) == "::ffff:")
|
std::string ip = I.substr(7);
|
||||||
{
|
|
||||||
std::string ip = I.substr(7 );
|
|
||||||
return ip;
|
return ip;
|
||||||
}
|
}
|
||||||
return I;
|
return I;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string Get(const Poco::Net::IPAddress & IP) {
|
inline std::string Get(const Poco::Net::IPAddress &IP) {
|
||||||
if (!Enabled_)
|
if (!Enabled_)
|
||||||
return Default_;
|
return Default_;
|
||||||
return Get(ReformatAddress(IP.toString()));
|
return Get(ReformatAddress(IP.toString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string Get(const std::string & IP) {
|
inline std::string Get(const std::string &IP) {
|
||||||
if (!Enabled_)
|
if (!Enabled_)
|
||||||
return Default_;
|
return Default_;
|
||||||
try {
|
try {
|
||||||
@@ -178,10 +174,10 @@ namespace OpenWifi {
|
|||||||
std::string Response;
|
std::string Response;
|
||||||
if (Utils::wgets(URL, Response)) {
|
if (Utils::wgets(URL, Response)) {
|
||||||
auto Answer = Provider_->Country(Response);
|
auto Answer = Provider_->Country(Response);
|
||||||
if(!Answer.empty())
|
if (!Answer.empty())
|
||||||
return Answer;
|
return Answer;
|
||||||
}
|
}
|
||||||
} catch(...) {
|
} catch (...) {
|
||||||
}
|
}
|
||||||
return Default_;
|
return Default_;
|
||||||
}
|
}
|
||||||
@@ -189,17 +185,14 @@ namespace OpenWifi {
|
|||||||
inline auto Enabled() const { return Enabled_; }
|
inline auto Enabled() const { return Enabled_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool Enabled_=false;
|
bool Enabled_ = false;
|
||||||
std::string Default_;
|
std::string Default_;
|
||||||
std::unique_ptr<IPToCountryProvider> Provider_;
|
std::unique_ptr<IPToCountryProvider> Provider_;
|
||||||
std::string ProviderName_;
|
std::string ProviderName_;
|
||||||
|
|
||||||
FindCountryFromIP() noexcept:
|
FindCountryFromIP() noexcept : SubSystemServer("IpToCountry", "IPTOC-SVR", "iptocountry") {}
|
||||||
SubSystemServer("IpToCountry", "IPTOC-SVR", "iptocountry")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline auto FindCountryFromIP() { return FindCountryFromIP::instance(); }
|
inline auto FindCountryFromIP() { return FindCountryFromIP::instance(); }
|
||||||
|
|
||||||
}
|
} // namespace OpenWifi
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
void GWKafkaEvents::Send() {
|
void GWKafkaEvents::Send() {
|
||||||
if(KafkaManager()->Enabled()) {
|
if (KafkaManager()->Enabled()) {
|
||||||
Poco::JSON::Object Event;
|
Poco::JSON::Object Event;
|
||||||
Event.set("type", type_);
|
Event.set("type", type_);
|
||||||
Event.set("timestamp", timestamp_);
|
Event.set("timestamp", timestamp_);
|
||||||
|
|||||||
@@ -4,44 +4,40 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <Poco/JSON/Object.h>
|
#include <Poco/JSON/Object.h>
|
||||||
#include <framework/KafkaManager.h>
|
#include <framework/KafkaManager.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
class GWKafkaEvents {
|
class GWKafkaEvents {
|
||||||
public:
|
public:
|
||||||
GWKafkaEvents(const std::string &serialNumber, const std::string &type, std::uint64_t timestamp) :
|
GWKafkaEvents(const std::string &serialNumber, const std::string &type,
|
||||||
serialNumber_(serialNumber),
|
std::uint64_t timestamp)
|
||||||
type_(type),
|
: serialNumber_(serialNumber), type_(type), timestamp_(timestamp) {}
|
||||||
timestamp_(timestamp) {
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void SetPayload(Poco::JSON::Object::Ptr payload) {
|
inline void SetPayload(Poco::JSON::Object::Ptr payload) { payload_ = std::move(payload); }
|
||||||
payload_ = std::move(payload);
|
|
||||||
}
|
|
||||||
void Send();
|
void Send();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string serialNumber_;
|
std::string serialNumber_;
|
||||||
std::string type_;
|
std::string type_;
|
||||||
std::uint64_t timestamp_=0;
|
std::uint64_t timestamp_ = 0;
|
||||||
Poco::JSON::Object::Ptr payload_;
|
Poco::JSON::Object::Ptr payload_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DeviceFirmwareChangeKafkaEvent : public GWKafkaEvents {
|
class DeviceFirmwareChangeKafkaEvent : public GWKafkaEvents {
|
||||||
public:
|
public:
|
||||||
DeviceFirmwareChangeKafkaEvent( const std::string &serialNumber, std::uint64_t timestamp, const std::string &oldFirmware, const std::string &newFirmware) :
|
DeviceFirmwareChangeKafkaEvent(const std::string &serialNumber, std::uint64_t timestamp,
|
||||||
GWKafkaEvents(serialNumber,"unit.firmware_change", timestamp),
|
const std::string &oldFirmware,
|
||||||
oldFirmware_(oldFirmware),
|
const std::string &newFirmware)
|
||||||
newFirmware_(newFirmware) {
|
: GWKafkaEvents(serialNumber, "unit.firmware_change", timestamp),
|
||||||
}
|
oldFirmware_(oldFirmware), newFirmware_(newFirmware) {}
|
||||||
|
|
||||||
~DeviceFirmwareChangeKafkaEvent() {
|
~DeviceFirmwareChangeKafkaEvent() {
|
||||||
Poco::JSON::Object::Ptr payload = new Poco::JSON::Object;
|
Poco::JSON::Object::Ptr payload = new Poco::JSON::Object;
|
||||||
payload->set("oldFirmware", oldFirmware_);
|
payload->set("oldFirmware", oldFirmware_);
|
||||||
payload->set("newFirmware",newFirmware_);
|
payload->set("newFirmware", newFirmware_);
|
||||||
SetPayload(payload);
|
SetPayload(payload);
|
||||||
Send();
|
Send();
|
||||||
}
|
}
|
||||||
@@ -52,9 +48,9 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
class DeviceConfigurationChangeKafkaEvent : public GWKafkaEvents {
|
class DeviceConfigurationChangeKafkaEvent : public GWKafkaEvents {
|
||||||
public:
|
public:
|
||||||
DeviceConfigurationChangeKafkaEvent( const std::string &serialNumber, std::uint64_t timestamp, const std::string config) :
|
DeviceConfigurationChangeKafkaEvent(const std::string &serialNumber,
|
||||||
GWKafkaEvents(serialNumber,"unit.configuration_change", timestamp),
|
std::uint64_t timestamp, const std::string config)
|
||||||
config_(config) {
|
: GWKafkaEvents(serialNumber, "unit.configuration_change", timestamp), config_(config) {
|
||||||
}
|
}
|
||||||
|
|
||||||
~DeviceConfigurationChangeKafkaEvent() {
|
~DeviceConfigurationChangeKafkaEvent() {
|
||||||
@@ -70,11 +66,12 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
class DeviceBlacklistedKafkaEvent : public GWKafkaEvents {
|
class DeviceBlacklistedKafkaEvent : public GWKafkaEvents {
|
||||||
public:
|
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) :
|
explicit DeviceBlacklistedKafkaEvent(const std::string &serialNumber,
|
||||||
GWKafkaEvents(serialNumber,"blacklisted_device", timestamp),
|
std::uint64_t timestamp, const std::string &reason,
|
||||||
reason_(reason), author_(author), created_(created), IP_(IP)
|
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() {
|
~DeviceBlacklistedKafkaEvent() {
|
||||||
Poco::JSON::Object::Ptr payload = new Poco::JSON::Object;
|
Poco::JSON::Object::Ptr payload = new Poco::JSON::Object;
|
||||||
@@ -87,11 +84,9 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string reason_,author_;
|
std::string reason_, author_;
|
||||||
std::uint64_t created_;
|
std::uint64_t created_;
|
||||||
std::string IP_;
|
std::string IP_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace OpenWifi
|
} // namespace OpenWifi
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,23 +7,22 @@
|
|||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
GwWebSocketClient::GwWebSocketClient(Poco::Logger &Logger):
|
GwWebSocketClient::GwWebSocketClient(Poco::Logger &Logger) : Logger_(Logger) {
|
||||||
Logger_(Logger){
|
|
||||||
UI_WebSocketClientServer()->SetProcessor(this);
|
UI_WebSocketClientServer()->SetProcessor(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
GwWebSocketClient::~GwWebSocketClient() {
|
GwWebSocketClient::~GwWebSocketClient() { UI_WebSocketClientServer()->SetProcessor(nullptr); }
|
||||||
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 {
|
try {
|
||||||
if (O->has("command")) {
|
if (O->has("command")) {
|
||||||
auto Command = O->get("command").toString();
|
auto Command = O->get("command").toString();
|
||||||
if (Command == "serial_number_search" && O->has("serial_prefix")) {
|
if (Command == "serial_number_search" && O->has("serial_prefix")) {
|
||||||
ws_command_serial_number_search(O,Done,Answer);
|
ws_command_serial_number_search(O, Done, Answer);
|
||||||
} else if (Command=="exit") {
|
} else if (Command == "exit") {
|
||||||
ws_command_exit(O,Done,Answer);
|
ws_command_exit(O, Done, Answer);
|
||||||
} else {
|
} else {
|
||||||
ws_command_invalid(O, Done, Answer);
|
ws_command_invalid(O, Done, Answer);
|
||||||
}
|
}
|
||||||
@@ -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;
|
Done = true;
|
||||||
Answer = R"lit({ "closing" : "Goodbye! Aurevoir! Hasta la vista!" })lit";
|
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;
|
Done = false;
|
||||||
Answer = std::string{R"lit({ "error" : "invalid command" })lit"};
|
Answer = std::string{R"lit({ "error" : "invalid command" })lit"};
|
||||||
}
|
}
|
||||||
}
|
} // namespace OpenWifi
|
||||||
@@ -11,13 +11,15 @@ namespace OpenWifi {
|
|||||||
public:
|
public:
|
||||||
explicit GwWebSocketClient(Poco::Logger &Logger);
|
explicit GwWebSocketClient(Poco::Logger &Logger);
|
||||||
virtual ~GwWebSocketClient();
|
virtual ~GwWebSocketClient();
|
||||||
virtual void Processor(const Poco::JSON::Object::Ptr &O, std::string &Answer, bool &Done, const SecurityObjects::UserInfo &UserInfo);
|
virtual void Processor(const Poco::JSON::Object::Ptr &O, std::string &Answer, bool &Done,
|
||||||
void ws_command_serial_number_search( const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer);
|
const SecurityObjects::UserInfo &UserInfo);
|
||||||
void ws_command_exit( const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer);
|
void ws_command_serial_number_search(const Poco::JSON::Object::Ptr &O, bool &Done,
|
||||||
void ws_command_invalid( const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer);
|
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);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Poco::Logger & Logger_;
|
Poco::Logger &Logger_;
|
||||||
inline Poco::Logger & Logger() { return Logger_; }
|
inline Poco::Logger &Logger() { return Logger_; }
|
||||||
};
|
};
|
||||||
}
|
} // namespace OpenWifi
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
//
|
//
|
||||||
// Created by stephane bourque on 2021-06-17.
|
// Created by stephane bourque on 2021-06-17.
|
||||||
//
|
//
|
||||||
#include <thread>
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <thread>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "Poco/File.h"
|
||||||
|
#include "Poco/StreamCopier.h"
|
||||||
#include "Poco/String.h"
|
#include "Poco/String.h"
|
||||||
#include "Poco/StringTokenizer.h"
|
#include "Poco/StringTokenizer.h"
|
||||||
#include "Poco/URIStreamOpener.h"
|
#include "Poco/URIStreamOpener.h"
|
||||||
#include "Poco/StreamCopier.h"
|
|
||||||
#include "Poco/File.h"
|
|
||||||
|
|
||||||
#include "framework/MicroServiceFuncs.h"
|
#include "framework/MicroServiceFuncs.h"
|
||||||
#include "framework/utils.h"
|
#include "framework/utils.h"
|
||||||
@@ -27,20 +27,20 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
bool Recovered = false;
|
bool Recovered = false;
|
||||||
Poco::File OuiFile(CurrentOUIFileName_);
|
Poco::File OuiFile(CurrentOUIFileName_);
|
||||||
if(OuiFile.exists()) {
|
if (OuiFile.exists()) {
|
||||||
std::unique_lock Lock(LocalMutex_);
|
std::unique_lock Lock(LocalMutex_);
|
||||||
Recovered = ProcessFile(CurrentOUIFileName_,OUIs_);
|
Recovered = ProcessFile(CurrentOUIFileName_, OUIs_);
|
||||||
if(Recovered) {
|
if (Recovered) {
|
||||||
poco_notice(Logger(),
|
poco_notice(Logger(),
|
||||||
fmt::format("Recovered last OUI file - {}", CurrentOUIFileName_));
|
fmt::format("Recovered last OUI file - {}", CurrentOUIFileName_));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
poco_notice(Logger(),
|
poco_notice(Logger(), fmt::format("No existing OUIFile.", CurrentOUIFileName_));
|
||||||
fmt::format("No existing OUIFile.", CurrentOUIFileName_));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdaterCallBack_ = std::make_unique<Poco::TimerCallback<OUIServer>>(*this, &OUIServer::onTimer);
|
UpdaterCallBack_ =
|
||||||
if(Recovered) {
|
std::make_unique<Poco::TimerCallback<OUIServer>>(*this, &OUIServer::onTimer);
|
||||||
|
if (Recovered) {
|
||||||
Timer_.setStartInterval(60 * 60 * 1000); // first run in 1 hour
|
Timer_.setStartInterval(60 * 60 * 1000); // first run in 1 hour
|
||||||
} else {
|
} else {
|
||||||
Timer_.setStartInterval(30 * 1000); // first run in 5 minutes
|
Timer_.setStartInterval(30 * 1000); // first run in 5 minutes
|
||||||
@@ -51,15 +51,15 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OUIServer::Stop() {
|
void OUIServer::Stop() {
|
||||||
poco_notice(Logger(),"Stopping...");
|
poco_notice(Logger(), "Stopping...");
|
||||||
Running_=false;
|
Running_ = false;
|
||||||
Timer_.stop();
|
Timer_.stop();
|
||||||
poco_notice(Logger(),"Stopped...");
|
poco_notice(Logger(), "Stopped...");
|
||||||
}
|
}
|
||||||
|
|
||||||
void OUIServer::reinitialize([[maybe_unused]] Poco::Util::Application &self) {
|
void OUIServer::reinitialize([[maybe_unused]] Poco::Util::Application &self) {
|
||||||
MicroServiceLoadConfigurationFile();
|
MicroServiceLoadConfigurationFile();
|
||||||
poco_information(Logger(),"Reinitializing.");
|
poco_information(Logger(), "Reinitializing.");
|
||||||
Stop();
|
Stop();
|
||||||
Start();
|
Start();
|
||||||
}
|
}
|
||||||
@@ -67,14 +67,18 @@ namespace OpenWifi {
|
|||||||
bool OUIServer::GetFile(const std::string &FileName) {
|
bool OUIServer::GetFile(const std::string &FileName) {
|
||||||
try {
|
try {
|
||||||
LastUpdate_ = Utils::Now();
|
LastUpdate_ = Utils::Now();
|
||||||
poco_information(Logger(), fmt::format("Start: Retrieving OUI file: {}",MicroServiceConfigGetString("oui.download.uri","")));
|
poco_information(Logger(),
|
||||||
std::unique_ptr<std::istream> pStr(
|
fmt::format("Start: Retrieving OUI file: {}",
|
||||||
Poco::URIStreamOpener::defaultOpener().open(MicroServiceConfigGetString("oui.download.uri","")));
|
MicroServiceConfigGetString("oui.download.uri", "")));
|
||||||
|
std::unique_ptr<std::istream> pStr(Poco::URIStreamOpener::defaultOpener().open(
|
||||||
|
MicroServiceConfigGetString("oui.download.uri", "")));
|
||||||
std::ofstream OS;
|
std::ofstream OS;
|
||||||
OS.open(FileName);
|
OS.open(FileName);
|
||||||
Poco::StreamCopier::copyStream(*pStr, OS);
|
Poco::StreamCopier::copyStream(*pStr, OS);
|
||||||
OS.close();
|
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;
|
return true;
|
||||||
} catch (const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
Logger().log(E);
|
Logger().log(E);
|
||||||
@@ -82,13 +86,13 @@ namespace OpenWifi {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OUIServer::ProcessFile( const std::string &FileName, OUIMap &Map) {
|
bool OUIServer::ProcessFile(const std::string &FileName, OUIMap &Map) {
|
||||||
try {
|
try {
|
||||||
std::ifstream Input;
|
std::ifstream Input;
|
||||||
Input.open(FileName, std::ios::binary);
|
Input.open(FileName, std::ios::binary);
|
||||||
|
|
||||||
while (!Input.eof()) {
|
while (!Input.eof()) {
|
||||||
if(!Running_)
|
if (!Running_)
|
||||||
return false;
|
return false;
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
Input.getline(buf, sizeof(buf));
|
Input.getline(buf, sizeof(buf));
|
||||||
@@ -112,67 +116,68 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} catch ( const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
Logger().log(E);
|
Logger().log(E);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OUIServer::onTimer([[maybe_unused]] Poco::Timer & timer) {
|
void OUIServer::onTimer([[maybe_unused]] Poco::Timer &timer) {
|
||||||
Utils::SetThreadName("ouisvr-timer");
|
Utils::SetThreadName("ouisvr-timer");
|
||||||
if(Updating_)
|
if (Updating_)
|
||||||
return;
|
return;
|
||||||
Updating_ = true;
|
Updating_ = true;
|
||||||
|
|
||||||
poco_information(Logger(),"Starting to process OUI file...");
|
poco_information(Logger(), "Starting to process OUI file...");
|
||||||
|
|
||||||
// fetch data from server, if not available, just use the file we already have.
|
// fetch data from server, if not available, just use the file we already have.
|
||||||
Poco::File Current(CurrentOUIFileName_);
|
Poco::File Current(CurrentOUIFileName_);
|
||||||
if(Current.exists()) {
|
if (Current.exists()) {
|
||||||
if((Utils::Now()-Current.getLastModified().epochTime()) < (7*24*60*60)) {
|
if ((Utils::Now() - Current.getLastModified().epochTime()) < (7 * 24 * 60 * 60)) {
|
||||||
if(!Initialized_) {
|
if (!Initialized_) {
|
||||||
if(ProcessFile(CurrentOUIFileName_, OUIs_)) {
|
if (ProcessFile(CurrentOUIFileName_, OUIs_)) {
|
||||||
Initialized_ = true;
|
Initialized_ = true;
|
||||||
Updating_=false;
|
Updating_ = false;
|
||||||
poco_information(Logger(), "Using cached file.");
|
poco_information(Logger(), "Using cached file.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Updating_=false;
|
Updating_ = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OUIMap TmpOUIs;
|
OUIMap TmpOUIs;
|
||||||
if(GetFile(LatestOUIFileName_) && ProcessFile(LatestOUIFileName_, TmpOUIs)) {
|
if (GetFile(LatestOUIFileName_) && ProcessFile(LatestOUIFileName_, TmpOUIs)) {
|
||||||
std::unique_lock G(LocalMutex_);
|
std::unique_lock G(LocalMutex_);
|
||||||
OUIs_ = std::move(TmpOUIs);
|
OUIs_ = std::move(TmpOUIs);
|
||||||
LastUpdate_ = Utils::Now();
|
LastUpdate_ = Utils::Now();
|
||||||
Poco::File F1(CurrentOUIFileName_);
|
Poco::File F1(CurrentOUIFileName_);
|
||||||
if(F1.exists())
|
if (F1.exists())
|
||||||
F1.remove();
|
F1.remove();
|
||||||
Poco::File F2(LatestOUIFileName_);
|
Poco::File F2(LatestOUIFileName_);
|
||||||
F2.renameTo(CurrentOUIFileName_);
|
F2.renameTo(CurrentOUIFileName_);
|
||||||
poco_information(Logger(), fmt::format("New OUI file {} downloaded.",LatestOUIFileName_));
|
poco_information(Logger(),
|
||||||
} else if(OUIs_.empty()) {
|
fmt::format("New OUI file {} downloaded.", LatestOUIFileName_));
|
||||||
if(ProcessFile(CurrentOUIFileName_, TmpOUIs)) {
|
} else if (OUIs_.empty()) {
|
||||||
|
if (ProcessFile(CurrentOUIFileName_, TmpOUIs)) {
|
||||||
LastUpdate_ = Utils::Now();
|
LastUpdate_ = Utils::Now();
|
||||||
std::unique_lock G(LocalMutex_);
|
std::unique_lock G(LocalMutex_);
|
||||||
OUIs_ = std::move(TmpOUIs);
|
OUIs_ = std::move(TmpOUIs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Initialized_=true;
|
Initialized_ = true;
|
||||||
Updating_ = false;
|
Updating_ = false;
|
||||||
poco_information(Logger(),"Done processing OUI file...");
|
poco_information(Logger(), "Done processing OUI file...");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string OUIServer::GetManufacturer(const std::string &MAC) {
|
std::string OUIServer::GetManufacturer(const std::string &MAC) {
|
||||||
std::shared_lock Lock(LocalMutex_);
|
std::shared_lock Lock(LocalMutex_);
|
||||||
|
|
||||||
auto Manufacturer = OUIs_.find(Utils::SerialNumberToOUI(MAC));
|
auto Manufacturer = OUIs_.find(Utils::SerialNumberToOUI(MAC));
|
||||||
if(Manufacturer != OUIs_.end())
|
if (Manufacturer != OUIs_.end())
|
||||||
return Manufacturer->second;
|
return Manufacturer->second;
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
};
|
}; // namespace OpenWifi
|
||||||
|
|||||||
@@ -14,8 +14,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
class OUIServer : public SubSystemServer {
|
class OUIServer : public SubSystemServer {
|
||||||
public:
|
public:
|
||||||
|
typedef std::map<uint64_t, std::string> OUIMap;
|
||||||
typedef std::map<uint64_t,std::string> OUIMap;
|
|
||||||
|
|
||||||
static auto instance() {
|
static auto instance() {
|
||||||
static auto instance_ = new OUIServer;
|
static auto instance_ = new OUIServer;
|
||||||
@@ -25,7 +24,7 @@ namespace OpenWifi {
|
|||||||
int Start() override;
|
int Start() override;
|
||||||
void Stop() override;
|
void Stop() override;
|
||||||
|
|
||||||
void onTimer(Poco::Timer & timer);
|
void onTimer(Poco::Timer &timer);
|
||||||
|
|
||||||
void reinitialize(Poco::Util::Application &self) override;
|
void reinitialize(Poco::Util::Application &self) override;
|
||||||
[[nodiscard]] std::string GetManufacturer(const std::string &MAC);
|
[[nodiscard]] std::string GetManufacturer(const std::string &MAC);
|
||||||
@@ -34,22 +33,18 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_mutex LocalMutex_;
|
std::shared_mutex LocalMutex_;
|
||||||
uint64_t LastUpdate_ = 0 ;
|
uint64_t LastUpdate_ = 0;
|
||||||
bool Initialized_ = false;
|
bool Initialized_ = false;
|
||||||
OUIMap OUIs_;
|
OUIMap OUIs_;
|
||||||
volatile std::atomic_bool Updating_=false;
|
volatile std::atomic_bool Updating_ = false;
|
||||||
volatile std::atomic_bool Running_=false;
|
volatile std::atomic_bool Running_ = false;
|
||||||
Poco::Timer Timer_;
|
Poco::Timer Timer_;
|
||||||
std::unique_ptr<Poco::TimerCallback<OUIServer>> UpdaterCallBack_;
|
std::unique_ptr<Poco::TimerCallback<OUIServer>> UpdaterCallBack_;
|
||||||
std::string LatestOUIFileName_,CurrentOUIFileName_;
|
std::string LatestOUIFileName_, CurrentOUIFileName_;
|
||||||
|
|
||||||
OUIServer() noexcept:
|
OUIServer() noexcept : SubSystemServer("OUIServer", "OUI-SVR", "ouiserver") {}
|
||||||
SubSystemServer("OUIServer", "OUI-SVR", "ouiserver")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline auto OUIServer() { return OUIServer::instance(); }
|
inline auto OUIServer() { return OUIServer::instance(); }
|
||||||
|
|
||||||
}
|
} // namespace OpenWifi
|
||||||
|
|
||||||
|
|||||||
1305
src/ParseWifiScan.h
1305
src/ParseWifiScan.h
File diff suppressed because it is too large
Load Diff
@@ -4,15 +4,15 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <iomanip>
|
||||||
|
#include <iostream>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iostream>
|
|
||||||
#include <iomanip>
|
|
||||||
|
|
||||||
#include "Poco/HMACEngine.h"
|
#include "Poco/HMACEngine.h"
|
||||||
#include "Poco/MD5Engine.h"
|
#include "Poco/MD5Engine.h"
|
||||||
#include "Poco/StringTokenizer.h"
|
|
||||||
#include "Poco/Net/SocketAddress.h"
|
#include "Poco/Net/SocketAddress.h"
|
||||||
|
#include "Poco/StringTokenizer.h"
|
||||||
|
|
||||||
namespace OpenWifi::RADIUS {
|
namespace OpenWifi::RADIUS {
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ namespace OpenWifi::RADIUS {
|
|||||||
#define RADCMD_COA_NAK 45 /* CoA-NAK */
|
#define RADCMD_COA_NAK 45 /* CoA-NAK */
|
||||||
#define RADCMD_RESERVED 255 /* Reserved */
|
#define RADCMD_RESERVED 255 /* Reserved */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
21 Resource-Free-Request [RFC3575]
|
21 Resource-Free-Request [RFC3575]
|
||||||
22 Resource-Free-Response [RFC3575]
|
22 Resource-Free-Response [RFC3575]
|
||||||
23 Resource-Query-Request [RFC3575]
|
23 Resource-Query-Request [RFC3575]
|
||||||
@@ -75,16 +75,16 @@ namespace OpenWifi::RADIUS {
|
|||||||
250-253 Experimental Use [RFC3575]
|
250-253 Experimental Use [RFC3575]
|
||||||
254 Reserved [RFC3575]
|
254 Reserved [RFC3575]
|
||||||
255 Reserved [RFC3575]
|
255 Reserved [RFC3575]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct tok {
|
struct tok {
|
||||||
uint cmd;
|
uint cmd;
|
||||||
const char * name;
|
const char *name;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
Radius commands
|
Radius commands
|
||||||
|
|
||||||
char const *fr_packet_codes[FR_MAX_PACKET_CODE] = {
|
char const *fr_packet_codes[FR_MAX_PACKET_CODE] = {
|
||||||
"", //!< 0
|
"", //!< 0
|
||||||
@@ -139,128 +139,125 @@ Radius commands
|
|||||||
"49",
|
"49",
|
||||||
"IP-Address-Allocate",
|
"IP-Address-Allocate",
|
||||||
"IP-Address-Release", //!< 50
|
"IP-Address-Release", //!< 50
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static const struct tok radius_command_values[] = {
|
static const struct tok radius_command_values[] = {
|
||||||
{ RADCMD_ACCESS_REQ, "Access-Request" },
|
{RADCMD_ACCESS_REQ, "Access-Request"},
|
||||||
{ RADCMD_ACCESS_ACC, "Access-Accept" },
|
{RADCMD_ACCESS_ACC, "Access-Accept"},
|
||||||
{ RADCMD_ACCESS_REJ, "Access-Reject" },
|
{RADCMD_ACCESS_REJ, "Access-Reject"},
|
||||||
{ RADCMD_ACCOUN_REQ, "Accounting-Request" },
|
{RADCMD_ACCOUN_REQ, "Accounting-Request"},
|
||||||
{ RADCMD_ACCOUN_RES, "Accounting-Response" },
|
{RADCMD_ACCOUN_RES, "Accounting-Response"},
|
||||||
{ RADCMD_ACCESS_CHA, "Access-Challenge" },
|
{RADCMD_ACCESS_CHA, "Access-Challenge"},
|
||||||
{ RADCMD_STATUS_SER, "Status-Server" },
|
{RADCMD_STATUS_SER, "Status-Server"},
|
||||||
{ RADCMD_STATUS_CLI, "Status-Client" },
|
{RADCMD_STATUS_CLI, "Status-Client"},
|
||||||
{ RADCMD_DISCON_REQ, "Disconnect-Request" },
|
{RADCMD_DISCON_REQ, "Disconnect-Request"},
|
||||||
{ RADCMD_DISCON_ACK, "Disconnect-ACK" },
|
{RADCMD_DISCON_ACK, "Disconnect-ACK"},
|
||||||
{ RADCMD_DISCON_NAK, "Disconnect-NAK" },
|
{RADCMD_DISCON_NAK, "Disconnect-NAK"},
|
||||||
{ RADCMD_COA_REQ, "CoA-Request" },
|
{RADCMD_COA_REQ, "CoA-Request"},
|
||||||
{ RADCMD_COA_ACK, "CoA-ACK" },
|
{RADCMD_COA_ACK, "CoA-ACK"},
|
||||||
{ RADCMD_COA_NAK, "CoA-NAK" },
|
{RADCMD_COA_NAK, "CoA-NAK"},
|
||||||
{ RADCMD_RESERVED, "Reserved" },
|
{RADCMD_RESERVED, "Reserved"},
|
||||||
{ RADCMD_ACCOUN_STATUS, "Accounting-Status"},
|
{RADCMD_ACCOUN_STATUS, "Accounting-Status"},
|
||||||
{ RADCMD_PASSWORD_REQUEST, "Password-Request"},
|
{RADCMD_PASSWORD_REQUEST, "Password-Request"},
|
||||||
{ RADCMD_PASSWORD_ACK, "Password-Ack"},
|
{RADCMD_PASSWORD_ACK, "Password-Ack"},
|
||||||
{ RADCMD_PASSWORD_REJECT, "Password-Reject"},
|
{RADCMD_PASSWORD_REJECT, "Password-Reject"},
|
||||||
{ RADCMD_ACCOUN_MESSAGE, "Accounting-Message"},
|
{RADCMD_ACCOUN_MESSAGE, "Accounting-Message"},
|
||||||
{ RADCMD_RES_FREE_REQ, "Resource-Free-Request"},
|
{RADCMD_RES_FREE_REQ, "Resource-Free-Request"},
|
||||||
{ RADCMD_RES_FREE_RES, "Resource-Free-Response"},
|
{RADCMD_RES_FREE_RES, "Resource-Free-Response"},
|
||||||
{ RADCMD_RES_QUERY_REQ, "Resource-Query-Request"},
|
{RADCMD_RES_QUERY_REQ, "Resource-Query-Request"},
|
||||||
{ RADCMD_RES_QUERY_RES, "Resource-Query-Response"},
|
{RADCMD_RES_QUERY_RES, "Resource-Query-Response"},
|
||||||
{ RADCMD_RES_ALT_RECLAIM_REQ, "Alternate-Resource-Reclaim-Request"},
|
{RADCMD_RES_ALT_RECLAIM_REQ, "Alternate-Resource-Reclaim-Request"},
|
||||||
{ 0, nullptr}
|
{0, nullptr}};
|
||||||
};
|
|
||||||
|
|
||||||
static const struct tok radius_attribute_names[] = {
|
static const struct tok radius_attribute_names[] = {{1, "User-Name"},
|
||||||
{1,"User-Name"},
|
{2, "User-Password"},
|
||||||
{2,"User-Password"},
|
{3, "CHAP-Password"},
|
||||||
{3,"CHAP-Password"},
|
{4, "NAS-IP Address"},
|
||||||
{4,"NAS-IP Address"},
|
{5, "NAS-Port"},
|
||||||
{5,"NAS-Port"},
|
{6, "Service-Type"},
|
||||||
{6,"Service-Type"},
|
{7, "Framed-Protocol"},
|
||||||
{7,"Framed-Protocol"},
|
{8, "Framed-IP-Address"},
|
||||||
{8,"Framed-IP-Address"},
|
{9, "Framed-IP-Netmask"},
|
||||||
{9,"Framed-IP-Netmask"},
|
{10, "Framed-Routing"},
|
||||||
{10,"Framed-Routing"},
|
{11, "Filter-Id"},
|
||||||
{11,"Filter-Id"},
|
{12, "Framed-MTU"},
|
||||||
{12,"Framed-MTU"},
|
{13, "Framed-Compression"},
|
||||||
{13,"Framed-Compression"},
|
{14, "Login-IP-Host"},
|
||||||
{14,"Login-IP-Host"},
|
{15, "Login-Service"},
|
||||||
{15,"Login-Service"},
|
{16, "Login-TCP-Port"},
|
||||||
{16,"Login-TCP-Port"},
|
{18, "Reply-Message"},
|
||||||
{18,"Reply-Message"},
|
{19, "Callback-Number"},
|
||||||
{19,"Callback-Number"},
|
{20, "Callback-ID"},
|
||||||
{20,"Callback-ID"},
|
{22, "Framed-Route"},
|
||||||
{22,"Framed-Route"},
|
{23, "Framed-IPX-Network"},
|
||||||
{23,"Framed-IPX-Network"},
|
{24, "State"},
|
||||||
{24,"State"},
|
{25, "Class"},
|
||||||
{25,"Class"},
|
{26, "Vendor-Specific"},
|
||||||
{26,"Vendor-Specific"},
|
{27, "Session-Timeout"},
|
||||||
{27,"Session-Timeout"},
|
{28, "Idle-Timeout"},
|
||||||
{28,"Idle-Timeout"},
|
{29, "Termination-Action"},
|
||||||
{29,"Termination-Action"},
|
{30, "Called-Station-Id"},
|
||||||
{30,"Called-Station-Id"},
|
{31, "Calling-Station-Id"},
|
||||||
{31,"Calling-Station-Id"},
|
{32, "NAS-Identifier"},
|
||||||
{32,"NAS-Identifier"},
|
{33, "Proxy-State"},
|
||||||
{33,"Proxy-State"},
|
{34, "Login-LAT-Service"},
|
||||||
{34,"Login-LAT-Service"},
|
{35, "Login-LAT-Node"},
|
||||||
{35,"Login-LAT-Node"},
|
{36, "Login-LAT-Group"},
|
||||||
{36,"Login-LAT-Group"},
|
{37, "Framed-AppleTalk-Link"},
|
||||||
{37,"Framed-AppleTalk-Link"},
|
{38, "Framed-AppleTalk-Network"},
|
||||||
{38,"Framed-AppleTalk-Network"},
|
{39, "Framed-AppleTalk-Zone"},
|
||||||
{39,"Framed-AppleTalk-Zone"},
|
{40, "Acct-Status-Type"},
|
||||||
{40,"Acct-Status-Type"},
|
{41, "Acct-Delay-Time"},
|
||||||
{41,"Acct-Delay-Time"},
|
{42, "Acct-Input-Octets"},
|
||||||
{42,"Acct-Input-Octets"},
|
{43, "Acct-Output-Octets"},
|
||||||
{43,"Acct-Output-Octets"},
|
{44, "Acct-Session-Id"},
|
||||||
{44,"Acct-Session-Id"},
|
{45, "Acct-Authentic"},
|
||||||
{45,"Acct-Authentic"},
|
{46, "Acct-Session-Time"},
|
||||||
{46,"Acct-Session-Time"},
|
{47, "Acct-Input-Packets"},
|
||||||
{47,"Acct-Input-Packets"},
|
{48, "Acct-Output-Packets"},
|
||||||
{48,"Acct-Output-Packets"},
|
{49, "Acct-Terminate-Cause"},
|
||||||
{49,"Acct-Terminate-Cause"},
|
{50, "Acct-Multi-Session-Id"},
|
||||||
{50,"Acct-Multi-Session-Id"},
|
{51, "Acct-Link-Count"},
|
||||||
{51,"Acct-Link-Count"},
|
{52, "Acct-Input-Gigawords"},
|
||||||
{52,"Acct-Input-Gigawords"},
|
{53, "Acct-Output-Gigawords"},
|
||||||
{53,"Acct-Output-Gigawords"},
|
{55, "Event-Timestamp"},
|
||||||
{55,"Event-Timestamp"},
|
{60, "CHAP-Challenge"},
|
||||||
{60,"CHAP-Challenge"},
|
{61, "NAS-Port-Type"},
|
||||||
{61,"NAS-Port-Type"},
|
{62, "Port-Limit"},
|
||||||
{62,"Port-Limit"},
|
{63, "Login-LAT-Port"},
|
||||||
{63,"Login-LAT-Port"},
|
{64, "Tunnel-Type3"},
|
||||||
{64,"Tunnel-Type3"},
|
{65, "Tunnel-Medium-Type1"},
|
||||||
{65,"Tunnel-Medium-Type1"},
|
{66, "Tunnel-Client-Endpoint"},
|
||||||
{66,"Tunnel-Client-Endpoint"},
|
{67, "Tunnel-Server-Endpoint1"},
|
||||||
{67,"Tunnel-Server-Endpoint1"},
|
{68, "Acct-Tunnel-Connection-ID"},
|
||||||
{68,"Acct-Tunnel-Connection-ID"},
|
{69, "Tunnel-Password1"},
|
||||||
{69,"Tunnel-Password1"},
|
{70, "ARAP-Password"},
|
||||||
{70,"ARAP-Password"},
|
{71, "ARAP-Features"},
|
||||||
{71,"ARAP-Features"},
|
{72, "ARAP-Zone-Access"},
|
||||||
{72,"ARAP-Zone-Access"},
|
{73, "ARAP-Security"},
|
||||||
{73,"ARAP-Security"},
|
{74, "ARAP-Security-Data"},
|
||||||
{74,"ARAP-Security-Data"},
|
{75, "Password-Retry"},
|
||||||
{75,"Password-Retry"},
|
{76, "Prompt"},
|
||||||
{76,"Prompt"},
|
{77, "Connect-Info"},
|
||||||
{77,"Connect-Info"},
|
{78, "Configuration-Token"},
|
||||||
{78,"Configuration-Token"},
|
{79, "EAP-Message"},
|
||||||
{79,"EAP-Message"},
|
{80, "Message-Authenticator"},
|
||||||
{80,"Message-Authenticator"},
|
{81, "Tunnel-Private-Group-ID"},
|
||||||
{81,"Tunnel-Private-Group-ID"},
|
{82, "Tunnel-Assignment-ID1"},
|
||||||
{82,"Tunnel-Assignment-ID1"},
|
{83, "Tunnel-Preference"},
|
||||||
{83,"Tunnel-Preference"},
|
{84, "ARAP-Challenge-Response"},
|
||||||
{84,"ARAP-Challenge-Response"},
|
{85, "Acct-Interim-Interval"},
|
||||||
{85,"Acct-Interim-Interval"},
|
{86, "Acct-Tunnel-Packets-Lost"},
|
||||||
{86,"Acct-Tunnel-Packets-Lost"},
|
{87, "NAS-Port-ID"},
|
||||||
{87,"NAS-Port-ID"},
|
{88, "Framed-Pool"},
|
||||||
{88,"Framed-Pool"},
|
{90, "Tunnel-Client-Auth-ID"},
|
||||||
{90,"Tunnel-Client-Auth-ID"},
|
{91, "Tunnel-Server-Auth-ID"},
|
||||||
{91,"Tunnel-Server-Auth-ID"},
|
{0, nullptr}};
|
||||||
{0, nullptr}
|
|
||||||
};
|
|
||||||
|
|
||||||
#pragma pack(push,1)
|
#pragma pack(push, 1)
|
||||||
struct RadiusAttribute {
|
struct RadiusAttribute {
|
||||||
unsigned char type{0};
|
unsigned char type{0};
|
||||||
uint16_t pos{0};
|
uint16_t pos{0};
|
||||||
@@ -295,47 +292,42 @@ static const struct tok radius_attribute_names[] = {
|
|||||||
constexpr unsigned char ATTR_MessageAuthenticator = 80;
|
constexpr unsigned char ATTR_MessageAuthenticator = 80;
|
||||||
|
|
||||||
inline bool IsAuthentication(unsigned char t) {
|
inline bool IsAuthentication(unsigned char t) {
|
||||||
return (t == RADIUS::Access_Request ||
|
return (t == RADIUS::Access_Request || t == RADIUS::Access_Accept ||
|
||||||
t == RADIUS::Access_Accept ||
|
t == RADIUS::Access_Challenge || t == RADIUS::Access_Reject);
|
||||||
t == RADIUS::Access_Challenge ||
|
|
||||||
t == RADIUS::Access_Reject);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsAccounting(unsigned char t) {
|
inline bool IsAccounting(unsigned char t) {
|
||||||
return (t == RADIUS::Accounting_Request ||
|
return (t == RADIUS::Accounting_Request || t == RADIUS::Accounting_Response ||
|
||||||
t == RADIUS::Accounting_Response ||
|
t == RADIUS::Accounting_Status || t == RADIUS::Accounting_Message);
|
||||||
t == RADIUS::Accounting_Status ||
|
|
||||||
t == RADIUS::Accounting_Message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsAuthority(unsigned char t) {
|
inline bool IsAuthority(unsigned char t) {
|
||||||
return (t == RADIUS::Disconnect_Request ||
|
return (t == RADIUS::Disconnect_Request || t == RADIUS::Disconnect_ACK ||
|
||||||
t == RADIUS::Disconnect_ACK ||
|
t == RADIUS::Disconnect_NAK || t == RADIUS::CoA_Request || t == RADIUS::CoA_ACK ||
|
||||||
t == RADIUS::Disconnect_NAK ||
|
|
||||||
t == RADIUS::CoA_Request ||
|
|
||||||
t == RADIUS::CoA_ACK ||
|
|
||||||
t == RADIUS::CoA_NAK);
|
t == RADIUS::CoA_NAK);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const char * CommandName(uint cmd) {
|
inline const char *CommandName(uint cmd) {
|
||||||
auto cmds = radius_command_values;
|
auto cmds = radius_command_values;
|
||||||
while(cmds->cmd && (cmds->cmd!=cmd))
|
while (cmds->cmd && (cmds->cmd != cmd))
|
||||||
cmds++;
|
cmds++;
|
||||||
if(cmds->cmd==cmd) return cmds->name;
|
if (cmds->cmd == cmd)
|
||||||
|
return cmds->name;
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const char * AttributeName(uint cmd) {
|
inline const char *AttributeName(uint cmd) {
|
||||||
auto cmds = radius_attribute_names;
|
auto cmds = radius_attribute_names;
|
||||||
while(cmds->cmd && (cmds->cmd!=cmd))
|
while (cmds->cmd && (cmds->cmd != cmd))
|
||||||
cmds++;
|
cmds++;
|
||||||
if(cmds->cmd==cmd) return cmds->name;
|
if (cmds->cmd == cmd)
|
||||||
|
return cmds->name;
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void MakeRadiusAuthenticator(unsigned char *authenticator) {
|
inline void MakeRadiusAuthenticator(unsigned char *authenticator) {
|
||||||
for(int i=0;i<16;i++)
|
for (int i = 0; i < 16; i++)
|
||||||
authenticator[i]=std::rand() & 0xff;
|
authenticator[i] = std::rand() & 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -349,29 +341,35 @@ static const struct tok radius_attribute_names[] = {
|
|||||||
using AttributeList = std::list<RadiusAttribute>;
|
using AttributeList = std::list<RadiusAttribute>;
|
||||||
|
|
||||||
inline std::ostream &operator<<(std::ostream &os, AttributeList const &P) {
|
inline std::ostream &operator<<(std::ostream &os, AttributeList const &P) {
|
||||||
for(const auto &attr: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;
|
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();
|
Attrs.clear();
|
||||||
uint16_t pos=0;
|
uint16_t pos = 0;
|
||||||
auto x=25;
|
auto x = 25;
|
||||||
while(pos<Size && x) {
|
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],
|
||||||
if(pos+Attr.len<=Size) {
|
.pos = (uint16_t)(pos + 2 + offset),
|
||||||
|
.len = (unsigned int)(Buffer[pos + 1] - 2)};
|
||||||
|
if (pos + Attr.len <= Size) {
|
||||||
Attrs.emplace_back(Attr);
|
Attrs.emplace_back(Attr);
|
||||||
} else {
|
} 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;
|
return false;
|
||||||
}
|
}
|
||||||
if(Buffer[pos+1]==0) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
pos+=Buffer[pos+1];
|
pos += Buffer[pos + 1];
|
||||||
x--;
|
x--;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -379,40 +377,40 @@ static const struct tok radius_attribute_names[] = {
|
|||||||
|
|
||||||
class RadiusPacket {
|
class RadiusPacket {
|
||||||
public:
|
public:
|
||||||
explicit RadiusPacket(const Poco::Buffer<char> & Buf) {
|
explicit RadiusPacket(const Poco::Buffer<char> &Buf) {
|
||||||
if(Buf.size() >= sizeof(RawRadiusPacket)) {
|
if (Buf.size() >= sizeof(RawRadiusPacket)) {
|
||||||
Valid_ = false;
|
Valid_ = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memcpy((void *)&P_,Buf.begin(), Buf.size());
|
memcpy((void *)&P_, Buf.begin(), Buf.size());
|
||||||
Size_=Buf.size();
|
Size_ = Buf.size();
|
||||||
Valid_ = (Size_== htons(P_.rawlen));
|
Valid_ = (Size_ == htons(P_.rawlen));
|
||||||
if(Valid_)
|
if (Valid_)
|
||||||
Valid_ = ParseRadius(0,(unsigned char *)&P_.attributes[0],Size_-20,Attrs_);
|
Valid_ = ParseRadius(0, (unsigned char *)&P_.attributes[0], Size_ - 20, Attrs_);
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit RadiusPacket(const unsigned char *buffer, uint16_t size) {
|
explicit RadiusPacket(const unsigned char *buffer, uint16_t size) {
|
||||||
if(size >= sizeof(RawRadiusPacket)) {
|
if (size >= sizeof(RawRadiusPacket)) {
|
||||||
Valid_ = false;
|
Valid_ = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memcpy((void *)&P_,buffer, size);
|
memcpy((void *)&P_, buffer, size);
|
||||||
Size_=size;
|
Size_ = size;
|
||||||
Valid_ = (Size_== htons(P_.rawlen));
|
Valid_ = (Size_ == htons(P_.rawlen));
|
||||||
if(Valid_)
|
if (Valid_)
|
||||||
Valid_ = ParseRadius(0,(unsigned char *)&P_.attributes[0],Size_-20,Attrs_);
|
Valid_ = ParseRadius(0, (unsigned char *)&P_.attributes[0], Size_ - 20, Attrs_);
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit RadiusPacket(const std::string &p) {
|
explicit RadiusPacket(const std::string &p) {
|
||||||
if(p.size() >= sizeof(RawRadiusPacket)) {
|
if (p.size() >= sizeof(RawRadiusPacket)) {
|
||||||
Valid_ = false;
|
Valid_ = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memcpy((void *)&P_,(const unsigned char*) p.c_str(), p.size());
|
memcpy((void *)&P_, (const unsigned char *)p.c_str(), p.size());
|
||||||
Size_=p.size();
|
Size_ = p.size();
|
||||||
Valid_ = (Size_== htons(P_.rawlen));
|
Valid_ = (Size_ == htons(P_.rawlen));
|
||||||
if(Valid_)
|
if (Valid_)
|
||||||
Valid_ = ParseRadius(0,(unsigned char *)&P_.attributes[0],Size_-20,Attrs_);
|
Valid_ = ParseRadius(0, (unsigned char *)&P_.attributes[0], Size_ - 20, Attrs_);
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit RadiusPacket(const RadiusPacket &P) {
|
explicit RadiusPacket(const RadiusPacket &P) {
|
||||||
@@ -424,12 +422,12 @@ static const struct tok radius_attribute_names[] = {
|
|||||||
|
|
||||||
explicit RadiusPacket() = default;
|
explicit RadiusPacket() = default;
|
||||||
|
|
||||||
unsigned char * Buffer() { return (unsigned char *)&P_; }
|
unsigned char *Buffer() { return (unsigned char *)&P_; }
|
||||||
[[nodiscard]] uint16_t BufferLen() const { return sizeof(P_);}
|
[[nodiscard]] uint16_t BufferLen() const { return sizeof(P_); }
|
||||||
|
|
||||||
void Evaluate(uint16_t size) {
|
void Evaluate(uint16_t size) {
|
||||||
Size_ = size;
|
Size_ = size;
|
||||||
Valid_ = ParseRadius(0,(unsigned char *)&P_.attributes[0],Size_-20,Attrs_);
|
Valid_ = ParseRadius(0, (unsigned char *)&P_.attributes[0], Size_ - 20, Attrs_);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] uint16_t Len() const { return htons(P_.rawlen); }
|
[[nodiscard]] uint16_t Len() const { return htons(P_.rawlen); }
|
||||||
@@ -438,62 +436,51 @@ static const struct tok radius_attribute_names[] = {
|
|||||||
friend std::ostream &operator<<(std::ostream &os, RadiusPacket const &P);
|
friend std::ostream &operator<<(std::ostream &os, RadiusPacket const &P);
|
||||||
|
|
||||||
inline bool IsAuthentication() {
|
inline bool IsAuthentication() {
|
||||||
return (P_.code == RADIUS::Access_Request ||
|
return (P_.code == RADIUS::Access_Request || P_.code == RADIUS::Access_Accept ||
|
||||||
P_.code == RADIUS::Access_Accept ||
|
P_.code == RADIUS::Access_Challenge || P_.code == RADIUS::Access_Reject ||
|
||||||
P_.code == RADIUS::Access_Challenge ||
|
P_.code == RADCMD_RES_FREE_REQ || P_.code == RADCMD_RES_FREE_RES ||
|
||||||
P_.code == RADIUS::Access_Reject ||
|
P_.code == RADCMD_RES_QUERY_REQ || P_.code == RADCMD_RES_QUERY_RES ||
|
||||||
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);
|
P_.code == RADCMD_RES_ALT_RECLAIM_REQ);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsAccounting() {
|
inline bool IsAccounting() {
|
||||||
return (P_.code == RADIUS::Accounting_Request ||
|
return (P_.code == RADIUS::Accounting_Request ||
|
||||||
P_.code == RADIUS::Accounting_Response ||
|
P_.code == RADIUS::Accounting_Response ||
|
||||||
P_.code == RADIUS::Accounting_Status ||
|
P_.code == RADIUS::Accounting_Status || P_.code == RADIUS::Accounting_Message);
|
||||||
P_.code == RADIUS::Accounting_Message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsAuthority() {
|
inline bool IsAuthority() {
|
||||||
return (P_.code == RADIUS::Disconnect_Request ||
|
return (P_.code == RADIUS::Disconnect_Request || P_.code == RADIUS::Disconnect_ACK ||
|
||||||
P_.code == RADIUS::Disconnect_ACK ||
|
P_.code == RADIUS::Disconnect_NAK || P_.code == RADIUS::CoA_Request ||
|
||||||
P_.code == RADIUS::Disconnect_NAK ||
|
P_.code == RADIUS::CoA_ACK || P_.code == RADIUS::CoA_NAK);
|
||||||
P_.code == RADIUS::CoA_Request ||
|
|
||||||
P_.code == RADIUS::CoA_ACK ||
|
|
||||||
P_.code == RADIUS::CoA_NAK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Log(std::ostream &os) {
|
void Log(std::ostream &os) {
|
||||||
uint16_t p = 0;
|
uint16_t p = 0;
|
||||||
|
|
||||||
while(p<Size_) {
|
while (p < Size_) {
|
||||||
os << std::setfill('0') << std::setw(4) << p << ": ";
|
os << std::setfill('0') << std::setw(4) << p << ": ";
|
||||||
uint16_t v=0;
|
uint16_t v = 0;
|
||||||
while(v<16 && p+v<Size_) {
|
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++;
|
v++;
|
||||||
}
|
}
|
||||||
os << std::endl;
|
os << std::endl;
|
||||||
p+=16;
|
p += 16;
|
||||||
}
|
}
|
||||||
os << std::dec << std::endl << std::endl;
|
os << std::dec << std::endl << std::endl;
|
||||||
Print(os);
|
Print(os);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const char * PacketType() {
|
inline const char *PacketType() { return CommandName(P_.code); }
|
||||||
return CommandName(P_.code);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int PacketTypeInt() {
|
inline int PacketTypeInt() { return (int)(P_.code); }
|
||||||
return (int)(P_.code);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ComputeMessageAuthenticator(const std::string &secret) {
|
void ComputeMessageAuthenticator(const std::string &secret) {
|
||||||
RawRadiusPacket P = P_;
|
RawRadiusPacket P = P_;
|
||||||
|
|
||||||
if(P_.code==1) {
|
if (P_.code == 1) {
|
||||||
unsigned char OldAuthenticator[16]{0};
|
unsigned char OldAuthenticator[16]{0};
|
||||||
for (const auto &attr : Attrs_) {
|
for (const auto &attr : Attrs_) {
|
||||||
if (attr.type == 80) {
|
if (attr.type == 80) {
|
||||||
@@ -525,7 +512,7 @@ static const struct tok radius_attribute_names[] = {
|
|||||||
|
|
||||||
bool VerifyMessageAuthenticator(const std::string &secret) {
|
bool VerifyMessageAuthenticator(const std::string &secret) {
|
||||||
RawRadiusPacket P = P_;
|
RawRadiusPacket P = P_;
|
||||||
if(P_.code==1) {
|
if (P_.code == 1) {
|
||||||
unsigned char OldAuthenticator[16]{0};
|
unsigned char OldAuthenticator[16]{0};
|
||||||
for (const auto &attr : Attrs_) {
|
for (const auto &attr : Attrs_) {
|
||||||
if (attr.type == 80) {
|
if (attr.type == 80) {
|
||||||
@@ -545,31 +532,33 @@ static const struct tok radius_attribute_names[] = {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void BufLog(std::ostream & os, const char * pre, const unsigned char *b, uint s) {
|
static void BufLog(std::ostream &os, const char *pre, const unsigned char *b, uint s) {
|
||||||
uint16_t p = 0;
|
uint16_t p = 0;
|
||||||
while(p<s) {
|
while (p < s) {
|
||||||
os << pre << std::setfill('0') << std::setw(4) << p << ": ";
|
os << pre << std::setfill('0') << std::setw(4) << p << ": ";
|
||||||
uint16_t v=0;
|
uint16_t v = 0;
|
||||||
while(v<16 && p+v<s) {
|
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++;
|
v++;
|
||||||
}
|
}
|
||||||
os << std::endl;
|
os << std::endl;
|
||||||
p+=16;
|
p += 16;
|
||||||
}
|
}
|
||||||
os << std::dec ;
|
os << std::dec;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Print(std::ostream &os) {
|
inline void Print(std::ostream &os) {
|
||||||
os << "Packet type: (" << (uint) P_.code << ") " << CommandName(P_.code) << std::endl;
|
os << "Packet type: (" << (uint)P_.code << ") " << CommandName(P_.code) << std::endl;
|
||||||
os << " Identifier: " << (uint) P_.identifier << std::endl;
|
os << " Identifier: " << (uint)P_.identifier << std::endl;
|
||||||
os << " Length: " << Size_ << std::endl;
|
os << " Length: " << Size_ << std::endl;
|
||||||
os << " Authenticator: " ;
|
os << " Authenticator: ";
|
||||||
BufLog(os, "", P_.authenticator, sizeof(P_.authenticator));
|
BufLog(os, "", P_.authenticator, sizeof(P_.authenticator));
|
||||||
os << " Attributes: " << std::endl;
|
os << " Attributes: " << std::endl;
|
||||||
for(const auto &attr:Attrs_) {
|
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 << ") "
|
||||||
BufLog(os, " " , &P_.attributes[attr.pos], attr.len);
|
<< AttributeName(attr.type) << " Len:" << attr.len << std::endl;
|
||||||
|
BufLog(os, " ", &P_.attributes[attr.pos], attr.len);
|
||||||
}
|
}
|
||||||
os << std::dec << std::endl << std::endl;
|
os << std::dec << std::endl << std::endl;
|
||||||
}
|
}
|
||||||
@@ -577,21 +566,21 @@ static const struct tok radius_attribute_names[] = {
|
|||||||
std::string ExtractSerialNumberTIP() {
|
std::string ExtractSerialNumberTIP() {
|
||||||
std::string R;
|
std::string R;
|
||||||
|
|
||||||
for(const auto &attribute:Attrs_) {
|
for (const auto &attribute : Attrs_) {
|
||||||
if(attribute.type==26) {
|
if (attribute.type == 26) {
|
||||||
AttributeList VendorAttributes;
|
AttributeList VendorAttributes;
|
||||||
uint32_t VendorId = htonl( *(const uint32_t *)&(P_.attributes[attribute.pos]));
|
uint32_t VendorId = htonl(*(const uint32_t *)&(P_.attributes[attribute.pos]));
|
||||||
// std::cout << VendorId << std::endl;
|
// std::cout << VendorId << std::endl;
|
||||||
if(VendorId==TIP_vendor_id && attribute.len>(4+2)) {
|
if (VendorId == TIP_vendor_id && attribute.len > (4 + 2)) {
|
||||||
if (ParseRadius(attribute.pos + 4, &P_.attributes[attribute.pos + 4], attribute.len - 4 - 2,
|
if (ParseRadius(attribute.pos + 4, &P_.attributes[attribute.pos + 4],
|
||||||
VendorAttributes)) {
|
attribute.len - 4 - 2, VendorAttributes)) {
|
||||||
// std::cout << VendorAttributes << std::endl;
|
// std::cout << VendorAttributes << std::endl;
|
||||||
for (const auto &vendorAttr: VendorAttributes) {
|
for (const auto &vendorAttr : VendorAttributes) {
|
||||||
if (vendorAttr.type == TIP_serial) {
|
if (vendorAttr.type == TIP_serial) {
|
||||||
for (uint16_t i = 0; i < vendorAttr.len; i++) {
|
for (uint16_t i = 0; i < vendorAttr.len; i++) {
|
||||||
if (P_.attributes[vendorAttr.pos + i] == '-')
|
if (P_.attributes[vendorAttr.pos + i] == '-')
|
||||||
continue;
|
continue;
|
||||||
R += (char) P_.attributes[vendorAttr.pos + i];
|
R += (char)P_.attributes[vendorAttr.pos + i];
|
||||||
}
|
}
|
||||||
return R;
|
return R;
|
||||||
}
|
}
|
||||||
@@ -605,17 +594,18 @@ static const struct tok radius_attribute_names[] = {
|
|||||||
|
|
||||||
std::string ExtractSerialNumberFromProxyState() {
|
std::string ExtractSerialNumberFromProxyState() {
|
||||||
std::string Result;
|
std::string Result;
|
||||||
for(const auto &attribute:Attrs_) {
|
for (const auto &attribute : Attrs_) {
|
||||||
if(attribute.type==33) {
|
if (attribute.type == 33) {
|
||||||
std::string Attr33;
|
std::string Attr33;
|
||||||
// format is serial:IP:port:interface
|
// 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],
|
||||||
auto Parts = Poco::StringTokenizer(Attr33,"|");
|
attribute.len - 2);
|
||||||
if(Parts.count()==4) {
|
auto Parts = Poco::StringTokenizer(Attr33, "|");
|
||||||
|
if (Parts.count() == 4) {
|
||||||
return Parts[0];
|
return Parts[0];
|
||||||
}
|
}
|
||||||
Parts = Poco::StringTokenizer(Attr33,":");
|
Parts = Poco::StringTokenizer(Attr33, ":");
|
||||||
if(Parts.count()==4) {
|
if (Parts.count() == 4) {
|
||||||
return Parts[0];
|
return Parts[0];
|
||||||
}
|
}
|
||||||
return Result;
|
return Result;
|
||||||
@@ -626,19 +616,20 @@ static const struct tok radius_attribute_names[] = {
|
|||||||
|
|
||||||
std::string ExtractProxyStateDestination() {
|
std::string ExtractProxyStateDestination() {
|
||||||
std::string Result;
|
std::string Result;
|
||||||
for(const auto &attribute:Attrs_) {
|
for (const auto &attribute : Attrs_) {
|
||||||
if(attribute.type==33 && attribute.len>2) {
|
if (attribute.type == 33 && attribute.len > 2) {
|
||||||
std::string Attr33;
|
std::string Attr33;
|
||||||
// format is serial:IP:port:interface
|
// 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],
|
||||||
auto Parts = Poco::StringTokenizer(Attr33,"|");
|
attribute.len - 2);
|
||||||
if(Parts.count()==4) {
|
auto Parts = Poco::StringTokenizer(Attr33, "|");
|
||||||
Poco::Net::SocketAddress D(Parts[1],Parts[2]);
|
if (Parts.count() == 4) {
|
||||||
|
Poco::Net::SocketAddress D(Parts[1], Parts[2]);
|
||||||
return D.toString();
|
return D.toString();
|
||||||
}
|
}
|
||||||
Parts = Poco::StringTokenizer(Attr33,":");
|
Parts = Poco::StringTokenizer(Attr33, ":");
|
||||||
if(Parts.count()==4) {
|
if (Parts.count() == 4) {
|
||||||
Poco::Net::SocketAddress D(Parts[1],Parts[2]);
|
Poco::Net::SocketAddress D(Parts[1], Parts[2]);
|
||||||
return D.toString();
|
return D.toString();
|
||||||
}
|
}
|
||||||
return Result;
|
return Result;
|
||||||
@@ -649,9 +640,10 @@ static const struct tok radius_attribute_names[] = {
|
|||||||
|
|
||||||
std::string ExtractCallingStationID() {
|
std::string ExtractCallingStationID() {
|
||||||
std::string Result;
|
std::string Result;
|
||||||
for(const auto &attribute:Attrs_) {
|
for (const auto &attribute : Attrs_) {
|
||||||
if(attribute.type==31 && attribute.len>2) {
|
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;
|
return Result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -660,9 +652,10 @@ static const struct tok radius_attribute_names[] = {
|
|||||||
|
|
||||||
std::string ExtractCalledStationID() {
|
std::string ExtractCalledStationID() {
|
||||||
std::string Result;
|
std::string Result;
|
||||||
for(const auto &attribute:Attrs_) {
|
for (const auto &attribute : Attrs_) {
|
||||||
if(attribute.type==30 && attribute.len>2) {
|
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;
|
return Result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -670,9 +663,9 @@ static const struct tok radius_attribute_names[] = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] std::string UserName() const {
|
[[nodiscard]] std::string UserName() const {
|
||||||
for(const auto &attr:Attrs_) {
|
for (const auto &attr : Attrs_) {
|
||||||
if(attr.type==1) {
|
if (attr.type == 1) {
|
||||||
std::string user_name{(const char *)&P_.attributes[attr.pos],attr.len};
|
std::string user_name{(const char *)&P_.attributes[attr.pos], attr.len};
|
||||||
return user_name;
|
return user_name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -683,21 +676,20 @@ static const struct tok radius_attribute_names[] = {
|
|||||||
RawRadiusPacket P_;
|
RawRadiusPacket P_;
|
||||||
uint16_t Size_{0};
|
uint16_t Size_{0};
|
||||||
AttributeList Attrs_;
|
AttributeList Attrs_;
|
||||||
bool Valid_=false;
|
bool Valid_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RadiusOutputPacket {
|
class RadiusOutputPacket {
|
||||||
public:
|
public:
|
||||||
explicit RadiusOutputPacket(const std::string &Secret)
|
explicit RadiusOutputPacket(const std::string &Secret) : Secret_(Secret) {}
|
||||||
: Secret_(Secret) {
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void MakeStatusMessage() {
|
inline void MakeStatusMessage() {
|
||||||
P_.code = RADCMD_STATUS_SER;
|
P_.code = RADCMD_STATUS_SER;
|
||||||
P_.identifier = std::rand() & 0x00ff;
|
P_.identifier = std::rand() & 0x00ff;
|
||||||
MakeRadiusAuthenticator(P_.authenticator);
|
MakeRadiusAuthenticator(P_.authenticator);
|
||||||
unsigned char MessageAuthenticator[16]{0};
|
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;
|
P_.rawlen = 1 + 1 + 2 + 16 + 1 + 1 + 16;
|
||||||
|
|
||||||
Poco::HMACEngine<Poco::MD5Engine> H(Secret_);
|
Poco::HMACEngine<Poco::MD5Engine> H(Secret_);
|
||||||
@@ -708,24 +700,26 @@ static const struct tok radius_attribute_names[] = {
|
|||||||
P_.attributes[1 + 1 + p++] = i;
|
P_.attributes[1 + 1 + p++] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void AddAttribute(unsigned char attr, uint8_t len, const unsigned char * data) {
|
inline void AddAttribute(unsigned char attr, uint8_t len, const unsigned char *data) {
|
||||||
P_.attributes[AttributesLen_++] = attr;
|
P_.attributes[AttributesLen_++] = attr;
|
||||||
P_.attributes[AttributesLen_++] = len;
|
P_.attributes[AttributesLen_++] = len;
|
||||||
memcpy(&P_.attributes[AttributesLen_],data,len);
|
memcpy(&P_.attributes[AttributesLen_], data, len);
|
||||||
AttributesLen_+=len;
|
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; }
|
[[nodiscard]] inline std::uint16_t Len() const { return P_.rawlen; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RawRadiusPacket P_;
|
RawRadiusPacket P_;
|
||||||
uint16_t AttributesLen_=0;
|
uint16_t AttributesLen_ = 0;
|
||||||
std::string Secret_;
|
std::string Secret_;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::ostream &operator<<(std::ostream &os, RadiusPacket const &P) {
|
inline std::ostream &operator<<(std::ostream &os, RadiusPacket const &P) {
|
||||||
os << P.Attrs_ ;
|
os << P.Attrs_;
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
}
|
} // namespace OpenWifi::RADIUS
|
||||||
@@ -4,85 +4,108 @@
|
|||||||
|
|
||||||
#include "Poco/JSON/Parser.h"
|
#include "Poco/JSON/Parser.h"
|
||||||
|
|
||||||
#include "RADIUS_proxy_server.h"
|
|
||||||
#include "RADIUS_helpers.h"
|
|
||||||
#include "AP_WS_Server.h"
|
#include "AP_WS_Server.h"
|
||||||
|
#include "RADIUS_helpers.h"
|
||||||
|
#include "RADIUS_proxy_server.h"
|
||||||
|
|
||||||
#include "framework/MicroServiceFuncs.h"
|
#include "framework/MicroServiceFuncs.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
const int SMALLEST_RADIUS_PACKET = 20+19+4;
|
const int SMALLEST_RADIUS_PACKET = 20 + 19 + 4;
|
||||||
const int DEFAULT_RADIUS_AUTHENTICATION_PORT = 1812;
|
const int DEFAULT_RADIUS_AUTHENTICATION_PORT = 1812;
|
||||||
const int DEFAULT_RADIUS_ACCOUNTING_PORT = 1813;
|
const int DEFAULT_RADIUS_ACCOUNTING_PORT = 1813;
|
||||||
const int DEFAULT_RADIUS_CoA_PORT = 3799;
|
const int DEFAULT_RADIUS_CoA_PORT = 3799;
|
||||||
|
|
||||||
int RADIUS_proxy_server::Start() {
|
int RADIUS_proxy_server::Start() {
|
||||||
|
|
||||||
ConfigFilename_ = MicroServiceDataDirectory()+"/radius_pool_config.json";
|
ConfigFilename_ = MicroServiceDataDirectory() + "/radius_pool_config.json";
|
||||||
Poco::File Config(ConfigFilename_);
|
Poco::File Config(ConfigFilename_);
|
||||||
|
|
||||||
Enabled_ = MicroServiceConfigGetBool("radius.proxy.enable",false);
|
Enabled_ = MicroServiceConfigGetBool("radius.proxy.enable", false);
|
||||||
if(!Enabled_ && !Config.exists()) {
|
if (!Enabled_ && !Config.exists()) {
|
||||||
StopRADSECServers();
|
StopRADSECServers();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
poco_notice(Logger(),"Starting...");
|
poco_notice(Logger(), "Starting...");
|
||||||
|
|
||||||
Enabled_ = true;
|
Enabled_ = true;
|
||||||
|
|
||||||
Poco::Net::SocketAddress AuthSockAddrV4(Poco::Net::AddressFamily::IPv4,
|
Poco::Net::SocketAddress AuthSockAddrV4(
|
||||||
MicroServiceConfigGetInt("radius.proxy.authentication.port",DEFAULT_RADIUS_AUTHENTICATION_PORT));
|
Poco::Net::AddressFamily::IPv4,
|
||||||
AuthenticationSocketV4_ = std::make_unique<Poco::Net::DatagramSocket>(AuthSockAddrV4,true,true);
|
MicroServiceConfigGetInt("radius.proxy.authentication.port",
|
||||||
Poco::Net::SocketAddress AuthSockAddrV6(Poco::Net::AddressFamily::IPv6,
|
DEFAULT_RADIUS_AUTHENTICATION_PORT));
|
||||||
MicroServiceConfigGetInt("radius.proxy.authentication.port",DEFAULT_RADIUS_AUTHENTICATION_PORT));
|
AuthenticationSocketV4_ =
|
||||||
AuthenticationSocketV6_ = std::make_unique<Poco::Net::DatagramSocket>(AuthSockAddrV6,true,true);
|
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,
|
Poco::Net::SocketAddress AcctSockAddrV4(
|
||||||
MicroServiceConfigGetInt("radius.proxy.accounting.port",DEFAULT_RADIUS_ACCOUNTING_PORT));
|
Poco::Net::AddressFamily::IPv4,
|
||||||
AccountingSocketV4_ = std::make_unique<Poco::Net::DatagramSocket>(AcctSockAddrV4,true,true);
|
MicroServiceConfigGetInt("radius.proxy.accounting.port",
|
||||||
Poco::Net::SocketAddress AcctSockAddrV6(Poco::Net::AddressFamily::IPv6,
|
DEFAULT_RADIUS_ACCOUNTING_PORT));
|
||||||
MicroServiceConfigGetInt("radius.proxy.accounting.port",DEFAULT_RADIUS_ACCOUNTING_PORT));
|
AccountingSocketV4_ =
|
||||||
AccountingSocketV6_ = std::make_unique<Poco::Net::DatagramSocket>(AcctSockAddrV6,true,true);
|
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(
|
||||||
MicroServiceConfigGetInt("radius.proxy.coa.port",DEFAULT_RADIUS_CoA_PORT));
|
Poco::Net::AddressFamily::IPv4,
|
||||||
CoASocketV4_ = std::make_unique<Poco::Net::DatagramSocket>(CoASockAddrV4,true,true);
|
MicroServiceConfigGetInt("radius.proxy.coa.port", DEFAULT_RADIUS_CoA_PORT));
|
||||||
Poco::Net::SocketAddress CoASockAddrV6(Poco::Net::AddressFamily::IPv6,
|
CoASocketV4_ = std::make_unique<Poco::Net::DatagramSocket>(CoASockAddrV4, true, true);
|
||||||
MicroServiceConfigGetInt("radius.proxy.coa.port",DEFAULT_RADIUS_CoA_PORT));
|
Poco::Net::SocketAddress CoASockAddrV6(
|
||||||
CoASocketV6_ = std::make_unique<Poco::Net::DatagramSocket>(CoASockAddrV6,true,true);
|
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_.reset();
|
||||||
RadiusReactor_ = std::make_unique<Poco::Net::SocketReactor>();
|
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));
|
*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));
|
*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));
|
*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));
|
*this, &RADIUS_proxy_server::OnAccountingSocketReadable));
|
||||||
|
|
||||||
|
RadiusReactor_->addEventHandler(
|
||||||
RadiusReactor_->addEventHandler(*CoASocketV4_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
*CoASocketV4_, Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||||
*this, &RADIUS_proxy_server::OnCoASocketReadable));
|
*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));
|
*this, &RADIUS_proxy_server::OnCoASocketReadable));
|
||||||
|
|
||||||
ParseConfig();
|
ParseConfig();
|
||||||
StartRADSECServers();
|
StartRADSECServers();
|
||||||
RadiusReactorThread_.start(*RadiusReactor_);
|
RadiusReactorThread_.start(*RadiusReactor_);
|
||||||
Utils::SetThreadName(RadiusReactorThread_,"rad:reactor");
|
Utils::SetThreadName(RadiusReactorThread_, "rad:reactor");
|
||||||
Running_ = true;
|
Running_ = true;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RADIUS_proxy_server::Stop() {
|
void RADIUS_proxy_server::Stop() {
|
||||||
if(Enabled_ && Running_) {
|
if (Enabled_ && Running_) {
|
||||||
poco_information(Logger(),"Stopping...");
|
poco_information(Logger(), "Stopping...");
|
||||||
RadiusReactor_->removeEventHandler(
|
RadiusReactor_->removeEventHandler(
|
||||||
*AuthenticationSocketV4_,
|
*AuthenticationSocketV4_,
|
||||||
Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||||
@@ -127,17 +150,18 @@ namespace OpenWifi {
|
|||||||
StopRADSECServers();
|
StopRADSECServers();
|
||||||
RadiusReactor_->stop();
|
RadiusReactor_->stop();
|
||||||
RadiusReactorThread_.join();
|
RadiusReactorThread_.join();
|
||||||
Running_=false;
|
Running_ = false;
|
||||||
poco_information(Logger(),"Stopped...");
|
poco_information(Logger(), "Stopped...");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RADIUS_proxy_server::StartRADSECServers() {
|
void RADIUS_proxy_server::StartRADSECServers() {
|
||||||
std::lock_guard G(Mutex_);
|
std::lock_guard G(Mutex_);
|
||||||
for(const auto &pool:PoolList_.pools) {
|
for (const auto &pool : PoolList_.pools) {
|
||||||
for(const auto &entry:pool.authConfig.servers) {
|
for (const auto &entry : pool.authConfig.servers) {
|
||||||
if(entry.radsec) {
|
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,75 +172,90 @@ namespace OpenWifi {
|
|||||||
RADSECservers_.clear();
|
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;
|
Poco::Net::SocketAddress Sender;
|
||||||
RADIUS::RadiusPacket P;
|
RADIUS::RadiusPacket P;
|
||||||
|
|
||||||
auto ReceiveSize = pNf->socket().impl()->receiveBytes(P.Buffer(),P.BufferLen());
|
auto ReceiveSize = pNf->socket().impl()->receiveBytes(P.Buffer(), P.BufferLen());
|
||||||
if(ReceiveSize<SMALLEST_RADIUS_PACKET) {
|
if (ReceiveSize < SMALLEST_RADIUS_PACKET) {
|
||||||
poco_warning(Logger(),"Accounting: bad packet received.");
|
poco_warning(Logger(), "Accounting: bad packet received.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
P.Evaluate(ReceiveSize);
|
P.Evaluate(ReceiveSize);
|
||||||
auto SerialNumber = P.ExtractSerialNumberFromProxyState();
|
auto SerialNumber = P.ExtractSerialNumberFromProxyState();
|
||||||
if(SerialNumber.empty()) {
|
if (SerialNumber.empty()) {
|
||||||
poco_warning(Logger(),"Accounting: missing serial number.");
|
poco_warning(Logger(), "Accounting: missing serial number.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto CallingStationID = P.ExtractCallingStationID();
|
auto CallingStationID = P.ExtractCallingStationID();
|
||||||
auto CalledStationID = P.ExtractCalledStationID();
|
auto CalledStationID = P.ExtractCalledStationID();
|
||||||
|
|
||||||
poco_debug(Logger(), fmt::format("Accounting Packet received for {}, CalledStationID: {}, CallingStationID:{}",SerialNumber, CalledStationID, CallingStationID));
|
poco_debug(
|
||||||
AP_WS_Server()->SendRadiusAccountingData(SerialNumber,P.Buffer(),P.Size());
|
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;
|
Poco::Net::SocketAddress Sender;
|
||||||
RADIUS::RadiusPacket P;
|
RADIUS::RadiusPacket P;
|
||||||
|
|
||||||
auto ReceiveSize = pNf->socket().impl()->receiveBytes(P.Buffer(),P.BufferLen());
|
auto ReceiveSize = pNf->socket().impl()->receiveBytes(P.Buffer(), P.BufferLen());
|
||||||
if(ReceiveSize<SMALLEST_RADIUS_PACKET) {
|
if (ReceiveSize < SMALLEST_RADIUS_PACKET) {
|
||||||
poco_warning(Logger(),"Authentication: bad packet received.");
|
poco_warning(Logger(), "Authentication: bad packet received.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
P.Evaluate(ReceiveSize);
|
P.Evaluate(ReceiveSize);
|
||||||
auto SerialNumber = P.ExtractSerialNumberFromProxyState();
|
auto SerialNumber = P.ExtractSerialNumberFromProxyState();
|
||||||
if(SerialNumber.empty()) {
|
if (SerialNumber.empty()) {
|
||||||
poco_warning(Logger(),"Authentication: missing serial number.");
|
poco_warning(Logger(), "Authentication: missing serial number.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto CallingStationID = P.ExtractCallingStationID();
|
auto CallingStationID = P.ExtractCallingStationID();
|
||||||
auto CalledStationID = P.ExtractCalledStationID();
|
auto CalledStationID = P.ExtractCalledStationID();
|
||||||
|
|
||||||
poco_debug(Logger(), fmt::format("Authentication Packet received for {}, CalledStationID: {}, CallingStationID:{}",SerialNumber, CalledStationID, CallingStationID));
|
poco_debug(
|
||||||
AP_WS_Server()->SendRadiusAuthenticationData(SerialNumber,P.Buffer(),P.Size());
|
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;
|
Poco::Net::SocketAddress Sender;
|
||||||
RADIUS::RadiusPacket P;
|
RADIUS::RadiusPacket P;
|
||||||
|
|
||||||
auto ReceiveSize = pNf.get()->socket().impl()->receiveBytes(P.Buffer(),P.BufferLen());
|
auto ReceiveSize = pNf.get()->socket().impl()->receiveBytes(P.Buffer(), P.BufferLen());
|
||||||
if(ReceiveSize<SMALLEST_RADIUS_PACKET) {
|
if (ReceiveSize < SMALLEST_RADIUS_PACKET) {
|
||||||
poco_warning(Logger(),"CoA/DM: bad packet received.");
|
poco_warning(Logger(), "CoA/DM: bad packet received.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
P.Evaluate(ReceiveSize);
|
P.Evaluate(ReceiveSize);
|
||||||
auto SerialNumber = P.ExtractSerialNumberTIP();
|
auto SerialNumber = P.ExtractSerialNumberTIP();
|
||||||
if(SerialNumber.empty()) {
|
if (SerialNumber.empty()) {
|
||||||
poco_warning(Logger(),"CoA/DM: missing serial number.");
|
poco_warning(Logger(), "CoA/DM: missing serial number.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto CallingStationID = P.ExtractCallingStationID();
|
auto CallingStationID = P.ExtractCallingStationID();
|
||||||
auto CalledStationID = P.ExtractCalledStationID();
|
auto CalledStationID = P.ExtractCalledStationID();
|
||||||
|
|
||||||
poco_debug(Logger(), fmt::format("CoA Packet received for {}, CalledStationID: {}, CallingStationID:{}",SerialNumber, CalledStationID, CallingStationID));
|
poco_debug(
|
||||||
AP_WS_Server()->SendRadiusCoAData(SerialNumber,P.Buffer(),P.Size());
|
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())
|
if (!Continue())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -257,28 +296,32 @@ namespace OpenWifi {
|
|||||||
fmt::format("{}: Could not send Accounting packet packet to {}.",
|
fmt::format("{}: Could not send Accounting packet packet to {}.",
|
||||||
serialNumber, Destination));
|
serialNumber, Destination));
|
||||||
else
|
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(),
|
serialNumber, FinalDestination.toString(),
|
||||||
CalledStationID, CallingStationID));
|
CalledStationID, CallingStationID));
|
||||||
}
|
}
|
||||||
} catch (const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
Logger().log(E);
|
Logger().log(E);
|
||||||
} catch (...) {
|
} 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,
|
||||||
return Sock.sendTo(buf, size, S)==(int)size;
|
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())
|
if (!Continue())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
RADIUS::RadiusPacket P((unsigned char *)buffer,size);
|
RADIUS::RadiusPacket P((unsigned char *)buffer, size);
|
||||||
auto Destination = P.ExtractProxyStateDestination();
|
auto Destination = P.ExtractProxyStateDestination();
|
||||||
auto CallingStationID = P.ExtractCallingStationID();
|
auto CallingStationID = P.ExtractCallingStationID();
|
||||||
auto CalledStationID = P.ExtractCalledStationID();
|
auto CalledStationID = P.ExtractCalledStationID();
|
||||||
@@ -287,11 +330,12 @@ namespace OpenWifi {
|
|||||||
std::lock_guard G(Mutex_);
|
std::lock_guard G(Mutex_);
|
||||||
bool UseRADSEC = false;
|
bool UseRADSEC = false;
|
||||||
auto FinalDestination = Route(radius_type::auth, Dst, P, UseRADSEC);
|
auto FinalDestination = Route(radius_type::auth, Dst, P, UseRADSEC);
|
||||||
if(UseRADSEC) {
|
if (UseRADSEC) {
|
||||||
Poco::Net::SocketAddress RSP(FinalDestination.host(),0);
|
Poco::Net::SocketAddress RSP(FinalDestination.host(), 0);
|
||||||
auto DestinationServer = RADSECservers_.find(RSP);
|
auto DestinationServer = RADSECservers_.find(RSP);
|
||||||
if(DestinationServer!=end(RADSECservers_)) {
|
if (DestinationServer != end(RADSECservers_)) {
|
||||||
DestinationServer->second->SendData(serialNumber, (const unsigned char *)buffer, size);
|
DestinationServer->second->SendData(serialNumber, (const unsigned char *)buffer,
|
||||||
|
size);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((Dst.family() == Poco::Net::SocketAddress::IPv4 &&
|
if ((Dst.family() == Poco::Net::SocketAddress::IPv4 &&
|
||||||
@@ -300,12 +344,13 @@ namespace OpenWifi {
|
|||||||
AuthenticationSocketV6_ == nullptr)) {
|
AuthenticationSocketV6_ == nullptr)) {
|
||||||
poco_debug(
|
poco_debug(
|
||||||
Logger(),
|
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));
|
serialNumber));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto AllSent =
|
auto AllSent = SendData(Dst.family() == Poco::Net::SocketAddress::IPv4
|
||||||
SendData(Dst.family() == Poco::Net::SocketAddress::IPv4 ? *AuthenticationSocketV4_
|
? *AuthenticationSocketV4_
|
||||||
: *AuthenticationSocketV6_,
|
: *AuthenticationSocketV6_,
|
||||||
(const unsigned char *)buffer, size, FinalDestination);
|
(const unsigned char *)buffer, size, FinalDestination);
|
||||||
if (!AllSent)
|
if (!AllSent)
|
||||||
@@ -313,28 +358,30 @@ namespace OpenWifi {
|
|||||||
fmt::format("{}: Could not send Authentication packet packet to {}.",
|
fmt::format("{}: Could not send Authentication packet packet to {}.",
|
||||||
serialNumber, Destination));
|
serialNumber, Destination));
|
||||||
else
|
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(),
|
serialNumber, FinalDestination.toString(),
|
||||||
CalledStationID, CallingStationID));
|
CalledStationID, CallingStationID));
|
||||||
}
|
}
|
||||||
} catch (const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
Logger().log(E);
|
Logger().log(E);
|
||||||
} catch (...) {
|
} 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())
|
||||||
|
|
||||||
if(!Continue())
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
RADIUS::RadiusPacket P((unsigned char *)buffer,size);
|
RADIUS::RadiusPacket P((unsigned char *)buffer, size);
|
||||||
auto Destination = P.ExtractProxyStateDestination();
|
auto Destination = P.ExtractProxyStateDestination();
|
||||||
|
|
||||||
if(Destination.empty()) {
|
if (Destination.empty()) {
|
||||||
Destination = "0.0.0.0:0";
|
Destination = "0.0.0.0:0";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -342,23 +389,28 @@ namespace OpenWifi {
|
|||||||
std::lock_guard G(Mutex_);
|
std::lock_guard G(Mutex_);
|
||||||
bool UseRADSEC = false;
|
bool UseRADSEC = false;
|
||||||
auto FinalDestination = Route(radius_type::coa, Dst, P, UseRADSEC);
|
auto FinalDestination = Route(radius_type::coa, Dst, P, UseRADSEC);
|
||||||
if(UseRADSEC) {
|
if (UseRADSEC) {
|
||||||
Poco::Net::SocketAddress RSP(FinalDestination.host(),0);
|
Poco::Net::SocketAddress RSP(FinalDestination.host(), 0);
|
||||||
auto DestinationServer = RADSECservers_.find(RSP);
|
auto DestinationServer = RADSECservers_.find(RSP);
|
||||||
if(DestinationServer!=end(RADSECservers_)) {
|
if (DestinationServer != end(RADSECservers_)) {
|
||||||
DestinationServer->second->SendData(serialNumber, (const unsigned char *)buffer, size);
|
DestinationServer->second->SendData(serialNumber, (const unsigned char *)buffer,
|
||||||
|
size);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if( (Dst.family() == Poco::Net::SocketAddress::IPv4 && CoASocketV4_== nullptr) ||
|
if ((Dst.family() == Poco::Net::SocketAddress::IPv4 && CoASocketV4_ == nullptr) ||
|
||||||
(Dst.family() == Poco::Net::SocketAddress::IPv6 && CoASocketV6_== 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;
|
return;
|
||||||
}
|
}
|
||||||
auto AllSent = SendData(Dst.family() == Poco::Net::SocketAddress::IPv4 ? *CoASocketV4_
|
auto AllSent = SendData(
|
||||||
: *CoASocketV6_,
|
Dst.family() == Poco::Net::SocketAddress::IPv4 ? *CoASocketV4_ : *CoASocketV6_,
|
||||||
(const unsigned char *)buffer, size, FinalDestination);
|
(const unsigned char *)buffer, size, FinalDestination);
|
||||||
if (!AllSent)
|
if (!AllSent)
|
||||||
poco_error(Logger(),fmt::format("{}: Could not send CoA packet packet to {}.",
|
poco_error(Logger(), fmt::format("{}: Could not send CoA packet packet to {}.",
|
||||||
serialNumber, Destination));
|
serialNumber, Destination));
|
||||||
else
|
else
|
||||||
poco_debug(Logger(), fmt::format("{}: Sending CoA Packet to {}", serialNumber,
|
poco_debug(Logger(), fmt::format("{}: Sending CoA Packet to {}", serialNumber,
|
||||||
@@ -367,39 +419,42 @@ namespace OpenWifi {
|
|||||||
} catch (const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
Logger().log(E);
|
Logger().log(E);
|
||||||
} catch (...) {
|
} 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,
|
||||||
uint64_t TotalV4=0, TotalV6=0;
|
std::vector<Destination> &V4,
|
||||||
|
std::vector<Destination> &V6, bool setAsDefault) {
|
||||||
|
uint64_t TotalV4 = 0, TotalV6 = 0;
|
||||||
|
|
||||||
for(const auto &server:Config.servers) {
|
for (const auto &server : Config.servers) {
|
||||||
Poco::Net::IPAddress a;
|
Poco::Net::IPAddress a;
|
||||||
if(!Poco::Net::IPAddress::tryParse(server.ip,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;
|
continue;
|
||||||
}
|
}
|
||||||
auto S = Poco::Net::SocketAddress(fmt::format("{}:{}",server.ip,server.port));
|
auto S = Poco::Net::SocketAddress(fmt::format("{}:{}", server.ip, server.port));
|
||||||
Destination D{
|
Destination D{.Addr = S,
|
||||||
.Addr = S,
|
|
||||||
.state = 0,
|
.state = 0,
|
||||||
.step = 0,
|
.step = 0,
|
||||||
.weight = server.weight,
|
.weight = server.weight,
|
||||||
.available = true,
|
.available = true,
|
||||||
.strategy = Config.strategy,
|
.strategy = Config.strategy,
|
||||||
.monitor = Config. monitor,
|
.monitor = Config.monitor,
|
||||||
.monitorMethod = Config.monitorMethod,
|
.monitorMethod = Config.monitorMethod,
|
||||||
.methodParameters = Config.methodParameters,
|
.methodParameters = Config.methodParameters,
|
||||||
.useAsDefault = setAsDefault,
|
.useAsDefault = setAsDefault,
|
||||||
.useRADSEC = server.radsec,
|
.useRADSEC = server.radsec,
|
||||||
.realms = server.radsecRealms
|
.realms = server.radsecRealms};
|
||||||
};
|
|
||||||
|
|
||||||
if(setAsDefault && D.useRADSEC)
|
if (setAsDefault && D.useRADSEC)
|
||||||
DefaultIsRADSEC_ = true;
|
DefaultIsRADSEC_ = true;
|
||||||
|
|
||||||
if(S.family()==Poco::Net::IPAddress::IPv4) {
|
if (S.family() == Poco::Net::IPAddress::IPv4) {
|
||||||
TotalV4 += server.weight;
|
TotalV4 += server.weight;
|
||||||
V4.push_back(D);
|
V4.push_back(D);
|
||||||
} else {
|
} else {
|
||||||
@@ -408,16 +463,16 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto &i:V4) {
|
for (auto &i : V4) {
|
||||||
if(TotalV4==0) {
|
if (TotalV4 == 0) {
|
||||||
i.step = 1000;
|
i.step = 1000;
|
||||||
} else {
|
} else {
|
||||||
i.step = 1000 - ((1000 * i.weight) / TotalV4);
|
i.step = 1000 - ((1000 * i.weight) / TotalV4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto &i:V6) {
|
for (auto &i : V6) {
|
||||||
if(TotalV6==0) {
|
if (TotalV6 == 0) {
|
||||||
i.step = 1000;
|
i.step = 1000;
|
||||||
} else {
|
} else {
|
||||||
i.step = 1000 - ((1000 * i.weight) / TotalV6);
|
i.step = 1000 - ((1000 * i.weight) / TotalV6);
|
||||||
@@ -432,55 +487,64 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
std::lock_guard G(Mutex_);
|
std::lock_guard G(Mutex_);
|
||||||
|
|
||||||
if(F.exists()) {
|
if (F.exists()) {
|
||||||
std::ifstream ifs(ConfigFilename_,std::ios_base::binary);
|
std::ifstream ifs(ConfigFilename_, std::ios_base::binary);
|
||||||
Poco::JSON::Parser P;
|
Poco::JSON::Parser P;
|
||||||
auto RawConfig = P.parse(ifs).extract<Poco::JSON::Object::Ptr>();
|
auto RawConfig = P.parse(ifs).extract<Poco::JSON::Object::Ptr>();
|
||||||
GWObjects::RadiusProxyPoolList RPC;
|
GWObjects::RadiusProxyPoolList RPC;
|
||||||
if(RPC.from_json(RawConfig)) {
|
if (RPC.from_json(RawConfig)) {
|
||||||
ResetConfig();
|
ResetConfig();
|
||||||
PoolList_ = RPC;
|
PoolList_ = RPC;
|
||||||
for(const auto &pool:RPC.pools) {
|
for (const auto &pool : RPC.pools) {
|
||||||
RadiusPool NewPool;
|
RadiusPool NewPool;
|
||||||
ParseServerList(pool.authConfig, NewPool.AuthV4, NewPool.AuthV6, pool.useByDefault);
|
ParseServerList(pool.authConfig, NewPool.AuthV4, NewPool.AuthV6,
|
||||||
ParseServerList(pool.acctConfig, NewPool.AcctV4, NewPool.AcctV6, pool.useByDefault);
|
pool.useByDefault);
|
||||||
ParseServerList(pool.coaConfig, NewPool.CoaV4, NewPool.CoaV6, pool.useByDefault);
|
ParseServerList(pool.acctConfig, NewPool.AcctV4, NewPool.AcctV6,
|
||||||
|
pool.useByDefault);
|
||||||
|
ParseServerList(pool.coaConfig, NewPool.CoaV4, NewPool.CoaV6,
|
||||||
|
pool.useByDefault);
|
||||||
Pools_.push_back(NewPool);
|
Pools_.push_back(NewPool);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
poco_warning(Logger(),fmt::format("Configuration file '{}' is bad.",ConfigFilename_));
|
poco_warning(Logger(),
|
||||||
|
fmt::format("Configuration file '{}' is bad.", ConfigFilename_));
|
||||||
}
|
}
|
||||||
} else {
|
} 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) {
|
} catch (const Poco::Exception &E) {
|
||||||
Logger().log(E);
|
Logger().log(E);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
poco_error(Logger(),fmt::format("Error while parsing configuration file '{}'",ConfigFilename_));
|
poco_error(Logger(),
|
||||||
|
fmt::format("Error while parsing configuration file '{}'", ConfigFilename_));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool RealmMatch(const std::string &user_realm, const std::string & realm) {
|
static bool RealmMatch(const std::string &user_realm, const std::string &realm) {
|
||||||
if(realm.find_first_of('*') == std::string::npos)
|
if (realm.find_first_of('*') == std::string::npos)
|
||||||
return user_realm == realm;
|
return user_realm == realm;
|
||||||
return realm.find(user_realm) != std::string::npos;
|
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
|
||||||
bool IsV4 = RequestedAddress.family()==Poco::Net::SocketAddress::IPv4;
|
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...
|
// find the realm...
|
||||||
auto UserName = P.UserName();
|
auto UserName = P.UserName();
|
||||||
if(!UserName.empty()) {
|
if (!UserName.empty()) {
|
||||||
auto UserTokens = Poco::StringTokenizer(UserName, "@");
|
auto UserTokens = Poco::StringTokenizer(UserName, "@");
|
||||||
auto UserRealm = ((UserTokens.count() > 1) ? UserTokens[1] : UserName);
|
auto UserRealm = ((UserTokens.count() > 1) ? UserTokens[1] : UserName);
|
||||||
Poco::toLowerInPlace(UserRealm);
|
Poco::toLowerInPlace(UserRealm);
|
||||||
|
|
||||||
for(const auto &pool:Pools_) {
|
for (const auto &pool : Pools_) {
|
||||||
for(const auto &server:pool.AuthV4) {
|
for (const auto &server : pool.AuthV4) {
|
||||||
if(!server.realms.empty()) {
|
if (!server.realms.empty()) {
|
||||||
for(const auto &realm:server.realms) {
|
for (const auto &realm : server.realms) {
|
||||||
if (RealmMatch(UserRealm,realm)) {
|
if (RealmMatch(UserRealm, realm)) {
|
||||||
std::cout << "Realm match..." << std::endl;
|
std::cout << "Realm match..." << std::endl;
|
||||||
UseRADSEC = true;
|
UseRADSEC = true;
|
||||||
return server.Addr;
|
return server.Addr;
|
||||||
@@ -491,12 +555,13 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(DefaultIsRADSEC_) {
|
if (DefaultIsRADSEC_) {
|
||||||
UseRADSEC = true;
|
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) {
|
switch (rtype) {
|
||||||
case radius_type::auth: {
|
case radius_type::auth: {
|
||||||
return ChooseAddress(IsV4 ? Pools_[DefaultPoolIndex_].AuthV4
|
return ChooseAddress(IsV4 ? Pools_[DefaultPoolIndex_].AuthV4
|
||||||
: Pools_[DefaultPoolIndex_].AuthV6,
|
: Pools_[DefaultPoolIndex_].AuthV6,
|
||||||
@@ -516,33 +581,39 @@ 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_);
|
std::lock_guard G(Mutex_);
|
||||||
|
|
||||||
if(Pools_.empty()) {
|
if (Pools_.empty()) {
|
||||||
UseRADSEC = false;
|
UseRADSEC = false;
|
||||||
return RequestedAddress;
|
return RequestedAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsV4 = RequestedAddress.family()==Poco::Net::SocketAddress::IPv4;
|
bool IsV4 = RequestedAddress.family() == Poco::Net::SocketAddress::IPv4;
|
||||||
bool useDefault;
|
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) {
|
if (useDefault) {
|
||||||
return DefaultRoute(rtype, RequestedAddress, P, UseRADSEC);
|
return DefaultRoute(rtype, RequestedAddress, P, UseRADSEC);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto isAddressInPool = [&](const std::vector<Destination> & D, bool &UseRADSEC) -> bool {
|
auto isAddressInPool = [&](const std::vector<Destination> &D, bool &UseRADSEC) -> bool {
|
||||||
for(const auto &entry:D)
|
for (const auto &entry : D)
|
||||||
if(entry.Addr.host()==RequestedAddress.host()) {
|
if (entry.Addr.host() == RequestedAddress.host()) {
|
||||||
UseRADSEC = entry.useRADSEC;
|
UseRADSEC = entry.useRADSEC;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
for(auto &i:Pools_) {
|
for (auto &i : Pools_) {
|
||||||
switch(rtype) {
|
switch (rtype) {
|
||||||
case radius_type::coa: {
|
case radius_type::coa: {
|
||||||
if (isAddressInPool((IsV4 ? i.CoaV4 : i.CoaV6), UseRADSEC)) {
|
if (isAddressInPool((IsV4 ? i.CoaV4 : i.CoaV6), UseRADSEC)) {
|
||||||
return ChooseAddress(IsV4 ? i.CoaV4 : i.CoaV6, RequestedAddress);
|
return ChooseAddress(IsV4 ? i.CoaV4 : i.CoaV6, RequestedAddress);
|
||||||
@@ -565,9 +636,11 @@ namespace OpenWifi {
|
|||||||
return RequestedAddress;
|
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) {
|
if (Pool.size() == 1) {
|
||||||
return Pool[0].Addr;
|
return Pool[0].Addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -633,7 +706,7 @@ namespace OpenWifi {
|
|||||||
Poco::JSON::Object Disk;
|
Poco::JSON::Object Disk;
|
||||||
C.to_json(Disk);
|
C.to_json(Disk);
|
||||||
|
|
||||||
std::ofstream ofs(ConfigFilename_, std::ios_base::trunc | std::ios_base::binary );
|
std::ofstream ofs(ConfigFilename_, std::ios_base::trunc | std::ios_base::binary);
|
||||||
Disk.stringify(ofs);
|
Disk.stringify(ofs);
|
||||||
ofs.close();
|
ofs.close();
|
||||||
|
|
||||||
@@ -646,8 +719,8 @@ namespace OpenWifi {
|
|||||||
void RADIUS_proxy_server::ResetConfig() {
|
void RADIUS_proxy_server::ResetConfig() {
|
||||||
PoolList_.pools.clear();
|
PoolList_.pools.clear();
|
||||||
Pools_.clear();
|
Pools_.clear();
|
||||||
DefaultPoolIndex_=0;
|
DefaultPoolIndex_ = 0;
|
||||||
DefaultIsRADSEC_=false;
|
DefaultIsRADSEC_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RADIUS_proxy_server::DeleteConfig() {
|
void RADIUS_proxy_server::DeleteConfig() {
|
||||||
@@ -658,7 +731,6 @@ namespace OpenWifi {
|
|||||||
if (F.exists())
|
if (F.exists())
|
||||||
F.remove();
|
F.remove();
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
|
||||||
}
|
}
|
||||||
Stop();
|
Stop();
|
||||||
ResetConfig();
|
ResetConfig();
|
||||||
@@ -669,4 +741,4 @@ namespace OpenWifi {
|
|||||||
C = PoolList_;
|
C = PoolList_;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace OpenWifi
|
||||||
@@ -15,15 +15,12 @@
|
|||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
enum class radius_type {
|
enum class radius_type { auth, acct, coa };
|
||||||
auth, acct, coa
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class RADIUS_proxy_server : public SubSystemServer {
|
class RADIUS_proxy_server : public SubSystemServer {
|
||||||
public:
|
public:
|
||||||
inline static auto instance() {
|
inline static auto instance() {
|
||||||
static auto instance_= new RADIUS_proxy_server;
|
static auto instance_ = new RADIUS_proxy_server;
|
||||||
return instance_;
|
return instance_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,12 +28,15 @@ namespace OpenWifi {
|
|||||||
void Stop() final;
|
void Stop() final;
|
||||||
inline bool Enabled() const { return Enabled_; }
|
inline bool Enabled() const { return Enabled_; }
|
||||||
|
|
||||||
void OnAccountingSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf);
|
void OnAccountingSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf);
|
||||||
void OnAuthenticationSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf);
|
void
|
||||||
void OnCoASocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf);
|
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 SendAccountingData(const std::string &serialNumber, const char *buffer,
|
||||||
void SendAuthenticationData(const std::string &serialNumber, const char *buffer, std::size_t size);
|
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 SendCoAData(const std::string &serialNumber, const char *buffer, std::size_t size);
|
||||||
|
|
||||||
void SetConfig(const GWObjects::RadiusProxyPoolList &C);
|
void SetConfig(const GWObjects::RadiusProxyPoolList &C);
|
||||||
@@ -50,20 +50,18 @@ namespace OpenWifi {
|
|||||||
Poco::Net::SocketAddress Addr;
|
Poco::Net::SocketAddress Addr;
|
||||||
uint64_t state = 0;
|
uint64_t state = 0;
|
||||||
uint64_t step = 0;
|
uint64_t step = 0;
|
||||||
uint64_t weight=0;
|
uint64_t weight = 0;
|
||||||
bool available = true;
|
bool available = true;
|
||||||
std::string strategy;
|
std::string strategy;
|
||||||
bool monitor=false;
|
bool monitor = false;
|
||||||
std::string monitorMethod;
|
std::string monitorMethod;
|
||||||
std::vector<std::string> methodParameters;
|
std::vector<std::string> methodParameters;
|
||||||
bool useAsDefault=false;
|
bool useAsDefault = false;
|
||||||
bool useRADSEC=false;
|
bool useRADSEC = false;
|
||||||
std::vector<std::string> realms;
|
std::vector<std::string> realms;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool Continue() const {
|
inline bool Continue() const { return Running_ && Enabled_ && !Pools_.empty(); }
|
||||||
return Running_ && Enabled_ && !Pools_.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<Poco::Net::DatagramSocket> AccountingSocketV4_;
|
std::unique_ptr<Poco::Net::DatagramSocket> AccountingSocketV4_;
|
||||||
@@ -90,27 +88,32 @@ namespace OpenWifi {
|
|||||||
};
|
};
|
||||||
|
|
||||||
std::vector<RadiusPool> Pools_;
|
std::vector<RadiusPool> Pools_;
|
||||||
uint DefaultPoolIndex_=0;
|
uint DefaultPoolIndex_ = 0;
|
||||||
bool Enabled_=false;
|
bool Enabled_ = false;
|
||||||
bool DefaultIsRADSEC_=false;
|
bool DefaultIsRADSEC_ = false;
|
||||||
std::atomic_bool Running_=false;
|
std::atomic_bool Running_ = false;
|
||||||
|
|
||||||
RADIUS_proxy_server() noexcept:
|
RADIUS_proxy_server() noexcept
|
||||||
SubSystemServer("RADIUS-PROXY", "RADIUS-PROXY", "radius.proxy")
|
: 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 ParseConfig();
|
||||||
void ResetConfig();
|
void ResetConfig();
|
||||||
Poco::Net::SocketAddress Route(radius_type rtype, const Poco::Net::SocketAddress &A, const RADIUS::RadiusPacket &P, bool &UseRADSEC);
|
Poco::Net::SocketAddress Route(radius_type rtype, const Poco::Net::SocketAddress &A,
|
||||||
void ParseServerList(const GWObjects::RadiusProxyServerConfig & Config, std::vector<Destination> &V4, std::vector<Destination> &V6, bool setAsDefault);
|
const RADIUS::RadiusPacket &P, bool &UseRADSEC);
|
||||||
static Poco::Net::SocketAddress ChooseAddress(std::vector<Destination> &Pool, const Poco::Net::SocketAddress & OriginalAddress);
|
void ParseServerList(const GWObjects::RadiusProxyServerConfig &Config,
|
||||||
Poco::Net::SocketAddress DefaultRoute([[maybe_unused]] radius_type rtype, const Poco::Net::SocketAddress &RequestedAddress, const RADIUS::RadiusPacket &P, bool &UseRADSEC);
|
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(); }
|
inline auto RADIUS_proxy_server() { return RADIUS_proxy_server::instance(); }
|
||||||
|
|
||||||
}
|
} // namespace OpenWifi
|
||||||
|
|
||||||
|
|||||||
@@ -4,42 +4,37 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include "RESTObjects/RESTAPI_GWobjects.h"
|
#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/Crypto/X509Certificate.h"
|
||||||
|
#include "Poco/Net/Context.h"
|
||||||
#include "Poco/Net/NetException.h"
|
#include "Poco/Net/NetException.h"
|
||||||
|
#include "Poco/Net/SecureStreamSocket.h"
|
||||||
|
#include "Poco/Net/SocketReactor.h"
|
||||||
#include "Poco/TemporaryFile.h"
|
#include "Poco/TemporaryFile.h"
|
||||||
|
|
||||||
#include "framework/MicroServiceFuncs.h"
|
#include "framework/MicroServiceFuncs.h"
|
||||||
|
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
|
|
||||||
#include "RADIUS_helpers.h"
|
|
||||||
#include "AP_WS_Server.h"
|
#include "AP_WS_Server.h"
|
||||||
|
#include "RADIUS_helpers.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
class RADSEC_server : public Poco::Runnable {
|
class RADSEC_server : public Poco::Runnable {
|
||||||
public:
|
public:
|
||||||
RADSEC_server(Poco::Net::SocketReactor & R, GWObjects::RadiusProxyServerEntry E) :
|
RADSEC_server(Poco::Net::SocketReactor &R, GWObjects::RadiusProxyServerEntry E)
|
||||||
Reactor_(R),
|
: Reactor_(R), Server_(std::move(E)),
|
||||||
Server_(std::move(E)),
|
Logger_(Poco::Logger::get(
|
||||||
Logger_(Poco::Logger::get(fmt::format("RADSEC: {}@{}:{}",
|
fmt::format("RADSEC: {}@{}:{}", Server_.name, Server_.ip, Server_.port))) {
|
||||||
Server_.name ,
|
|
||||||
Server_.ip,
|
|
||||||
Server_.port))) {
|
|
||||||
Start();
|
Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
~RADSEC_server() {
|
~RADSEC_server() { Stop(); }
|
||||||
Stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int Start() {
|
inline int Start() {
|
||||||
ReconnectThread_.start(*this);
|
ReconnectThread_.start(*this);
|
||||||
@@ -55,17 +50,17 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
inline void run() final {
|
inline void run() final {
|
||||||
Poco::Thread::trySleep(3000);
|
Poco::Thread::trySleep(3000);
|
||||||
std::uint64_t LastStatus=0 ;
|
std::uint64_t LastStatus = 0;
|
||||||
auto RadSecKeepAlive = MicroServiceConfigGetInt("radsec.keepalive",120);
|
auto RadSecKeepAlive = MicroServiceConfigGetInt("radsec.keepalive", 120);
|
||||||
while(TryAgain_) {
|
while (TryAgain_) {
|
||||||
if(!Connected_) {
|
if (!Connected_) {
|
||||||
std::lock_guard G(LocalMutex_);
|
std::lock_guard G(LocalMutex_);
|
||||||
LastStatus = Utils::Now() ;
|
LastStatus = Utils::Now();
|
||||||
Connect();
|
Connect();
|
||||||
} else if( (Utils::Now() - LastStatus) > RadSecKeepAlive) {
|
} else if ((Utils::Now() - LastStatus) > RadSecKeepAlive) {
|
||||||
RADIUS::RadiusOutputPacket P(Server_.radsecSecret);
|
RADIUS::RadiusOutputPacket P(Server_.radsecSecret);
|
||||||
P.MakeStatusMessage();
|
P.MakeStatusMessage();
|
||||||
poco_information(Logger_,"Keep-Alive message.");
|
poco_information(Logger_, "Keep-Alive message.");
|
||||||
Socket_->sendBytes(P.Data(), P.Len());
|
Socket_->sendBytes(P.Data(), P.Len());
|
||||||
LastStatus = Utils::Now();
|
LastStatus = Utils::Now();
|
||||||
}
|
}
|
||||||
@@ -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 {
|
try {
|
||||||
if (Connected_) {
|
if (Connected_) {
|
||||||
RADIUS::RadiusPacket P(buffer, length);
|
RADIUS::RadiusPacket P(buffer, length);
|
||||||
@@ -93,21 +89,22 @@ namespace OpenWifi {
|
|||||||
} catch (const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
Logger_.log(E);
|
Logger_.log(E);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
poco_warning(Logger_,"Exception occurred: while sending data.");
|
poco_warning(Logger_, "Exception occurred: while sending data.");
|
||||||
}
|
}
|
||||||
return false;
|
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];
|
unsigned char Buffer[4096];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
auto NumberOfReceivedBytes = Socket_->receiveBytes(Buffer,sizeof(Buffer));
|
auto NumberOfReceivedBytes = Socket_->receiveBytes(Buffer, sizeof(Buffer));
|
||||||
if(NumberOfReceivedBytes>=20) {
|
if (NumberOfReceivedBytes >= 20) {
|
||||||
RADIUS::RadiusPacket P(Buffer,NumberOfReceivedBytes);
|
RADIUS::RadiusPacket P(Buffer, NumberOfReceivedBytes);
|
||||||
if (P.IsAuthentication()) {
|
if (P.IsAuthentication()) {
|
||||||
auto SerialNumber = P.ExtractSerialNumberFromProxyState();
|
auto SerialNumber = P.ExtractSerialNumberFromProxyState();
|
||||||
if(!SerialNumber.empty()) {
|
if (!SerialNumber.empty()) {
|
||||||
poco_debug(Logger_,
|
poco_debug(Logger_,
|
||||||
fmt::format("{}: {} Received {} bytes.", SerialNumber,
|
fmt::format("{}: {} Received {} bytes.", SerialNumber,
|
||||||
P.PacketType(), NumberOfReceivedBytes));
|
P.PacketType(), NumberOfReceivedBytes));
|
||||||
@@ -118,7 +115,7 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
} else if (P.IsAccounting()) {
|
} else if (P.IsAccounting()) {
|
||||||
auto SerialNumber = P.ExtractSerialNumberFromProxyState();
|
auto SerialNumber = P.ExtractSerialNumberFromProxyState();
|
||||||
if(!SerialNumber.empty()) {
|
if (!SerialNumber.empty()) {
|
||||||
poco_debug(Logger_,
|
poco_debug(Logger_,
|
||||||
fmt::format("{}: {} Received {} bytes.", SerialNumber,
|
fmt::format("{}: {} Received {} bytes.", SerialNumber,
|
||||||
P.PacketType(), NumberOfReceivedBytes));
|
P.PacketType(), NumberOfReceivedBytes));
|
||||||
@@ -129,7 +126,7 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
} else if (P.IsAuthority()) {
|
} else if (P.IsAuthority()) {
|
||||||
auto SerialNumber = P.ExtractSerialNumberTIP();
|
auto SerialNumber = P.ExtractSerialNumberTIP();
|
||||||
if(!SerialNumber.empty()) {
|
if (!SerialNumber.empty()) {
|
||||||
poco_debug(Logger_,
|
poco_debug(Logger_,
|
||||||
fmt::format("{}: {} Received {} bytes.", SerialNumber,
|
fmt::format("{}: {} Received {} bytes.", SerialNumber,
|
||||||
P.PacketType(), NumberOfReceivedBytes));
|
P.PacketType(), NumberOfReceivedBytes));
|
||||||
@@ -139,10 +136,12 @@ namespace OpenWifi {
|
|||||||
poco_debug(Logger_, "CoA/DM packet dropped.");
|
poco_debug(Logger_, "CoA/DM packet dropped.");
|
||||||
}
|
}
|
||||||
} else {
|
} 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 {
|
} else {
|
||||||
poco_warning(Logger_,"Invalid packet received. Resetting the connection.");
|
poco_warning(Logger_, "Invalid packet received. Resetting the connection.");
|
||||||
Disconnect();
|
Disconnect();
|
||||||
}
|
}
|
||||||
} catch (const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
@@ -150,22 +149,24 @@ namespace OpenWifi {
|
|||||||
Disconnect();
|
Disconnect();
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
Disconnect();
|
Disconnect();
|
||||||
poco_warning(Logger_,"Exception occurred. Resetting the connection.");
|
poco_warning(Logger_, "Exception occurred. Resetting the connection.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void onError([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ErrorNotification>& pNf) {
|
inline void
|
||||||
poco_warning(Logger_,"Socker error. Terminating connection.");
|
onError([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf) {
|
||||||
|
poco_warning(Logger_, "Socker error. Terminating connection.");
|
||||||
Disconnect();
|
Disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void onShutdown([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification>& pNf) {
|
inline void
|
||||||
poco_warning(Logger_,"Socker socket shutdown. Terminating connection.");
|
onShutdown([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf) {
|
||||||
|
poco_warning(Logger_, "Socker socket shutdown. Terminating connection.");
|
||||||
Disconnect();
|
Disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool Connect() {
|
inline bool Connect() {
|
||||||
if(TryAgain_) {
|
if (TryAgain_) {
|
||||||
std::lock_guard G(LocalMutex_);
|
std::lock_guard G(LocalMutex_);
|
||||||
|
|
||||||
Poco::TemporaryFile CertFile_(MicroServiceDataDirectory());
|
Poco::TemporaryFile CertFile_(MicroServiceDataDirectory());
|
||||||
@@ -175,21 +176,21 @@ namespace OpenWifi {
|
|||||||
DecodeFile(CertFile_.path(), Server_.radsecCert);
|
DecodeFile(CertFile_.path(), Server_.radsecCert);
|
||||||
DecodeFile(KeyFile_.path(), Server_.radsecKey);
|
DecodeFile(KeyFile_.path(), Server_.radsecKey);
|
||||||
|
|
||||||
for(auto &cert:Server_.radsecCacerts) {
|
for (auto &cert : Server_.radsecCacerts) {
|
||||||
CaCertFiles_.emplace_back(std::make_unique<Poco::TemporaryFile>(MicroServiceDataDirectory()));
|
CaCertFiles_.emplace_back(
|
||||||
DecodeFile(CaCertFiles_[CaCertFiles_.size()-1]->path(), cert);
|
std::make_unique<Poco::TemporaryFile>(MicroServiceDataDirectory()));
|
||||||
|
DecodeFile(CaCertFiles_[CaCertFiles_.size() - 1]->path(), cert);
|
||||||
}
|
}
|
||||||
|
|
||||||
Poco::Net::Context::Ptr SecureContext = Poco::AutoPtr<Poco::Net::Context>(
|
Poco::Net::Context::Ptr SecureContext =
|
||||||
new Poco::Net::Context(Poco::Net::Context::TLS_CLIENT_USE,
|
Poco::AutoPtr<Poco::Net::Context>(new Poco::Net::Context(
|
||||||
KeyFile_.path(),
|
Poco::Net::Context::TLS_CLIENT_USE, KeyFile_.path(), CertFile_.path(), ""));
|
||||||
CertFile_.path(),""));
|
if (Server_.allowSelfSigned) {
|
||||||
if(Server_.allowSelfSigned) {
|
|
||||||
SecureContext->setSecurityLevel(Poco::Net::Context::SECURITY_LEVEL_NONE);
|
SecureContext->setSecurityLevel(Poco::Net::Context::SECURITY_LEVEL_NONE);
|
||||||
SecureContext->enableExtendedCertificateVerification(false);
|
SecureContext->enableExtendedCertificateVerification(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(const auto &ca:CaCertFiles_) {
|
for (const auto &ca : CaCertFiles_) {
|
||||||
Poco::Crypto::X509Certificate cert(ca->path());
|
Poco::Crypto::X509Certificate cert(ca->path());
|
||||||
SecureContext->addCertificateAuthority(cert);
|
SecureContext->addCertificateAuthority(cert);
|
||||||
}
|
}
|
||||||
@@ -203,49 +204,48 @@ namespace OpenWifi {
|
|||||||
Socket_->connect(Destination, Poco::Timespan(100, 0));
|
Socket_->connect(Destination, Poco::Timespan(100, 0));
|
||||||
Socket_->completeHandshake();
|
Socket_->completeHandshake();
|
||||||
|
|
||||||
if(!Server_.allowSelfSigned) {
|
if (!Server_.allowSelfSigned) {
|
||||||
Socket_->verifyPeerCertificate();
|
Socket_->verifyPeerCertificate();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Socket_->havePeerCertificate()) {
|
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);
|
Socket_->setBlocking(false);
|
||||||
Socket_->setNoDelay(true);
|
Socket_->setNoDelay(true);
|
||||||
Socket_->setKeepAlive(true);
|
Socket_->setKeepAlive(true);
|
||||||
Socket_->setReceiveTimeout(Poco::Timespan(1 * 60 * 60,0));
|
Socket_->setReceiveTimeout(Poco::Timespan(1 * 60 * 60, 0));
|
||||||
|
|
||||||
Reactor_.addEventHandler(
|
Reactor_.addEventHandler(
|
||||||
*Socket_,
|
*Socket_, Poco::NObserver<RADSEC_server, Poco::Net::ReadableNotification>(
|
||||||
Poco::NObserver<RADSEC_server, Poco::Net::ReadableNotification>(
|
|
||||||
*this, &RADSEC_server::onData));
|
*this, &RADSEC_server::onData));
|
||||||
Reactor_.addEventHandler(
|
Reactor_.addEventHandler(
|
||||||
*Socket_, Poco::NObserver<RADSEC_server, Poco::Net::ErrorNotification>(
|
*Socket_, Poco::NObserver<RADSEC_server, Poco::Net::ErrorNotification>(
|
||||||
*this, &RADSEC_server::onError));
|
*this, &RADSEC_server::onError));
|
||||||
Reactor_.addEventHandler(
|
Reactor_.addEventHandler(
|
||||||
*Socket_,
|
*Socket_, Poco::NObserver<RADSEC_server, Poco::Net::ShutdownNotification>(
|
||||||
Poco::NObserver<RADSEC_server, Poco::Net::ShutdownNotification>(
|
|
||||||
*this, &RADSEC_server::onShutdown));
|
*this, &RADSEC_server::onShutdown));
|
||||||
|
|
||||||
Connected_ = true;
|
Connected_ = true;
|
||||||
poco_information(Logger_,fmt::format("Connected. CN={}",CommonName()));
|
poco_information(Logger_, fmt::format("Connected. CN={}", CommonName()));
|
||||||
return true;
|
return true;
|
||||||
} catch (const Poco::Net::NetException &E) {
|
} catch (const Poco::Net::NetException &E) {
|
||||||
poco_information(Logger_,"Could not connect.");
|
poco_information(Logger_, "Could not connect.");
|
||||||
Logger_.log(E);
|
Logger_.log(E);
|
||||||
} catch (const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
poco_information(Logger_,"Could not connect.");
|
poco_information(Logger_, "Could not connect.");
|
||||||
Logger_.log(E);
|
Logger_.log(E);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
poco_information(Logger_,"Could not connect.");
|
poco_information(Logger_, "Could not connect.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Disconnect() {
|
inline void Disconnect() {
|
||||||
if(Connected_) {
|
if (Connected_) {
|
||||||
std::lock_guard G(LocalMutex_);
|
std::lock_guard G(LocalMutex_);
|
||||||
|
|
||||||
Reactor_.removeEventHandler(
|
Reactor_.removeEventHandler(
|
||||||
@@ -260,31 +260,32 @@ namespace OpenWifi {
|
|||||||
Socket_->close();
|
Socket_->close();
|
||||||
Connected_ = false;
|
Connected_ = false;
|
||||||
}
|
}
|
||||||
poco_information(Logger_,"Disconnecting.");
|
poco_information(Logger_, "Disconnecting.");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DecodeFile(const std::string &filename, const std::string &s) {
|
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);
|
std::stringstream is(s);
|
||||||
Poco::Base64Decoder ds(is);
|
Poco::Base64Decoder ds(is);
|
||||||
Poco::StreamCopier::copyStream(ds,sec_file);
|
Poco::StreamCopier::copyStream(ds, sec_file);
|
||||||
sec_file.close();
|
sec_file.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] inline std::string CommonName() {
|
[[nodiscard]] inline std::string CommonName() {
|
||||||
if(Peer_Cert_)
|
if (Peer_Cert_)
|
||||||
return Peer_Cert_->commonName();
|
return Peer_Cert_->commonName();
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] inline std::string IssuerName() {
|
[[nodiscard]] inline std::string IssuerName() {
|
||||||
if(Peer_Cert_)
|
if (Peer_Cert_)
|
||||||
return Peer_Cert_->issuerName();
|
return Peer_Cert_->issuerName();
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] inline std::string SubjectName() {
|
[[nodiscard]] inline std::string SubjectName() {
|
||||||
if(Peer_Cert_)
|
if (Peer_Cert_)
|
||||||
return Peer_Cert_->subjectName();
|
return Peer_Cert_->subjectName();
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@@ -297,7 +298,7 @@ namespace OpenWifi {
|
|||||||
std::unique_ptr<Poco::Net::SecureStreamSocket> Socket_;
|
std::unique_ptr<Poco::Net::SecureStreamSocket> Socket_;
|
||||||
Poco::Thread ReconnectThread_;
|
Poco::Thread ReconnectThread_;
|
||||||
std::unique_ptr<Poco::Crypto::X509Certificate> Peer_Cert_;
|
std::unique_ptr<Poco::Crypto::X509Certificate> Peer_Cert_;
|
||||||
volatile bool Connected_=false;
|
volatile bool Connected_ = false;
|
||||||
volatile bool TryAgain_=true;
|
volatile bool TryAgain_ = true;
|
||||||
};
|
};
|
||||||
}
|
} // namespace OpenWifi
|
||||||
@@ -4,26 +4,26 @@
|
|||||||
|
|
||||||
#include "SDKcalls.h"
|
#include "SDKcalls.h"
|
||||||
|
|
||||||
#include "framework/OpenAPIRequests.h"
|
|
||||||
#include "framework/MicroServiceNames.h"
|
#include "framework/MicroServiceNames.h"
|
||||||
|
#include "framework/OpenAPIRequests.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
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"}};
|
Types::StringPairVec QD{{"config", "true"}};
|
||||||
OpenAPIRequestGet API(uSERVICE_PROVISIONING,
|
OpenAPIRequestGet API(uSERVICE_PROVISIONING, "/api/v1/inventory/" + SerialNumber, QD,
|
||||||
"/api/v1/inventory/" + SerialNumber,
|
20000);
|
||||||
QD,20000);
|
|
||||||
|
|
||||||
Poco::JSON::Object::Ptr ResponseObject;
|
Poco::JSON::Object::Ptr ResponseObject;
|
||||||
|
|
||||||
if(API.Do(ResponseObject)==Poco::Net::HTTPResponse::HTTP_OK) {
|
if (API.Do(ResponseObject) == Poco::Net::HTTPResponse::HTTP_OK) {
|
||||||
if(ResponseObject->has("config")) {
|
if (ResponseObject->has("config")) {
|
||||||
Config = ResponseObject->get("config").toString();
|
Config = ResponseObject->get("config").toString();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} // namespace OpenWifi
|
||||||
|
|||||||
@@ -9,8 +9,9 @@
|
|||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
class SDKCalls {
|
class SDKCalls {
|
||||||
public:
|
public:
|
||||||
static bool GetProvisioningConfiguration(const std::string & SerialNumber, std::string & Config);
|
static bool GetProvisioningConfiguration(const std::string &SerialNumber,
|
||||||
|
std::string &Config);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
}
|
} // namespace OpenWifi
|
||||||
|
|
||||||
|
|||||||
@@ -3,21 +3,22 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "ScriptManager.h"
|
#include "ScriptManager.h"
|
||||||
|
#include "Poco/JSON/Parser.h"
|
||||||
#include "framework/MicroServiceFuncs.h"
|
#include "framework/MicroServiceFuncs.h"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include "Poco/JSON/Parser.h"
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
int ScriptManager::Start() {
|
int ScriptManager::Start() {
|
||||||
poco_notice(Logger(),"Starting...");
|
poco_notice(Logger(), "Starting...");
|
||||||
ScriptDir_ = MicroServiceConfigPath("script.manager.directory", MicroServiceDataDirectory() + "/included_scripts" );
|
ScriptDir_ = MicroServiceConfigPath("script.manager.directory",
|
||||||
|
MicroServiceDataDirectory() + "/included_scripts");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptManager::Stop() {
|
void ScriptManager::Stop() {
|
||||||
poco_notice(Logger(),"Stopping...");
|
poco_notice(Logger(), "Stopping...");
|
||||||
poco_notice(Logger(),"Stopped...");
|
poco_notice(Logger(), "Stopped...");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace OpenWifi
|
} // namespace OpenWifi
|
||||||
@@ -21,14 +21,10 @@ namespace OpenWifi {
|
|||||||
private:
|
private:
|
||||||
std::string ScriptDir_;
|
std::string ScriptDir_;
|
||||||
|
|
||||||
explicit ScriptManager() noexcept:
|
explicit ScriptManager() noexcept
|
||||||
SubSystemServer("ScriptManager", "SCRIPT-MGR", "script.manager")
|
: SubSystemServer("ScriptManager", "SCRIPT-MGR", "script.manager") {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline auto ScriptManager() { return ScriptManager::instance(); }
|
inline auto ScriptManager() { return ScriptManager::instance(); }
|
||||||
|
|
||||||
} // namespace OpenWifi
|
} // namespace OpenWifi
|
||||||
|
|
||||||
|
|||||||
@@ -11,23 +11,23 @@
|
|||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
int SerialNumberCache::Start() {
|
int SerialNumberCache::Start() {
|
||||||
poco_notice(Logger(),"Starting...");
|
poco_notice(Logger(), "Starting...");
|
||||||
StorageService()->UpdateSerialNumberCache();
|
StorageService()->UpdateSerialNumberCache();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerialNumberCache::Stop() {
|
void SerialNumberCache::Stop() {
|
||||||
poco_notice(Logger(),"Stopping...");
|
poco_notice(Logger(), "Stopping...");
|
||||||
SNs_.clear();
|
SNs_.clear();
|
||||||
Reverse_SNs_.clear();
|
Reverse_SNs_.clear();
|
||||||
poco_notice(Logger(),"Stopped...");
|
poco_notice(Logger(), "Stopped...");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerialNumberCache::AddSerialNumber(const std::string &S) {
|
void SerialNumberCache::AddSerialNumber(const std::string &S) {
|
||||||
std::lock_guard G(Mutex_);
|
std::lock_guard G(Mutex_);
|
||||||
|
|
||||||
uint64_t SN = std::stoull(S, nullptr, 16);
|
uint64_t SN = std::stoull(S, nullptr, 16);
|
||||||
if(std::find(std::begin(SNs_),std::end(SNs_),SN) == std::end(SNs_)) {
|
if (std::find(std::begin(SNs_), std::end(SNs_), SN) == std::end(SNs_)) {
|
||||||
auto insert_point = std::lower_bound(SNs_.begin(), SNs_.end(), SN);
|
auto insert_point = std::lower_bound(SNs_.begin(), SNs_.end(), SN);
|
||||||
SNs_.insert(insert_point, SN);
|
SNs_.insert(insert_point, SN);
|
||||||
|
|
||||||
@@ -41,15 +41,15 @@ namespace OpenWifi {
|
|||||||
void SerialNumberCache::DeleteSerialNumber(const std::string &S) {
|
void SerialNumberCache::DeleteSerialNumber(const std::string &S) {
|
||||||
std::lock_guard G(Mutex_);
|
std::lock_guard G(Mutex_);
|
||||||
|
|
||||||
uint64_t SN = std::stoull(S,nullptr,16);
|
uint64_t SN = std::stoull(S, nullptr, 16);
|
||||||
auto It = std::find(SNs_.begin(),SNs_.end(),SN);
|
auto It = std::find(SNs_.begin(), SNs_.end(), SN);
|
||||||
if(It != SNs_.end()) {
|
if (It != SNs_.end()) {
|
||||||
SNs_.erase(It);
|
SNs_.erase(It);
|
||||||
|
|
||||||
auto R = ReverseSerialNumber(S);
|
auto R = ReverseSerialNumber(S);
|
||||||
uint64_t RSN = std::stoull(R, nullptr, 16);
|
uint64_t RSN = std::stoull(R, nullptr, 16);
|
||||||
auto RIt = std::find(Reverse_SNs_.begin(),Reverse_SNs_.end(),RSN);
|
auto RIt = std::find(Reverse_SNs_.begin(), Reverse_SNs_.end(), RSN);
|
||||||
if(RIt != Reverse_SNs_.end()) {
|
if (RIt != Reverse_SNs_.end()) {
|
||||||
Reverse_SNs_.erase(RIt);
|
Reverse_SNs_.erase(RIt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -66,7 +66,9 @@ namespace OpenWifi {
|
|||||||
return Res;
|
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_);
|
std::lock_guard G(Mutex_);
|
||||||
|
|
||||||
if (S.length() == 12) {
|
if (S.length() == 12) {
|
||||||
@@ -82,9 +84,10 @@ namespace OpenWifi {
|
|||||||
auto LB = std::lower_bound(SNArr.begin(), SNArr.end(), SN);
|
auto LB = std::lower_bound(SNArr.begin(), SNArr.end(), SN);
|
||||||
if (LB != SNArr.end()) {
|
if (LB != SNArr.end()) {
|
||||||
for (; LB != SNArr.end() && HowMany; ++LB, --HowMany) {
|
for (; LB != SNArr.end() && HowMany; ++LB, --HowMany) {
|
||||||
if(ReverseResult) {
|
if (ReverseResult) {
|
||||||
const auto TSN = ReverseSerialNumber(Utils::IntToSerialNumber(Reverse(*LB)));
|
const auto TSN =
|
||||||
if (S == TSN.substr(0,S.size())) {
|
ReverseSerialNumber(Utils::IntToSerialNumber(Reverse(*LB)));
|
||||||
|
if (S == TSN.substr(0, S.size())) {
|
||||||
A.emplace_back(Reverse(*LB));
|
A.emplace_back(Reverse(*LB));
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
@@ -102,18 +105,19 @@ 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,
|
||||||
if(S.empty())
|
std::vector<uint64_t> &A) {
|
||||||
|
if (S.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (S[0] == '*') {
|
if (S[0] == '*') {
|
||||||
std::string Reversed;
|
std::string Reversed;
|
||||||
std::copy(rbegin(S), rend(S)-1, std::back_inserter(Reversed));
|
std::copy(rbegin(S), rend(S) - 1, std::back_inserter(Reversed));
|
||||||
if(Reversed.empty())
|
if (Reversed.empty())
|
||||||
return;
|
return;
|
||||||
return ReturnNumbers(Reversed, HowMany, Reverse_SNs_, A, true);
|
return ReturnNumbers(Reversed, HowMany, Reverse_SNs_, A, true);
|
||||||
} else {
|
} else {
|
||||||
return ReturnNumbers(S, HowMany, SNs_, A, false);
|
return ReturnNumbers(S, HowMany, SNs_, A, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} // namespace OpenWifi
|
||||||
@@ -9,7 +9,6 @@
|
|||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
class SerialNumberCache : public SubSystemServer {
|
class SerialNumberCache : public SubSystemServer {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static auto instance() {
|
static auto instance() {
|
||||||
static auto instance_ = new SerialNumberCache;
|
static auto instance_ = new SerialNumberCache;
|
||||||
return instance_;
|
return instance_;
|
||||||
@@ -22,12 +21,12 @@ namespace OpenWifi {
|
|||||||
void FindNumbers(const std::string &SerialNumber, uint HowMany, std::vector<uint64_t> &A);
|
void FindNumbers(const std::string &SerialNumber, uint HowMany, std::vector<uint64_t> &A);
|
||||||
inline bool NumberExists(uint64_t SerialNumber) {
|
inline bool NumberExists(uint64_t SerialNumber) {
|
||||||
std::lock_guard G(Mutex_);
|
std::lock_guard G(Mutex_);
|
||||||
return std::find(SNs_.begin(),SNs_.end(),SerialNumber)!=SNs_.end();
|
return std::find(SNs_.begin(), SNs_.end(), SerialNumber) != SNs_.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline std::string ReverseSerialNumber(const std::string &S) {
|
static inline std::string ReverseSerialNumber(const std::string &S) {
|
||||||
std::string ReversedString;
|
std::string ReversedString;
|
||||||
std::copy(rbegin(S),rend(S),std::back_inserter(ReversedString));
|
std::copy(rbegin(S), rend(S), std::back_inserter(ReversedString));
|
||||||
return ReversedString;
|
return ReversedString;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,15 +34,15 @@ namespace OpenWifi {
|
|||||||
std::vector<uint64_t> SNs_;
|
std::vector<uint64_t> SNs_;
|
||||||
std::vector<uint64_t> Reverse_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:
|
SerialNumberCache() noexcept
|
||||||
SubSystemServer("SerialNumberCache", "SNCACHE-SVR", "serialcache")
|
: SubSystemServer("SerialNumberCache", "SNCACHE-SVR", "serialcache") {
|
||||||
{
|
|
||||||
SNs_.reserve(2000);
|
SNs_.reserve(2000);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline auto SerialNumberCache() { return SerialNumberCache::instance(); }
|
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 <fstream>
|
||||||
#include <shared_mutex>
|
#include <shared_mutex>
|
||||||
|
|
||||||
#include "framework/SubSystemServer.h"
|
|
||||||
#include "framework/MicroServiceFuncs.h"
|
#include "framework/MicroServiceFuncs.h"
|
||||||
|
#include "framework/SubSystemServer.h"
|
||||||
#include "framework/utils.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/Crypto/RSADigestEngine.h"
|
||||||
#include "Poco/StreamCopier.h"
|
#include "Poco/DigestEngine.h"
|
||||||
|
#include "Poco/DigestStream.h"
|
||||||
#include "Poco/File.h"
|
#include "Poco/File.h"
|
||||||
|
#include "Poco/StreamCopier.h"
|
||||||
#include "Poco/StringTokenizer.h"
|
#include "Poco/StringTokenizer.h"
|
||||||
#include "Poco/TemporaryFile.h"
|
#include "Poco/TemporaryFile.h"
|
||||||
|
#include "RESTObjects/RESTAPI_GWobjects.h"
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
@@ -36,56 +36,61 @@ namespace OpenWifi {
|
|||||||
};
|
};
|
||||||
|
|
||||||
inline int Start() final {
|
inline int Start() final {
|
||||||
poco_notice(Logger(),"Starting...");
|
poco_notice(Logger(), "Starting...");
|
||||||
|
|
||||||
std::shared_lock L(KeyMutex_);
|
std::shared_lock L(KeyMutex_);
|
||||||
|
|
||||||
CacheFilename_ = MicroServiceDataDirectory() + "/signature_cache";
|
CacheFilename_ = MicroServiceDataDirectory() + "/signature_cache";
|
||||||
Poco::File CacheFile(CacheFilename_);
|
Poco::File CacheFile(CacheFilename_);
|
||||||
|
|
||||||
if(CacheFile.exists()) {
|
if (CacheFile.exists()) {
|
||||||
std::fstream CacheFileContent(CacheFilename_, std::ios_base::in);
|
std::fstream CacheFileContent(CacheFilename_, std::ios_base::in);
|
||||||
std::string line;
|
std::string line;
|
||||||
while(std::getline(CacheFileContent, line)) {
|
while (std::getline(CacheFileContent, line)) {
|
||||||
auto Tokens = Poco::StringTokenizer(line,":");
|
auto Tokens = Poco::StringTokenizer(line, ":");
|
||||||
if(Tokens.count()==2) {
|
if (Tokens.count() == 2) {
|
||||||
SignatureCache_[Tokens[0]] = Tokens[1];
|
SignatureCache_[Tokens[0]] = Tokens[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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.
|
// read all the key vendors.
|
||||||
// signature.manager.0.key.public
|
// signature.manager.0.key.public
|
||||||
// signature.manager.0.key.private
|
// signature.manager.0.key.private
|
||||||
// signature.manager.0.vendor
|
// signature.manager.0.vendor
|
||||||
int i=0;
|
int i = 0;
|
||||||
while(true) {
|
while (true) {
|
||||||
auto Vendor = MicroServiceConfigGetString("signature.manager." + std::to_string(i) + ".vendor","");
|
auto Vendor = MicroServiceConfigGetString(
|
||||||
auto PrivateKey = MicroServiceConfigPath("signature.manager." + std::to_string(i) + ".key.private","");
|
"signature.manager." + std::to_string(i) + ".vendor", "");
|
||||||
auto PublicKey = MicroServiceConfigPath("signature.manager." + std::to_string(i) + ".key.public","");
|
auto PrivateKey = MicroServiceConfigPath(
|
||||||
if(Vendor.empty() || PrivateKey.empty() || PublicKey.empty()) {
|
"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;
|
break;
|
||||||
}
|
}
|
||||||
Poco::File PubKey(PublicKey), PrivKey(PrivateKey);
|
Poco::File PubKey(PublicKey), PrivKey(PrivateKey);
|
||||||
if(PubKey.exists() && PrivKey.exists()) {
|
if (PubKey.exists() && PrivKey.exists()) {
|
||||||
Keys_[Vendor] = Poco::SharedPtr<Poco::Crypto::RSAKey>(
|
Keys_[Vendor] = Poco::SharedPtr<Poco::Crypto::RSAKey>(
|
||||||
new Poco::Crypto::RSAKey(PublicKey, PrivateKey, ""));
|
new Poco::Crypto::RSAKey(PublicKey, PrivateKey, ""));
|
||||||
}
|
}
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
poco_information(Logger(),fmt::format("{} signatures in dictionary.", Keys_.size()));
|
poco_information(Logger(), fmt::format("{} signatures in dictionary.", Keys_.size()));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Stop() final {
|
inline void Stop() final {
|
||||||
poco_notice(Logger(),"Stopping...");
|
poco_notice(Logger(), "Stopping...");
|
||||||
poco_notice(Logger(),"Stopped...");
|
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_);
|
std::shared_lock L(KeyMutex_);
|
||||||
try {
|
try {
|
||||||
if (Restrictions.key_info.algo == "static") {
|
if (Restrictions.key_info.algo == "static") {
|
||||||
@@ -93,7 +98,8 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
auto Vendor = Keys_.find(Restrictions.key_info.vendor);
|
auto Vendor = Keys_.find(Restrictions.key_info.vendor);
|
||||||
if (Vendor == Keys_.end()) {
|
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 "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,7 +118,8 @@ namespace OpenWifi {
|
|||||||
return "";
|
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_);
|
std::shared_lock L(KeyMutex_);
|
||||||
try {
|
try {
|
||||||
if (Restrictions.key_info.algo == "static") {
|
if (Restrictions.key_info.algo == "static") {
|
||||||
@@ -121,13 +128,15 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
auto Vendor = Keys_.find(Restrictions.key_info.vendor);
|
auto Vendor = Keys_.find(Restrictions.key_info.vendor);
|
||||||
if (Vendor == Keys_.end()) {
|
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 "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Restrictions.key_info.algo == "dgst-sha256") {
|
if (Restrictions.key_info.algo == "dgst-sha256") {
|
||||||
auto FileHash =
|
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);
|
auto CacheEntry = SignatureCache_.find(FileHash);
|
||||||
if (CacheEntry != end(SignatureCache_)) {
|
if (CacheEntry != end(SignatureCache_)) {
|
||||||
return CacheEntry->second;
|
return CacheEntry->second;
|
||||||
@@ -141,7 +150,8 @@ namespace OpenWifi {
|
|||||||
std::ios_base::in | std::ios_base::binary);
|
std::ios_base::in | std::ios_base::binary);
|
||||||
Poco::StreamCopier::copyStream(ifs, ofs);
|
Poco::StreamCopier::copyStream(ifs, ofs);
|
||||||
ofs.flush();
|
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;
|
SignatureCache_[FileHash] = Signature;
|
||||||
SaveCache();
|
SaveCache();
|
||||||
return Signature;
|
return Signature;
|
||||||
@@ -156,7 +166,7 @@ namespace OpenWifi {
|
|||||||
void SaveCache() {
|
void SaveCache() {
|
||||||
std::ofstream ofs(CacheFilename_, std::ios_base::trunc | std::ios_base::out);
|
std::ofstream ofs(CacheFilename_, std::ios_base::trunc | std::ios_base::out);
|
||||||
|
|
||||||
for(const auto &[hash,signature]:SignatureCache_) {
|
for (const auto &[hash, signature] : SignatureCache_) {
|
||||||
ofs << hash << ":" << signature << std::endl;
|
ofs << hash << ":" << signature << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -164,7 +174,7 @@ namespace OpenWifi {
|
|||||||
private:
|
private:
|
||||||
mutable std::shared_mutex KeyMutex_;
|
mutable std::shared_mutex KeyMutex_;
|
||||||
std::map<std::string, Poco::SharedPtr<Poco::Crypto::RSAKey>> Keys_;
|
std::map<std::string, Poco::SharedPtr<Poco::Crypto::RSAKey>> Keys_;
|
||||||
std::map<std::string,std::string> SignatureCache_;
|
std::map<std::string, std::string> SignatureCache_;
|
||||||
std::string CacheFilename_;
|
std::string CacheFilename_;
|
||||||
explicit SignatureManager() noexcept
|
explicit SignatureManager() noexcept
|
||||||
: SubSystemServer("SignatureManager", "SIGNATURE-MGR", "signature.manager") {}
|
: SubSystemServer("SignatureManager", "SIGNATURE-MGR", "signature.manager") {}
|
||||||
@@ -172,5 +182,4 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
inline auto SignatureManager() { return SignatureManager::instance(); }
|
inline auto SignatureManager() { return SignatureManager::instance(); }
|
||||||
|
|
||||||
}
|
} // namespace OpenWifi
|
||||||
|
|
||||||
|
|||||||
@@ -8,60 +8,62 @@
|
|||||||
namespace OpenWifi::StateUtils {
|
namespace OpenWifi::StateUtils {
|
||||||
|
|
||||||
static int ChannelToBand(uint64_t C) {
|
static int ChannelToBand(uint64_t C) {
|
||||||
if(C>=1 && C<=16) return 2;
|
if (C >= 1 && C <= 16)
|
||||||
|
return 2;
|
||||||
return 5;
|
return 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int BandToInt(const std::string &band) {
|
static int BandToInt(const std::string &band) {
|
||||||
if(band=="2G") return 2;
|
if (band == "2G")
|
||||||
if(band=="5G") return 5;
|
return 2;
|
||||||
if(band=="6G") return 6;
|
if (band == "5G")
|
||||||
|
return 5;
|
||||||
|
if (band == "6G")
|
||||||
|
return 6;
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ComputeAssociations(const Poco::JSON::Object::Ptr RawObject,
|
bool ComputeAssociations(const Poco::JSON::Object::Ptr RawObject, uint64_t &Radios_2G,
|
||||||
uint64_t &Radios_2G,
|
|
||||||
uint64_t &Radios_5G, uint64_t &Radios_6G) {
|
uint64_t &Radios_5G, uint64_t &Radios_6G) {
|
||||||
Radios_2G = 0 ;
|
Radios_2G = 0;
|
||||||
Radios_5G = 0;
|
Radios_5G = 0;
|
||||||
Radios_6G = 0;
|
Radios_6G = 0;
|
||||||
|
|
||||||
if(RawObject->isArray("radios") && RawObject->isArray("interfaces")) {
|
if (RawObject->isArray("radios") && RawObject->isArray("interfaces")) {
|
||||||
auto RA = RawObject->getArray("radios");
|
auto RA = RawObject->getArray("radios");
|
||||||
// map of phy to 2g/5g
|
// map of phy to 2g/5g
|
||||||
std::map<std::string,int> RadioPHYs;
|
std::map<std::string, int> RadioPHYs;
|
||||||
// parse radios and get the phy out with the band
|
// parse radios and get the phy out with the band
|
||||||
bool UseBandInfo = false;
|
bool UseBandInfo = false;
|
||||||
for(auto const &i:*RA) {
|
for (auto const &i : *RA) {
|
||||||
// Poco::JSON::Parser p2;
|
// Poco::JSON::Parser p2;
|
||||||
auto RadioObj = i.extract<Poco::JSON::Object::Ptr>();
|
auto RadioObj = i.extract<Poco::JSON::Object::Ptr>();
|
||||||
if(RadioObj->has("band")) {
|
if (RadioObj->has("band")) {
|
||||||
// std::cout << "Use band info" << std::endl;
|
// std::cout << "Use band info" << std::endl;
|
||||||
UseBandInfo = true ;
|
UseBandInfo = true;
|
||||||
} else if(RadioObj->has("phy") && RadioObj->has("channel")) {
|
} else if (RadioObj->has("phy") && RadioObj->has("channel")) {
|
||||||
if(RadioObj->isArray("channel")) {
|
if (RadioObj->isArray("channel")) {
|
||||||
auto ChannelArray = RadioObj->getArray("channel");
|
auto ChannelArray = RadioObj->getArray("channel");
|
||||||
if(ChannelArray->size()) {
|
if (ChannelArray->size()) {
|
||||||
RadioPHYs[RadioObj->get("phy")] =
|
RadioPHYs[RadioObj->get("phy")] =
|
||||||
ChannelToBand( ChannelArray->getElement<uint64_t>(0) );
|
ChannelToBand(ChannelArray->getElement<uint64_t>(0));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
RadioPHYs[RadioObj->get("phy")] =
|
RadioPHYs[RadioObj->get("phy")] = ChannelToBand(RadioObj->get("channel"));
|
||||||
ChannelToBand(RadioObj->get("channel"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto InterfaceArray = RawObject->getArray("interfaces");
|
auto InterfaceArray = RawObject->getArray("interfaces");
|
||||||
for(auto const &interface:*InterfaceArray) {
|
for (auto const &interface : *InterfaceArray) {
|
||||||
auto InterfaceObj = interface.extract<Poco::JSON::Object::Ptr>();
|
auto InterfaceObj = interface.extract<Poco::JSON::Object::Ptr>();
|
||||||
if(InterfaceObj->isArray("ssids")) {
|
if (InterfaceObj->isArray("ssids")) {
|
||||||
auto SSIDArray = InterfaceObj->getArray("ssids");
|
auto SSIDArray = InterfaceObj->getArray("ssids");
|
||||||
for(const auto &ssid:*SSIDArray) {
|
for (const auto &ssid : *SSIDArray) {
|
||||||
auto SSID_info = ssid.extract<Poco::JSON::Object::Ptr>();
|
auto SSID_info = ssid.extract<Poco::JSON::Object::Ptr>();
|
||||||
if(SSID_info->isArray("associations") && SSID_info->has("phy")) {
|
if (SSID_info->isArray("associations") && SSID_info->has("phy")) {
|
||||||
int Radio = 2;
|
int Radio = 2;
|
||||||
if(UseBandInfo) {
|
if (UseBandInfo) {
|
||||||
Radio = BandToInt(SSID_info->get("band"));
|
Radio = BandToInt(SSID_info->get("band"));
|
||||||
} else {
|
} else {
|
||||||
auto PHY = SSID_info->get("phy");
|
auto PHY = SSID_info->get("phy");
|
||||||
@@ -70,19 +72,27 @@ namespace OpenWifi::StateUtils {
|
|||||||
Radio = Rit->second;
|
Radio = Rit->second;
|
||||||
}
|
}
|
||||||
auto AssocA = SSID_info->getArray("associations");
|
auto AssocA = SSID_info->getArray("associations");
|
||||||
switch(Radio) {
|
switch (Radio) {
|
||||||
case 2: Radios_2G += AssocA->size(); break;
|
case 2:
|
||||||
case 5: Radios_5G += AssocA->size(); break;
|
Radios_2G += AssocA->size();
|
||||||
case 6: Radios_6G += AssocA->size(); break;
|
break;
|
||||||
default: 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// std::cout << Radios_2G << " " << Radios_5G << " " << Radios_6G << std::endl;
|
// std::cout << Radios_2G << " " << Radios_5G << " " << Radios_6G << std::endl;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} // namespace OpenWifi::StateUtils
|
||||||
@@ -8,42 +8,37 @@
|
|||||||
#include "StorageService.h"
|
#include "StorageService.h"
|
||||||
|
|
||||||
#include "framework/AppServiceRegistry.h"
|
#include "framework/AppServiceRegistry.h"
|
||||||
#include "framework/utils.h"
|
|
||||||
#include "framework/MicroServiceFuncs.h"
|
#include "framework/MicroServiceFuncs.h"
|
||||||
|
#include "framework/utils.h"
|
||||||
|
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
void Archiver::onTimer([[maybe_unused]] Poco::Timer &timer){
|
void Archiver::onTimer([[maybe_unused]] Poco::Timer &timer) {
|
||||||
Utils::SetThreadName("strg-archiver");
|
Utils::SetThreadName("strg-archiver");
|
||||||
auto now = Utils::Now();
|
auto now = Utils::Now();
|
||||||
for(const auto &[DBName, Keep]:DBs_) {
|
for (const auto &[DBName, Keep] : DBs_) {
|
||||||
if (!Poco::icompare(DBName, "healthchecks")) {
|
if (!Poco::icompare(DBName, "healthchecks")) {
|
||||||
poco_information(Logger(),"Archiving HealthChecks...");
|
poco_information(Logger(), "Archiving HealthChecks...");
|
||||||
StorageService()->RemoveHealthChecksRecordsOlderThan(
|
StorageService()->RemoveHealthChecksRecordsOlderThan(now - (Keep * 24 * 60 * 60));
|
||||||
now - (Keep * 24 * 60 * 60));
|
|
||||||
} else if (!Poco::icompare(DBName, "statistics")) {
|
} else if (!Poco::icompare(DBName, "statistics")) {
|
||||||
poco_information(Logger(),"Archiving Statistics...");
|
poco_information(Logger(), "Archiving Statistics...");
|
||||||
StorageService()->RemoveStatisticsRecordsOlderThan(
|
StorageService()->RemoveStatisticsRecordsOlderThan(now - (Keep * 24 * 60 * 60));
|
||||||
now - (Keep * 24 * 60 * 60));
|
|
||||||
} else if (!Poco::icompare(DBName, "devicelogs")) {
|
} else if (!Poco::icompare(DBName, "devicelogs")) {
|
||||||
poco_information(Logger(),"Archiving Device Logs...");
|
poco_information(Logger(), "Archiving Device Logs...");
|
||||||
StorageService()->RemoveDeviceLogsRecordsOlderThan(
|
StorageService()->RemoveDeviceLogsRecordsOlderThan(now - (Keep * 24 * 60 * 60));
|
||||||
now - (Keep * 24 * 60 * 60));
|
|
||||||
} else if (!Poco::icompare(DBName, "commandlist")) {
|
} else if (!Poco::icompare(DBName, "commandlist")) {
|
||||||
poco_information(Logger(),"Archiving Command History...");
|
poco_information(Logger(), "Archiving Command History...");
|
||||||
StorageService()->RemoveCommandListRecordsOlderThan(
|
StorageService()->RemoveCommandListRecordsOlderThan(now - (Keep * 24 * 60 * 60));
|
||||||
now - (Keep * 24 * 60 * 60));
|
|
||||||
} else if (!Poco::icompare(DBName, "fileuploads")) {
|
} else if (!Poco::icompare(DBName, "fileuploads")) {
|
||||||
poco_information(Logger(),"Archiving Upload files...");
|
poco_information(Logger(), "Archiving Upload files...");
|
||||||
StorageService()->RemoveUploadedFilesRecordsOlderThan(
|
StorageService()->RemoveUploadedFilesRecordsOlderThan(now - (Keep * 24 * 60 * 60));
|
||||||
now - (Keep * 24 * 60 * 60));
|
|
||||||
} else {
|
} else {
|
||||||
poco_information(Logger(),fmt::format("Cannot archive DB '{}'", DBName));
|
poco_information(Logger(), fmt::format("Cannot archive DB '{}'", DBName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AppServiceRegistry().Set("lastStorageArchiverRun", (uint64_t) now);
|
AppServiceRegistry().Set("lastStorageArchiverRun", (uint64_t)now);
|
||||||
}
|
}
|
||||||
|
|
||||||
static auto CalculateDelta(std::uint64_t H, std::uint64_t M) {
|
static auto CalculateDelta(std::uint64_t H, std::uint64_t M) {
|
||||||
@@ -51,56 +46,58 @@ namespace OpenWifi {
|
|||||||
Poco::LocalDateTime scheduled(dt.year(), dt.month(), dt.day(), (int)H, (int)M, 0);
|
Poco::LocalDateTime scheduled(dt.year(), dt.month(), dt.day(), (int)H, (int)M, 0);
|
||||||
|
|
||||||
std::uint64_t delta = 0;
|
std::uint64_t delta = 0;
|
||||||
if ((dt.hour() < (int)H) || (dt.hour()==(int)H && dt.minute()<(int)M)) {
|
if ((dt.hour() < (int)H) || (dt.hour() == (int)H && dt.minute() < (int)M)) {
|
||||||
delta = scheduled.timestamp().epochTime() - dt.timestamp().epochTime();
|
delta = scheduled.timestamp().epochTime() - dt.timestamp().epochTime();
|
||||||
} else {
|
} else {
|
||||||
delta = (24*60*60) - (dt.timestamp().epochTime() - scheduled.timestamp().epochTime());
|
delta =
|
||||||
|
(24 * 60 * 60) - (dt.timestamp().epochTime() - scheduled.timestamp().epochTime());
|
||||||
}
|
}
|
||||||
return delta;
|
return delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
int StorageArchiver::Start() {
|
int StorageArchiver::Start() {
|
||||||
|
|
||||||
Enabled_ = MicroServiceConfigGetBool("archiver.enabled",false);
|
Enabled_ = MicroServiceConfigGetBool("archiver.enabled", false);
|
||||||
if(!Enabled_) {
|
if (!Enabled_) {
|
||||||
poco_information(Logger(),"Archiver is disabled.");
|
poco_information(Logger(), "Archiver is disabled.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Archiver_ = std::make_unique<Archiver>(Logger());
|
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 Schedule = MicroServiceConfigGetString("archiver.schedule", "03:00");
|
||||||
auto S = Poco::StringTokenizer(Schedule,":");
|
auto S = Poco::StringTokenizer(Schedule, ":");
|
||||||
|
|
||||||
std::uint64_t RunAtHour_, RunAtMin_;
|
std::uint64_t RunAtHour_, RunAtMin_;
|
||||||
if(S.count()!=2) {
|
if (S.count() != 2) {
|
||||||
RunAtHour_ = 3 ;
|
RunAtHour_ = 3;
|
||||||
RunAtMin_ = 0;
|
RunAtMin_ = 0;
|
||||||
} else {
|
} else {
|
||||||
RunAtHour_ = std::strtoull(S[0].c_str(), nullptr, 10);
|
RunAtHour_ = std::strtoull(S[0].c_str(), nullptr, 10);
|
||||||
RunAtMin_ = std::strtoull(S[1].c_str(), nullptr, 10);
|
RunAtMin_ = std::strtoull(S[1].c_str(), nullptr, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i=0;i<20;i++) {
|
for (int i = 0; i < 20; i++) {
|
||||||
std::string key = "archiver.db." + std::to_string(i) + ".name";
|
std::string key = "archiver.db." + std::to_string(i) + ".name";
|
||||||
auto DBName = MicroServiceConfigGetString(key,"");
|
auto DBName = MicroServiceConfigGetString(key, "");
|
||||||
if(!DBName.empty()) {
|
if (!DBName.empty()) {
|
||||||
for(auto const &DB:AllInternalDBNames) {
|
for (auto const &DB : AllInternalDBNames) {
|
||||||
if(Poco::icompare(DBName,DB)==0) {
|
if (Poco::icompare(DBName, DB) == 0) {
|
||||||
std::string Key = "archiver.db." + std::to_string(i) + ".keep";
|
std::string Key = "archiver.db." + std::to_string(i) + ".keep";
|
||||||
auto Keep = MicroServiceConfigGetInt(Key,7);
|
auto Keep = MicroServiceConfigGetInt(Key, 7);
|
||||||
Archiver_->AddDb(DB, Keep);
|
Archiver_->AddDb(DB, Keep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int NextRun = CalculateDelta(RunAtHour_,RunAtMin_);
|
int NextRun = CalculateDelta(RunAtHour_, RunAtMin_);
|
||||||
|
|
||||||
poco_information(Logger(),fmt::format("Next run in {} seconds.",NextRun));
|
poco_information(Logger(), fmt::format("Next run in {} seconds.", NextRun));
|
||||||
|
|
||||||
Timer_.setStartInterval( NextRun * 1000);
|
Timer_.setStartInterval(NextRun * 1000);
|
||||||
Timer_.setPeriodicInterval(24 * 60 * 60 * 1000); // 1 hours
|
Timer_.setPeriodicInterval(24 * 60 * 60 * 1000); // 1 hours
|
||||||
Timer_.start(*ArchiverCallback_, MicroServiceTimerPool());
|
Timer_.start(*ArchiverCallback_, MicroServiceTimerPool());
|
||||||
|
|
||||||
@@ -108,11 +105,11 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void StorageArchiver::Stop() {
|
void StorageArchiver::Stop() {
|
||||||
poco_information(Logger(),"Stopping...");
|
poco_information(Logger(), "Stopping...");
|
||||||
if(Enabled_) {
|
if (Enabled_) {
|
||||||
Timer_.stop();
|
Timer_.stop();
|
||||||
}
|
}
|
||||||
poco_information(Logger(),"Stopped...");
|
poco_information(Logger(), "Stopped...");
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
}; // namespace OpenWifi
|
||||||
|
|||||||
@@ -13,26 +13,26 @@
|
|||||||
|
|
||||||
namespace OpenWifi {
|
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 {
|
class Archiver {
|
||||||
public:
|
public:
|
||||||
|
explicit Archiver(Poco::Logger &Logger) : Logger_(Logger) {
|
||||||
explicit Archiver(Poco::Logger &Logger):
|
for (const auto &db : AllInternalDBNames) {
|
||||||
Logger_(Logger) {
|
DBs_[db] = 7;
|
||||||
for(const auto &db:AllInternalDBNames) {
|
|
||||||
DBs_[db] = 7 ;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void onTimer(Poco::Timer & timer);
|
void onTimer(Poco::Timer &timer);
|
||||||
inline void AddDb(const std::string &dbname, std::uint64_t retain) {
|
inline void AddDb(const std::string &dbname, std::uint64_t retain) {
|
||||||
DBs_[dbname] = retain;
|
DBs_[dbname] = retain;
|
||||||
}
|
}
|
||||||
inline Poco::Logger & Logger() { return Logger_; }
|
inline Poco::Logger &Logger() { return Logger_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Poco::Logger &Logger_;
|
Poco::Logger &Logger_;
|
||||||
std::map<std::string,std::uint64_t> DBs_;
|
std::map<std::string, std::uint64_t> DBs_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class StorageArchiver : public SubSystemServer {
|
class StorageArchiver : public SubSystemServer {
|
||||||
@@ -53,12 +53,10 @@ namespace OpenWifi {
|
|||||||
std::unique_ptr<Archiver> Archiver_;
|
std::unique_ptr<Archiver> Archiver_;
|
||||||
std::unique_ptr<Poco::TimerCallback<Archiver>> ArchiverCallback_;
|
std::unique_ptr<Poco::TimerCallback<Archiver>> ArchiverCallback_;
|
||||||
|
|
||||||
StorageArchiver() noexcept:
|
StorageArchiver() noexcept
|
||||||
SubSystemServer("StorageArchiver", "STORAGE-ARCHIVE", "archiver")
|
: SubSystemServer("StorageArchiver", "STORAGE-ARCHIVE", "archiver") {}
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline auto StorageArchiver() { return StorageArchiver::instance(); }
|
inline auto StorageArchiver() { return StorageArchiver::instance(); }
|
||||||
|
|
||||||
} // namespace
|
} // namespace OpenWifi
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ namespace OpenWifi {
|
|||||||
Create_Tables();
|
Create_Tables();
|
||||||
InitializeBlackListCache();
|
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_->Create();
|
||||||
ScriptDB_->Initialize();
|
ScriptDB_->Initialize();
|
||||||
|
|
||||||
@@ -26,9 +27,9 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
void Storage::Stop() {
|
void Storage::Stop() {
|
||||||
std::lock_guard Guard(Mutex_);
|
std::lock_guard Guard(Mutex_);
|
||||||
poco_notice(Logger(),"Stopping...");
|
poco_notice(Logger(), "Stopping...");
|
||||||
StorageClass::Stop();
|
StorageClass::Stop();
|
||||||
poco_notice(Logger(),"Stopped...");
|
poco_notice(Logger(), "Stopped...");
|
||||||
}
|
}
|
||||||
}
|
} // namespace OpenWifi
|
||||||
// namespace
|
// namespace
|
||||||
@@ -8,10 +8,10 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "framework/StorageClass.h"
|
|
||||||
#include "RESTObjects//RESTAPI_GWobjects.h"
|
|
||||||
#include "Poco/Net/IPAddress.h"
|
|
||||||
#include "CentralConfig.h"
|
#include "CentralConfig.h"
|
||||||
|
#include "Poco/Net/IPAddress.h"
|
||||||
|
#include "RESTObjects//RESTAPI_GWobjects.h"
|
||||||
|
#include "framework/StorageClass.h"
|
||||||
#include "storage/storage_scripts.h"
|
#include "storage/storage_scripts.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
@@ -19,7 +19,6 @@ namespace OpenWifi {
|
|||||||
class Storage : public StorageClass {
|
class Storage : public StorageClass {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum class CommandExecutionType {
|
enum class CommandExecutionType {
|
||||||
COMMAND_PENDING,
|
COMMAND_PENDING,
|
||||||
COMMAND_EXECUTED,
|
COMMAND_EXECUTED,
|
||||||
@@ -30,16 +29,22 @@ namespace OpenWifi {
|
|||||||
COMMAND_EXECUTING
|
COMMAND_EXECUTING
|
||||||
};
|
};
|
||||||
|
|
||||||
inline OpenWifi::ScriptDB & ScriptDB() { return *ScriptDB_; }
|
inline OpenWifi::ScriptDB &ScriptDB() { return *ScriptDB_; }
|
||||||
|
|
||||||
inline std::string to_string(const CommandExecutionType &C) {
|
inline std::string to_string(const CommandExecutionType &C) {
|
||||||
switch(C) {
|
switch (C) {
|
||||||
case CommandExecutionType::COMMAND_PENDING: return "pending";
|
case CommandExecutionType::COMMAND_PENDING:
|
||||||
case CommandExecutionType::COMMAND_EXECUTED: return "executed";
|
return "pending";
|
||||||
case CommandExecutionType::COMMAND_COMPLETED: return "completed";
|
case CommandExecutionType::COMMAND_EXECUTED:
|
||||||
case CommandExecutionType::COMMAND_TIMEDOUT: return "timedout";
|
return "executed";
|
||||||
case CommandExecutionType::COMMAND_FAILED: return "failed";
|
case CommandExecutionType::COMMAND_COMPLETED:
|
||||||
case CommandExecutionType::COMMAND_EXPIRED: return "expired";
|
return "completed";
|
||||||
|
case CommandExecutionType::COMMAND_TIMEDOUT:
|
||||||
|
return "timedout";
|
||||||
|
case CommandExecutionType::COMMAND_FAILED:
|
||||||
|
return "failed";
|
||||||
|
case CommandExecutionType::COMMAND_EXPIRED:
|
||||||
|
return "expired";
|
||||||
case CommandExecutionType::COMMAND_EXECUTING:
|
case CommandExecutionType::COMMAND_EXECUTING:
|
||||||
default:
|
default:
|
||||||
return "executing";
|
return "executing";
|
||||||
@@ -47,24 +52,25 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] inline std::string ComputeRange(uint64_t From, uint64_t HowMany) {
|
[[nodiscard]] inline std::string ComputeRange(uint64_t From, uint64_t HowMany) {
|
||||||
if(dbType_==sqlite) {
|
if (dbType_ == sqlite) {
|
||||||
return " LIMIT " + std::to_string(From) + ", " + std::to_string(HowMany) + " ";
|
return " LIMIT " + std::to_string(From) + ", " + std::to_string(HowMany) + " ";
|
||||||
} else if(dbType_==pgsql) {
|
} 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) + " ";
|
} 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) + " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string ConvertParams(const std::string & S) const {
|
inline std::string ConvertParams(const std::string &S) const {
|
||||||
std::string R;
|
std::string R;
|
||||||
R.reserve(S.size()*2+1);
|
R.reserve(S.size() * 2 + 1);
|
||||||
if(dbType_==pgsql) {
|
if (dbType_ == pgsql) {
|
||||||
auto Idx=1;
|
auto Idx = 1;
|
||||||
for(auto const & i:S)
|
for (auto const &i : S) {
|
||||||
{
|
if (i == '?') {
|
||||||
if(i=='?') {
|
|
||||||
R += '$';
|
R += '$';
|
||||||
R.append(std::to_string(Idx++));
|
R.append(std::to_string(Idx++));
|
||||||
} else {
|
} else {
|
||||||
@@ -84,97 +90,129 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
// typedef std::map<std::string,std::string> DeviceCapabilitiesCache;
|
// typedef std::map<std::string,std::string> DeviceCapabilitiesCache;
|
||||||
|
|
||||||
bool AddLog(const GWObjects::DeviceLog & Log);
|
bool AddLog(const GWObjects::DeviceLog &Log);
|
||||||
bool AddStatisticsData(const GWObjects::Statistics & Stats);
|
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 DeleteStatisticsData(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate);
|
||||||
|
bool GetNewestStatisticsData(std::string &SerialNumber, uint64_t HowMany,
|
||||||
std::vector<GWObjects::Statistics> &Stats);
|
std::vector<GWObjects::Statistics> &Stats);
|
||||||
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 AddHealthCheckData(const GWObjects::HealthCheck &Check);
|
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);
|
std::vector<GWObjects::HealthCheck> &Checks);
|
||||||
bool DeleteHealthCheckData(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate );
|
bool DeleteHealthCheckData(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate);
|
||||||
bool GetNewestHealthCheckData(std::string &SerialNumber, uint64_t HowMany,
|
bool GetNewestHealthCheckData(std::string &SerialNumber, uint64_t HowMany,
|
||||||
std::vector<GWObjects::HealthCheck> &Checks);
|
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 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 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, std::vector<GWObjects::Device> &Devices,
|
||||||
// bool GetDevices(uint64_t From, uint64_t HowMany, const std::string & Select, std::vector<GWObjects::Device> &Devices, const std::string & orderBy="");
|
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 DeleteDevice(std::string &SerialNumber);
|
||||||
bool UpdateDevice(GWObjects::Device &);
|
bool UpdateDevice(GWObjects::Device &);
|
||||||
bool DeviceExists(std::string & SerialNumber);
|
bool DeviceExists(std::string &SerialNumber);
|
||||||
bool SetConnectInfo(std::string &SerialNumber, std::string &Firmware);
|
bool SetConnectInfo(std::string &SerialNumber, std::string &Firmware);
|
||||||
bool GetDeviceCount(uint64_t & Count);
|
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,
|
||||||
bool GetDeviceFWUpdatePolicy(std::string & SerialNumber, std::string & Policy);
|
std::vector<std::string> &SerialNumbers,
|
||||||
bool SetDevicePassword(std::string & SerialNumber, std::string & Password);
|
const std::string &orderBy = "");
|
||||||
|
bool GetDeviceFWUpdatePolicy(std::string &SerialNumber, std::string &Policy);
|
||||||
|
bool SetDevicePassword(std::string &SerialNumber, std::string &Password);
|
||||||
bool UpdateSerialNumberCache();
|
bool UpdateSerialNumberCache();
|
||||||
static void GetDeviceDbFieldList( Types::StringVec & Fields);
|
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 GetDeviceCapabilities(std::string &SerialNumber, GWObjects::Capabilities &);
|
||||||
bool DeleteDeviceCapabilities(std::string & SerialNumber);
|
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 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);
|
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,
|
||||||
bool DeleteDefaultConfiguration(std::string & name);
|
GWObjects::DefaultConfiguration &DefConfig);
|
||||||
bool UpdateDefaultConfiguration(std::string & name, GWObjects::DefaultConfiguration & DefConfig);
|
bool DeleteDefaultConfiguration(std::string &name);
|
||||||
bool GetDefaultConfiguration(std::string &name, GWObjects::DefaultConfiguration & DefConfig);
|
bool UpdateDefaultConfiguration(std::string &name,
|
||||||
bool GetDefaultConfigurations(uint64_t From, uint64_t HowMany, std::vector<GWObjects::DefaultConfiguration> &Devices);
|
GWObjects::DefaultConfiguration &DefConfig);
|
||||||
bool FindDefaultConfigurationForModel(const std::string & Model, 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);
|
||||||
uint64_t GetDefaultConfigurationsCount();
|
uint64_t GetDefaultConfigurationsCount();
|
||||||
bool DefaultConfigurationAlreadyExists(std::string &Name);
|
bool DefaultConfigurationAlreadyExists(std::string &Name);
|
||||||
|
|
||||||
bool AddCommand(std::string & SerialNumber, GWObjects::CommandDetails & Command,CommandExecutionType Type);
|
bool AddCommand(std::string &SerialNumber, GWObjects::CommandDetails &Command,
|
||||||
bool GetCommands(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate, uint64_t Offset, uint64_t HowMany, std::vector<GWObjects::CommandDetails> & Commands);
|
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 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,
|
||||||
bool UpdateCommand( std::string &UUID, GWObjects::CommandDetails & Command );
|
std::vector<GWObjects::CommandDetails> &Commands);
|
||||||
bool GetCommand( const std::string &UUID, GWObjects::CommandDetails & Command );
|
bool UpdateCommand(std::string &UUID, GWObjects::CommandDetails &Command);
|
||||||
bool DeleteCommand( std::string &UUID );
|
bool GetCommand(const std::string &UUID, GWObjects::CommandDetails &Command);
|
||||||
bool GetReadyToExecuteCommands( uint64_t Offset, uint64_t HowMany, std::vector<GWObjects::CommandDetails> & Commands );
|
bool DeleteCommand(std::string &UUID);
|
||||||
bool CommandExecuted(std::string & UUID);
|
bool GetReadyToExecuteCommands(uint64_t Offset, uint64_t HowMany,
|
||||||
bool SetCommandLastTry(std::string & UUID);
|
std::vector<GWObjects::CommandDetails> &Commands);
|
||||||
bool CommandCompleted(std::string & UUID, Poco::JSON::Object::Ptr ReturnVars, const std::chrono::duration<double, std::milli> & execution_time, bool FullCommand);
|
bool CommandExecuted(std::string &UUID);
|
||||||
bool AttachFileDataToCommand(std::string & UUID, const std::stringstream &s, const std::string &Type);
|
bool SetCommandLastTry(std::string &UUID);
|
||||||
bool CancelWaitFile( std::string & UUID, std::string & ErrorText );
|
bool CommandCompleted(std::string &UUID, Poco::JSON::Object::Ptr ReturnVars,
|
||||||
bool GetAttachedFileContent(std::string & UUID, const std::string & SerialNumber, std::string & FileContent, std::string &Type);
|
const std::chrono::duration<double, std::milli> &execution_time,
|
||||||
bool RemoveAttachedFile(std::string & UUID);
|
bool FullCommand);
|
||||||
bool SetCommandResult(std::string & UUID, std::string & Result);
|
bool AttachFileDataToCommand(std::string &UUID, const std::stringstream &s,
|
||||||
bool GetNewestCommands(std::string &SerialNumber, uint64_t HowMany, std::vector<GWObjects::CommandDetails> & Commands);
|
const std::string &Type);
|
||||||
bool SetCommandExecuted(std::string & CommandUUID);
|
bool CancelWaitFile(std::string &UUID, std::string &ErrorText);
|
||||||
|
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 SetCommandExecuted(std::string &CommandUUID);
|
||||||
bool SetCommandTimedOut(std::string &CommandUUID);
|
bool SetCommandTimedOut(std::string &CommandUUID);
|
||||||
bool SetCommandStatus(std::string & CommandUUID, std::uint64_t Error, const char *ErrorText);
|
bool SetCommandStatus(std::string &CommandUUID, std::uint64_t Error, const char *ErrorText);
|
||||||
|
|
||||||
void RemovedExpiredCommands();
|
void RemovedExpiredCommands();
|
||||||
void RemoveTimedOutCommands();
|
void RemoveTimedOutCommands();
|
||||||
|
|
||||||
bool RemoveOldCommands(std::string & SerilNumber, std::string & Command);
|
bool RemoveOldCommands(std::string &SerilNumber, std::string &Command);
|
||||||
|
|
||||||
bool AddBlackListDevices(std::vector<GWObjects::BlackListedDevice> & Devices);
|
bool AddBlackListDevices(std::vector<GWObjects::BlackListedDevice> &Devices);
|
||||||
bool AddBlackListDevice(GWObjects::BlackListedDevice & Device);
|
bool AddBlackListDevice(GWObjects::BlackListedDevice &Device);
|
||||||
bool GetBlackListDevice(std::string & SerialNumber, GWObjects::BlackListedDevice & Device);
|
bool GetBlackListDevice(std::string &SerialNumber, GWObjects::BlackListedDevice &Device);
|
||||||
bool DeleteBlackListDevice(std::string & SerialNumber);
|
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 IsBlackListed(const std::string &SerialNumber);
|
||||||
bool InitializeBlackListCache();
|
bool InitializeBlackListCache();
|
||||||
bool GetBlackListDevices(uint64_t Offset, uint64_t HowMany, std::vector<GWObjects::BlackListedDevice> & Devices );
|
bool GetBlackListDevices(uint64_t Offset, uint64_t HowMany,
|
||||||
bool UpdateBlackListDevice(std::string & SerialNumber, GWObjects::BlackListedDevice & Device);
|
std::vector<GWObjects::BlackListedDevice> &Devices);
|
||||||
|
bool UpdateBlackListDevice(std::string &SerialNumber, GWObjects::BlackListedDevice &Device);
|
||||||
uint64_t GetBlackListDeviceCount();
|
uint64_t GetBlackListDeviceCount();
|
||||||
|
|
||||||
bool RemoveHealthChecksRecordsOlderThan(uint64_t Date);
|
bool RemoveHealthChecksRecordsOlderThan(uint64_t Date);
|
||||||
@@ -201,12 +239,9 @@ namespace OpenWifi {
|
|||||||
void Stop() override;
|
void Stop() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::unique_ptr<OpenWifi::ScriptDB> ScriptDB_;
|
std::unique_ptr<OpenWifi::ScriptDB> ScriptDB_;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline auto StorageService() { return Storage::instance(); }
|
inline auto StorageService() { return Storage::instance(); }
|
||||||
|
|
||||||
} // namespace
|
} // namespace OpenWifi
|
||||||
|
|
||||||
|
|||||||
@@ -2,26 +2,20 @@
|
|||||||
// Created by stephane bourque on 2022-02-03.
|
// Created by stephane bourque on 2022-02-03.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "AP_WS_Server.h"
|
|
||||||
#include "TelemetryClient.h"
|
#include "TelemetryClient.h"
|
||||||
#include "TelemetryStream.h"
|
#include "AP_WS_Server.h"
|
||||||
#include "CommandManager.h"
|
#include "CommandManager.h"
|
||||||
|
#include "TelemetryStream.h"
|
||||||
|
|
||||||
#include "Poco/Net/SSLException.h"
|
#include "Poco/Net/SSLException.h"
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
TelemetryClient::TelemetryClient(
|
TelemetryClient::TelemetryClient(std::string UUID, uint64_t SerialNumber,
|
||||||
std::string UUID,
|
|
||||||
uint64_t SerialNumber,
|
|
||||||
std::unique_ptr<Poco::Net::WebSocket> WSock,
|
std::unique_ptr<Poco::Net::WebSocket> WSock,
|
||||||
Poco::Net::SocketReactor& Reactor,
|
Poco::Net::SocketReactor &Reactor, Poco::Logger &Logger)
|
||||||
Poco::Logger &Logger):
|
: UUID_(std::move(UUID)), SerialNumber_(SerialNumber), Reactor_(Reactor), Logger_(Logger),
|
||||||
UUID_(std::move(UUID)),
|
|
||||||
SerialNumber_(SerialNumber),
|
|
||||||
Reactor_(Reactor),
|
|
||||||
Logger_(Logger),
|
|
||||||
WS_(std::move(WSock)) {
|
WS_(std::move(WSock)) {
|
||||||
CompleteStartup();
|
CompleteStartup();
|
||||||
}
|
}
|
||||||
@@ -38,115 +32,126 @@ namespace OpenWifi {
|
|||||||
WS_->setKeepAlive(true);
|
WS_->setKeepAlive(true);
|
||||||
WS_->setMaxPayloadSize(2048);
|
WS_->setMaxPayloadSize(2048);
|
||||||
WS_->setBlocking(false);
|
WS_->setBlocking(false);
|
||||||
Reactor_.addEventHandler(
|
Reactor_.addEventHandler(*WS_,
|
||||||
*WS_, Poco::NObserver<TelemetryClient, Poco::Net::ReadableNotification>(
|
Poco::NObserver<TelemetryClient, Poco::Net::ReadableNotification>(
|
||||||
*this, &TelemetryClient::OnSocketReadable));
|
*this, &TelemetryClient::OnSocketReadable));
|
||||||
Reactor_.addEventHandler(
|
Reactor_.addEventHandler(*WS_,
|
||||||
*WS_, Poco::NObserver<TelemetryClient, Poco::Net::ShutdownNotification>(
|
Poco::NObserver<TelemetryClient, Poco::Net::ShutdownNotification>(
|
||||||
*this, &TelemetryClient::OnSocketShutdown));
|
*this, &TelemetryClient::OnSocketShutdown));
|
||||||
Reactor_.addEventHandler(
|
Reactor_.addEventHandler(*WS_,
|
||||||
*WS_, Poco::NObserver<TelemetryClient, Poco::Net::ErrorNotification>(
|
Poco::NObserver<TelemetryClient, Poco::Net::ErrorNotification>(
|
||||||
*this, &TelemetryClient::OnSocketError));
|
*this, &TelemetryClient::OnSocketError));
|
||||||
Registered_ = true;
|
Registered_ = true;
|
||||||
poco_information(Logger(),fmt::format("TELEMETRY-CONNECTION({}): Connection completed.", CId_));
|
poco_information(Logger(),
|
||||||
|
fmt::format("TELEMETRY-CONNECTION({}): Connection completed.", CId_));
|
||||||
}
|
}
|
||||||
|
|
||||||
TelemetryClient::~TelemetryClient() {
|
TelemetryClient::~TelemetryClient() {
|
||||||
poco_information(Logger(),fmt::format("TELEMETRY-CONNECTION({}): Closing connection.", CId_));
|
poco_information(Logger(),
|
||||||
|
fmt::format("TELEMETRY-CONNECTION({}): Closing connection.", CId_));
|
||||||
DeRegister();
|
DeRegister();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TelemetryClient::DeRegister() {
|
void TelemetryClient::DeRegister() {
|
||||||
if(Registered_) {
|
if (Registered_) {
|
||||||
Registered_ = false;
|
Registered_ = false;
|
||||||
Reactor_.removeEventHandler(*WS_,
|
Reactor_.removeEventHandler(
|
||||||
Poco::NObserver<TelemetryClient,
|
*WS_, Poco::NObserver<TelemetryClient, Poco::Net::ReadableNotification>(
|
||||||
Poco::Net::ReadableNotification>(*this,&TelemetryClient::OnSocketReadable));
|
*this, &TelemetryClient::OnSocketReadable));
|
||||||
Reactor_.removeEventHandler(*WS_,
|
Reactor_.removeEventHandler(
|
||||||
Poco::NObserver<TelemetryClient,
|
*WS_, Poco::NObserver<TelemetryClient, Poco::Net::ShutdownNotification>(
|
||||||
Poco::Net::ShutdownNotification>(*this,&TelemetryClient::OnSocketShutdown));
|
*this, &TelemetryClient::OnSocketShutdown));
|
||||||
Reactor_.removeEventHandler(*WS_,
|
Reactor_.removeEventHandler(
|
||||||
Poco::NObserver<TelemetryClient,
|
*WS_, Poco::NObserver<TelemetryClient, Poco::Net::ErrorNotification>(
|
||||||
Poco::Net::ErrorNotification>(*this,&TelemetryClient::OnSocketError));
|
*this, &TelemetryClient::OnSocketError));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TelemetryClient::Send(const std::string &Payload) {
|
bool TelemetryClient::Send(const std::string &Payload) {
|
||||||
std::lock_guard Guard(Mutex_);
|
std::lock_guard Guard(Mutex_);
|
||||||
size_t BytesSent = WS_->sendFrame(Payload.c_str(),(int)Payload.size());
|
size_t BytesSent = WS_->sendFrame(Payload.c_str(), (int)Payload.size());
|
||||||
return BytesSent == Payload.size();
|
return BytesSent == Payload.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TelemetryClient::SendTelemetryShutdown() {
|
void TelemetryClient::SendTelemetryShutdown() {
|
||||||
poco_information(Logger(),fmt::format("TELEMETRY-SHUTDOWN({}): Closing.",CId_));
|
poco_information(Logger(), fmt::format("TELEMETRY-SHUTDOWN({}): Closing.", CId_));
|
||||||
DeRegister();
|
DeRegister();
|
||||||
AP_WS_Server()->StopWebSocketTelemetry(CommandManager()->Next_RPC_ID(), SerialNumber_);
|
AP_WS_Server()->StopWebSocketTelemetry(CommandManager()->Next_RPC_ID(), SerialNumber_);
|
||||||
TelemetryStream()->DeRegisterClient(UUID_);
|
TelemetryStream()->DeRegisterClient(UUID_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TelemetryClient::OnSocketShutdown([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification>& pNf) {
|
void TelemetryClient::OnSocketShutdown(
|
||||||
poco_information(Logger(),fmt::format("TELEMETRY-SOCKET-SHUTDOWN({}): Orderly shutdown.", CId_));
|
[[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf) {
|
||||||
|
poco_information(Logger(),
|
||||||
|
fmt::format("TELEMETRY-SOCKET-SHUTDOWN({}): Orderly shutdown.", CId_));
|
||||||
SendTelemetryShutdown();
|
SendTelemetryShutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TelemetryClient::OnSocketError([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ErrorNotification>& pNf) {
|
void TelemetryClient::OnSocketError(
|
||||||
poco_information(Logger(),fmt::format("TELEMETRY-SOCKET-ERROR({}): Closing.",CId_));
|
[[maybe_unused]] const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf) {
|
||||||
|
poco_information(Logger(), fmt::format("TELEMETRY-SOCKET-ERROR({}): Closing.", CId_));
|
||||||
SendTelemetryShutdown();
|
SendTelemetryShutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TelemetryClient::OnSocketReadable([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf) {
|
void TelemetryClient::OnSocketReadable(
|
||||||
try
|
[[maybe_unused]] const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) {
|
||||||
{
|
try {
|
||||||
std::lock_guard Guard(Mutex_);
|
std::lock_guard Guard(Mutex_);
|
||||||
return ProcessIncomingFrame();
|
return ProcessIncomingFrame();
|
||||||
}
|
} catch (const Poco::Exception &E) {
|
||||||
catch (const Poco::Exception & E)
|
|
||||||
{
|
|
||||||
Logger().log(E);
|
Logger().log(E);
|
||||||
}
|
} catch (const std::exception &E) {
|
||||||
catch (const std::exception & E) {
|
|
||||||
std::string W = E.what();
|
std::string W = E.what();
|
||||||
poco_information(Logger(),fmt::format("TELEMETRY-std::exception caught: {}. Connection terminated with {}",W,CId_));
|
poco_information(
|
||||||
}
|
Logger(),
|
||||||
catch ( ... ) {
|
fmt::format("TELEMETRY-std::exception caught: {}. Connection terminated with {}", W,
|
||||||
poco_information(Logger(),fmt::format("TELEMETRY-Unknown exception for {}. Connection terminated.",CId_));
|
CId_));
|
||||||
|
} catch (...) {
|
||||||
|
poco_information(
|
||||||
|
Logger(),
|
||||||
|
fmt::format("TELEMETRY-Unknown exception for {}. Connection terminated.", CId_));
|
||||||
}
|
}
|
||||||
SendTelemetryShutdown();
|
SendTelemetryShutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TelemetryClient::ProcessIncomingFrame() {
|
void TelemetryClient::ProcessIncomingFrame() {
|
||||||
|
|
||||||
bool MustDisconnect=false;
|
bool MustDisconnect = false;
|
||||||
Poco::Buffer<char> IncomingFrame(0);
|
Poco::Buffer<char> IncomingFrame(0);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
int Op,flags;
|
int Op, flags;
|
||||||
int IncomingSize;
|
int IncomingSize;
|
||||||
IncomingSize = WS_->receiveFrame(IncomingFrame,flags);
|
IncomingSize = WS_->receiveFrame(IncomingFrame, flags);
|
||||||
Op = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK;
|
Op = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK;
|
||||||
|
|
||||||
if (IncomingSize == 0 && flags == 0 && Op == 0) {
|
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;
|
MustDisconnect = true;
|
||||||
} else {
|
} else {
|
||||||
if (Op == Poco::Net::WebSocket::FRAME_OP_PING) {
|
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,
|
WS_->sendFrame("", 0,
|
||||||
(int)Poco::Net::WebSocket::FRAME_OP_PONG |
|
(int)Poco::Net::WebSocket::FRAME_OP_PONG |
|
||||||
(int)Poco::Net::WebSocket::FRAME_FLAG_FIN);
|
(int)Poco::Net::WebSocket::FRAME_FLAG_FIN);
|
||||||
} else if (Op == Poco::Net::WebSocket::FRAME_OP_CLOSE) {
|
} else if (Op == Poco::Net::WebSocket::FRAME_OP_CLOSE) {
|
||||||
poco_information(Logger(),fmt::format("TELEMETRY-DISCONNECT({}): device wants to disconnect.", CId_));
|
poco_information(
|
||||||
MustDisconnect = true ;
|
Logger(),
|
||||||
|
fmt::format("TELEMETRY-DISCONNECT({}): device wants to disconnect.", CId_));
|
||||||
|
MustDisconnect = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
MustDisconnect = true ;
|
MustDisconnect = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!MustDisconnect)
|
if (!MustDisconnect)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SendTelemetryShutdown();
|
SendTelemetryShutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace OpenWifi
|
||||||
@@ -4,33 +4,31 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "Poco/AutoPtr.h"
|
#include "Poco/AutoPtr.h"
|
||||||
|
#include "Poco/Logger.h"
|
||||||
|
#include "Poco/Net/SocketNotification.h"
|
||||||
#include "Poco/Net/SocketReactor.h"
|
#include "Poco/Net/SocketReactor.h"
|
||||||
#include "Poco/Net/WebSocket.h"
|
#include "Poco/Net/WebSocket.h"
|
||||||
#include "Poco/Net/SocketNotification.h"
|
|
||||||
#include "Poco/Logger.h"
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
class TelemetryClient {
|
class TelemetryClient {
|
||||||
static constexpr int BufSize = 64000;
|
static constexpr int BufSize = 64000;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TelemetryClient(
|
TelemetryClient(std::string UUID, uint64_t SerialNumber,
|
||||||
std::string UUID,
|
|
||||||
uint64_t SerialNumber,
|
|
||||||
std::unique_ptr<Poco::Net::WebSocket> WSock,
|
std::unique_ptr<Poco::Net::WebSocket> WSock,
|
||||||
Poco::Net::SocketReactor& Reactor,
|
Poco::Net::SocketReactor &Reactor, Poco::Logger &Logger);
|
||||||
Poco::Logger &Logger);
|
|
||||||
~TelemetryClient();
|
~TelemetryClient();
|
||||||
|
|
||||||
void OnSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf);
|
void OnSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf);
|
||||||
void OnSocketShutdown(const Poco::AutoPtr<Poco::Net::ShutdownNotification>& pNf);
|
void OnSocketShutdown(const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf);
|
||||||
void OnSocketError(const Poco::AutoPtr<Poco::Net::ErrorNotification>& pNf);
|
void OnSocketError(const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf);
|
||||||
bool Send(const std::string &Payload);
|
bool Send(const std::string &Payload);
|
||||||
void ProcessIncomingFrame();
|
void ProcessIncomingFrame();
|
||||||
inline Poco::Logger & Logger() { return Logger_; }
|
inline Poco::Logger &Logger() { return Logger_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::recursive_mutex Mutex_;
|
std::recursive_mutex Mutex_;
|
||||||
@@ -41,9 +39,9 @@ namespace OpenWifi {
|
|||||||
Poco::Net::StreamSocket Socket_;
|
Poco::Net::StreamSocket Socket_;
|
||||||
std::string CId_;
|
std::string CId_;
|
||||||
std::unique_ptr<Poco::Net::WebSocket> WS_;
|
std::unique_ptr<Poco::Net::WebSocket> WS_;
|
||||||
bool Registered_=false;
|
bool Registered_ = false;
|
||||||
void SendTelemetryShutdown();
|
void SendTelemetryShutdown();
|
||||||
void CompleteStartup();
|
void CompleteStartup();
|
||||||
void DeRegister();
|
void DeRegister();
|
||||||
};
|
};
|
||||||
}
|
} // namespace OpenWifi
|
||||||
@@ -17,40 +17,41 @@ namespace OpenWifi {
|
|||||||
int TelemetryStream::Start() {
|
int TelemetryStream::Start() {
|
||||||
Running_ = true;
|
Running_ = true;
|
||||||
ReactorThr_.start(Reactor_);
|
ReactorThr_.start(Reactor_);
|
||||||
Utils::SetThreadName(ReactorThr_,"tel:reactor");
|
Utils::SetThreadName(ReactorThr_, "tel:reactor");
|
||||||
NotificationMgr_.start(*this);
|
NotificationMgr_.start(*this);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TelemetryStream::Stop() {
|
void TelemetryStream::Stop() {
|
||||||
poco_information(Logger(),"Stopping...");
|
poco_information(Logger(), "Stopping...");
|
||||||
Running_ = false;
|
Running_ = false;
|
||||||
Reactor_.stop();
|
Reactor_.stop();
|
||||||
ReactorThr_.join();
|
ReactorThr_.join();
|
||||||
MsgQueue_.wakeUpAll();
|
MsgQueue_.wakeUpAll();
|
||||||
NotificationMgr_.wakeUp();
|
NotificationMgr_.wakeUp();
|
||||||
NotificationMgr_.join();
|
NotificationMgr_.join();
|
||||||
poco_information(Logger(),"Stopped...");
|
poco_information(Logger(), "Stopped...");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TelemetryStream::IsValidEndPoint(uint64_t SerialNumber, const std::string & UUID) {
|
bool TelemetryStream::IsValidEndPoint(uint64_t SerialNumber, const std::string &UUID) {
|
||||||
std::lock_guard G(Mutex_);
|
std::lock_guard G(Mutex_);
|
||||||
|
|
||||||
auto U = Clients_.find(UUID);
|
auto U = Clients_.find(UUID);
|
||||||
if(U == Clients_.end() )
|
if (U == Clients_.end())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto N = SerialNumbers_.find(SerialNumber);
|
auto N = SerialNumbers_.find(SerialNumber);
|
||||||
if(N == SerialNumbers_.end())
|
if (N == SerialNumbers_.end())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return (N->second.find(UUID) != N->second.end());
|
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_);
|
std::lock_guard G(Mutex_);
|
||||||
|
|
||||||
Poco::URI Public(MicroServiceConfigGetString("openwifi.system.uri.public",""));
|
Poco::URI Public(MicroServiceConfigGetString("openwifi.system.uri.public", ""));
|
||||||
Poco::URI U;
|
Poco::URI U;
|
||||||
U.setScheme("wss");
|
U.setScheme("wss");
|
||||||
U.setHost(Public.getHost());
|
U.setHost(Public.getHost());
|
||||||
@@ -74,8 +75,8 @@ namespace OpenWifi {
|
|||||||
auto Notification = dynamic_cast<TelemetryNotification *>(NextNotification.get());
|
auto Notification = dynamic_cast<TelemetryNotification *>(NextNotification.get());
|
||||||
if (Notification != nullptr) {
|
if (Notification != nullptr) {
|
||||||
std::lock_guard Lock(Mutex_);
|
std::lock_guard Lock(Mutex_);
|
||||||
switch( Notification->Type_ ) {
|
switch (Notification->Type_) {
|
||||||
case TelemetryNotification::NotificationType::data : {
|
case TelemetryNotification::NotificationType::data: {
|
||||||
auto SerialNumberSetOfUUIDs = SerialNumbers_.find(Notification->SerialNumber_);
|
auto SerialNumberSetOfUUIDs = SerialNumbers_.find(Notification->SerialNumber_);
|
||||||
if (SerialNumberSetOfUUIDs != SerialNumbers_.end()) {
|
if (SerialNumberSetOfUUIDs != SerialNumbers_.end()) {
|
||||||
for (auto &uuid : SerialNumberSetOfUUIDs->second) {
|
for (auto &uuid : SerialNumberSetOfUUIDs->second) {
|
||||||
@@ -87,24 +88,36 @@ namespace OpenWifi {
|
|||||||
} catch (const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
Logger().log(E);
|
Logger().log(E);
|
||||||
} catch (std::exception &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 {
|
} 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 {
|
} 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;
|
} break;
|
||||||
case TelemetryNotification::NotificationType::unregister : {
|
case TelemetryNotification::NotificationType::unregister: {
|
||||||
std::lock_guard G(Mutex_);
|
std::lock_guard G(Mutex_);
|
||||||
|
|
||||||
auto client = Clients_.find(Notification->Data_);
|
auto client = Clients_.find(Notification->Data_);
|
||||||
if(client!=Clients_.end()) {
|
if (client != Clients_.end()) {
|
||||||
for(auto i = SerialNumbers_.begin(); i!= SerialNumbers_.end();) {
|
for (auto i = SerialNumbers_.begin(); i != SerialNumbers_.end();) {
|
||||||
i->second.erase(Notification->Data_);
|
i->second.erase(Notification->Data_);
|
||||||
if(i->second.empty()) {
|
if (i->second.empty()) {
|
||||||
i = SerialNumbers_.erase(i);
|
i = SerialNumbers_.erase(i);
|
||||||
} else {
|
} else {
|
||||||
++i;
|
++i;
|
||||||
@@ -112,7 +125,8 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
Clients_.erase(client);
|
Clients_.erase(client);
|
||||||
} else {
|
} else {
|
||||||
poco_warning(Logger(),fmt::format("Unknown connection: {}", Notification->Data_));
|
poco_warning(Logger(),
|
||||||
|
fmt::format("Unknown connection: {}", Notification->Data_));
|
||||||
}
|
}
|
||||||
} break;
|
} 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_);
|
std::lock_guard G(Mutex_);
|
||||||
try {
|
try {
|
||||||
Clients_[UUID] = std::make_unique<TelemetryClient>(
|
Clients_[UUID] = std::make_unique<TelemetryClient>(
|
||||||
@@ -137,8 +152,12 @@ namespace OpenWifi {
|
|||||||
} catch (const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
Logger().log(E);
|
Logger().log(E);
|
||||||
} catch (...) {
|
} 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;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} // namespace OpenWifi
|
||||||
|
|||||||
@@ -6,20 +6,20 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#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/HTTPRequestHandler.h"
|
||||||
|
#include "Poco/Net/HTTPRequestHandlerFactory.h"
|
||||||
|
#include "Poco/Net/HTTPServer.h"
|
||||||
#include "Poco/Net/HTTPServerRequest.h"
|
#include "Poco/Net/HTTPServerRequest.h"
|
||||||
#include "Poco/Net/HTTPServerRequestImpl.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/Timespan.h"
|
||||||
#include "Poco/URI.h"
|
#include "Poco/URI.h"
|
||||||
#include "Poco/Net/HTTPServer.h"
|
|
||||||
#include "Poco/NotificationQueue.h"
|
|
||||||
#include "Poco/Notification.h"
|
|
||||||
|
|
||||||
#include "framework/SubSystemServer.h"
|
#include "framework/SubSystemServer.h"
|
||||||
|
|
||||||
@@ -30,30 +30,21 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
class TelemetryNotification : public Poco::Notification {
|
class TelemetryNotification : public Poco::Notification {
|
||||||
public:
|
public:
|
||||||
enum class NotificationType {
|
enum class NotificationType { data, unregister };
|
||||||
data,
|
|
||||||
unregister
|
|
||||||
};
|
|
||||||
|
|
||||||
explicit TelemetryNotification(std::uint64_t SerialNumber, const std::string &Payload) :
|
explicit TelemetryNotification(std::uint64_t SerialNumber, const std::string &Payload)
|
||||||
Type_(NotificationType::data),
|
: Type_(NotificationType::data), SerialNumber_(SerialNumber), Data_(Payload) {}
|
||||||
SerialNumber_(SerialNumber),
|
|
||||||
Data_(Payload) {
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit TelemetryNotification(const std::string &UUID) :
|
explicit TelemetryNotification(const std::string &UUID)
|
||||||
Type_(NotificationType::unregister),
|
: Type_(NotificationType::unregister), Data_(UUID) {}
|
||||||
Data_(UUID) {
|
|
||||||
}
|
|
||||||
|
|
||||||
NotificationType Type_;
|
NotificationType Type_;
|
||||||
std::uint64_t SerialNumber_=0;
|
std::uint64_t SerialNumber_ = 0;
|
||||||
std::string Data_;
|
std::string Data_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TelemetryStream : public SubSystemServer, Poco::Runnable {
|
class TelemetryStream : public SubSystemServer, Poco::Runnable {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
struct QueueUpdate {
|
struct QueueUpdate {
|
||||||
uint64_t SerialNumber;
|
uint64_t SerialNumber;
|
||||||
std::string Payload;
|
std::string Payload;
|
||||||
@@ -68,37 +59,36 @@ namespace OpenWifi {
|
|||||||
void Stop() override;
|
void Stop() override;
|
||||||
void run() final;
|
void run() final;
|
||||||
|
|
||||||
bool IsValidEndPoint(uint64_t SerialNumber, const std::string & UUID);
|
bool IsValidEndPoint(uint64_t SerialNumber, const std::string &UUID);
|
||||||
bool CreateEndpoint(uint64_t SerialNumber, std::string &EndPoint, const std::string &UUID);
|
bool CreateEndpoint(uint64_t SerialNumber, std::string &EndPoint, const std::string &UUID);
|
||||||
|
|
||||||
inline void NotifyEndPoint(uint64_t SerialNumber, const std::string &PayLoad) {
|
inline void NotifyEndPoint(uint64_t SerialNumber, const std::string &PayLoad) {
|
||||||
MsgQueue_.enqueueNotification(new TelemetryNotification(SerialNumber,PayLoad));
|
MsgQueue_.enqueueNotification(new TelemetryNotification(SerialNumber, PayLoad));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void DeRegisterClient(const std::string &UUID) {
|
inline void DeRegisterClient(const std::string &UUID) {
|
||||||
MsgQueue_.enqueueNotification(new TelemetryNotification(UUID));
|
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_; }
|
||||||
Poco::Net::SocketReactor & NextReactor() { return Reactor_; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
volatile std::atomic_bool Running_=false;
|
volatile std::atomic_bool Running_ = false;
|
||||||
std::map<uint64_t, std::set<std::string>> SerialNumbers_; // serialNumber -> uuid
|
std::map<uint64_t, std::set<std::string>> SerialNumbers_; // serialNumber -> uuid
|
||||||
Poco::Net::SocketReactor Reactor_;
|
Poco::Net::SocketReactor Reactor_;
|
||||||
Poco::Thread ReactorThr_;
|
Poco::Thread ReactorThr_;
|
||||||
Poco::Thread NotificationMgr_;
|
Poco::Thread NotificationMgr_;
|
||||||
Poco::NotificationQueue MsgQueue_;
|
Poco::NotificationQueue MsgQueue_;
|
||||||
|
|
||||||
std::map<std::string, std::unique_ptr<TelemetryClient> > Clients_; // uuid -> client
|
std::map<std::string, std::unique_ptr<TelemetryClient>> Clients_; // uuid -> client
|
||||||
|
|
||||||
TelemetryStream() noexcept:
|
TelemetryStream() noexcept
|
||||||
SubSystemServer("TelemetryServer", "TELEMETRY-SVR", "openwifi.telemetry") {
|
: SubSystemServer("TelemetryServer", "TELEMETRY-SVR", "openwifi.telemetry") {}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline auto TelemetryStream() { return TelemetryStream::instance(); }
|
inline auto TelemetryStream() { return TelemetryStream::instance(); }
|
||||||
|
|
||||||
}
|
} // namespace OpenWifi
|
||||||
|
|||||||
@@ -7,154 +7,147 @@
|
|||||||
namespace OpenWifi::GWWebSocketNotifications {
|
namespace OpenWifi::GWWebSocketNotifications {
|
||||||
|
|
||||||
inline void SingleDevice::to_json(Poco::JSON::Object &Obj) const {
|
inline void SingleDevice::to_json(Poco::JSON::Object &Obj) const {
|
||||||
RESTAPI_utils::field_to_json(Obj,"serialNumber", serialNumber);
|
RESTAPI_utils::field_to_json(Obj, "serialNumber", serialNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool SingleDevice::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
inline bool SingleDevice::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
try {
|
try {
|
||||||
RESTAPI_utils::field_from_json(Obj,"serialNumber", serialNumber);
|
RESTAPI_utils::field_from_json(Obj, "serialNumber", serialNumber);
|
||||||
return true;
|
return true;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void SingleDeviceConfigurationChange::to_json(Poco::JSON::Object &Obj) const {
|
inline void SingleDeviceConfigurationChange::to_json(Poco::JSON::Object &Obj) const {
|
||||||
RESTAPI_utils::field_to_json(Obj,"serialNumber", serialNumber);
|
RESTAPI_utils::field_to_json(Obj, "serialNumber", serialNumber);
|
||||||
RESTAPI_utils::field_to_json(Obj,"oldUUID", oldUUID);
|
RESTAPI_utils::field_to_json(Obj, "oldUUID", oldUUID);
|
||||||
RESTAPI_utils::field_to_json(Obj,"newUUID", newUUID);
|
RESTAPI_utils::field_to_json(Obj, "newUUID", newUUID);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool SingleDeviceConfigurationChange::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
inline bool SingleDeviceConfigurationChange::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
try {
|
try {
|
||||||
RESTAPI_utils::field_from_json(Obj,"serialNumber", serialNumber);
|
RESTAPI_utils::field_from_json(Obj, "serialNumber", serialNumber);
|
||||||
RESTAPI_utils::field_from_json(Obj,"oldUUID", oldUUID);
|
RESTAPI_utils::field_from_json(Obj, "oldUUID", oldUUID);
|
||||||
RESTAPI_utils::field_from_json(Obj,"newUUID", newUUID);
|
RESTAPI_utils::field_from_json(Obj, "newUUID", newUUID);
|
||||||
return true;
|
return true;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void SingleDeviceFirmwareChange::to_json(Poco::JSON::Object &Obj) const {
|
inline void SingleDeviceFirmwareChange::to_json(Poco::JSON::Object &Obj) const {
|
||||||
RESTAPI_utils::field_to_json(Obj,"serialNumber", serialNumber);
|
RESTAPI_utils::field_to_json(Obj, "serialNumber", serialNumber);
|
||||||
RESTAPI_utils::field_to_json(Obj,"newFirmware", newFirmware);
|
RESTAPI_utils::field_to_json(Obj, "newFirmware", newFirmware);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool SingleDeviceFirmwareChange::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
inline bool SingleDeviceFirmwareChange::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
try {
|
try {
|
||||||
RESTAPI_utils::field_from_json(Obj,"serialNumber", serialNumber);
|
RESTAPI_utils::field_from_json(Obj, "serialNumber", serialNumber);
|
||||||
RESTAPI_utils::field_from_json(Obj,"newFirmware", newFirmware);
|
RESTAPI_utils::field_from_json(Obj, "newFirmware", newFirmware);
|
||||||
return true;
|
return true;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void NumberOfConnection::to_json(Poco::JSON::Object &Obj) const {
|
inline void NumberOfConnection::to_json(Poco::JSON::Object &Obj) const {
|
||||||
RESTAPI_utils::field_to_json(Obj,"numberOfDevices", numberOfDevices);
|
RESTAPI_utils::field_to_json(Obj, "numberOfDevices", numberOfDevices);
|
||||||
RESTAPI_utils::field_to_json(Obj,"averageConnectedTime", averageConnectedTime);
|
RESTAPI_utils::field_to_json(Obj, "averageConnectedTime", averageConnectedTime);
|
||||||
RESTAPI_utils::field_to_json(Obj,"numberOfConnectingDevices", numberOfConnectingDevices);
|
RESTAPI_utils::field_to_json(Obj, "numberOfConnectingDevices", numberOfConnectingDevices);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool NumberOfConnection::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
inline bool NumberOfConnection::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
try {
|
try {
|
||||||
RESTAPI_utils::field_from_json(Obj,"numberOfDevices", numberOfDevices);
|
RESTAPI_utils::field_from_json(Obj, "numberOfDevices", numberOfDevices);
|
||||||
RESTAPI_utils::field_from_json(Obj,"averageConnectedTime", averageConnectedTime);
|
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;
|
return true;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NumberOfConnections(NumberOfConnection_t &N) {
|
void NumberOfConnections(NumberOfConnection_t &N) {
|
||||||
// N.type = "device_connections_statistics";
|
// N.type = "device_connections_statistics";
|
||||||
N.type_id = 1000 ;
|
N.type_id = 1000;
|
||||||
UI_WebSocketClientServer()->SendNotification(N);
|
UI_WebSocketClientServer()->SendNotification(N);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NumberOfConnections(const std::string & User, NumberOfConnection_t &N) {
|
void NumberOfConnections(const std::string &User, NumberOfConnection_t &N) {
|
||||||
// N.type = "device_connections_statistics";
|
// N.type = "device_connections_statistics";
|
||||||
N.type_id = 1000 ;
|
N.type_id = 1000;
|
||||||
UI_WebSocketClientServer()->SendUserNotification(User,N);
|
UI_WebSocketClientServer()->SendUserNotification(User, N);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceConfigurationChange(SingleDeviceConfigurationChange_t &N) {
|
void DeviceConfigurationChange(SingleDeviceConfigurationChange_t &N) {
|
||||||
// N.type = "device_configuration_upgrade";
|
// N.type = "device_configuration_upgrade";
|
||||||
N.type_id = 2000 ;
|
N.type_id = 2000;
|
||||||
UI_WebSocketClientServer()->SendNotification(N);
|
UI_WebSocketClientServer()->SendNotification(N);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceConfigurationChange(const std::string & User, SingleDeviceConfigurationChange_t &N) {
|
void DeviceConfigurationChange(const std::string &User, SingleDeviceConfigurationChange_t &N) {
|
||||||
// N.type = "device_configuration_upgrade";
|
// N.type = "device_configuration_upgrade";
|
||||||
N.type_id = 2000 ;
|
N.type_id = 2000;
|
||||||
UI_WebSocketClientServer()->SendUserNotification(User,N);
|
UI_WebSocketClientServer()->SendUserNotification(User, N);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceFirmwareUpdated(SingleDeviceFirmwareChange_t &N) {
|
void DeviceFirmwareUpdated(SingleDeviceFirmwareChange_t &N) {
|
||||||
// N.type = "device_firmware_upgrade";
|
// N.type = "device_firmware_upgrade";
|
||||||
N.type_id = 3000 ;
|
N.type_id = 3000;
|
||||||
UI_WebSocketClientServer()->SendNotification(N);
|
UI_WebSocketClientServer()->SendNotification(N);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceFirmwareUpdated(const std::string & User, SingleDeviceFirmwareChange_t &N){
|
void DeviceFirmwareUpdated(const std::string &User, SingleDeviceFirmwareChange_t &N) {
|
||||||
// N.type = "device_firmware_upgrade";
|
// N.type = "device_firmware_upgrade";
|
||||||
N.type_id = 3000 ;
|
N.type_id = 3000;
|
||||||
UI_WebSocketClientServer()->SendUserNotification(User,N);
|
UI_WebSocketClientServer()->SendUserNotification(User, N);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceConnected(SingleDevice_t &N){
|
void DeviceConnected(SingleDevice_t &N) {
|
||||||
// N.type = "device_connection";
|
// N.type = "device_connection";
|
||||||
N.type_id = 4000 ;
|
N.type_id = 4000;
|
||||||
UI_WebSocketClientServer()->SendNotification(N);
|
UI_WebSocketClientServer()->SendNotification(N);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceConnected(const std::string & User, SingleDevice_t &N){
|
void DeviceConnected(const std::string &User, SingleDevice_t &N) {
|
||||||
// N.type = "device_connection";
|
// N.type = "device_connection";
|
||||||
N.type_id = 4000 ;
|
N.type_id = 4000;
|
||||||
UI_WebSocketClientServer()->SendUserNotification(User,N);
|
UI_WebSocketClientServer()->SendUserNotification(User, N);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceDisconnected(const std::string & User, SingleDevice_t &N){
|
void DeviceDisconnected(const std::string &User, SingleDevice_t &N) {
|
||||||
// N.type = "device_disconnection";
|
// N.type = "device_disconnection";
|
||||||
N.type_id = 5000 ;
|
N.type_id = 5000;
|
||||||
UI_WebSocketClientServer()->SendUserNotification(User,N);
|
UI_WebSocketClientServer()->SendUserNotification(User, N);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceDisconnected(SingleDevice_t &N){
|
void DeviceDisconnected(SingleDevice_t &N) {
|
||||||
// N.type = "device_disconnection";
|
// N.type = "device_disconnection";
|
||||||
N.type_id = 5000 ;
|
N.type_id = 5000;
|
||||||
UI_WebSocketClientServer()->SendNotification(N);
|
UI_WebSocketClientServer()->SendNotification(N);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceStatistics(const std::string & User, SingleDevice_t &N){
|
void DeviceStatistics(const std::string &User, SingleDevice_t &N) {
|
||||||
// N.type = "device_statistics";
|
// N.type = "device_statistics";
|
||||||
N.type_id = 6000 ;
|
N.type_id = 6000;
|
||||||
UI_WebSocketClientServer()->SendUserNotification(User,N);
|
UI_WebSocketClientServer()->SendUserNotification(User, N);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceStatistics(SingleDevice_t &N){
|
void DeviceStatistics(SingleDevice_t &N) {
|
||||||
// N.type = "device_statistics";
|
// N.type = "device_statistics";
|
||||||
N.type_id = 6000 ;
|
N.type_id = 6000;
|
||||||
UI_WebSocketClientServer()->SendNotification(N);
|
UI_WebSocketClientServer()->SendNotification(N);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Register() {
|
void Register() {
|
||||||
static const UI_WebSocketClientServer::NotificationTypeIdVec Notifications = {
|
static const UI_WebSocketClientServer::NotificationTypeIdVec Notifications = {
|
||||||
{ 1000, "device_connections_statistics" },
|
{1000, "device_connections_statistics"}, {2000, "device_configuration_upgrade"},
|
||||||
{ 2000, "device_configuration_upgrade" },
|
{3000, "device_firmware_upgrade"}, {4000, "device_connection"},
|
||||||
{ 3000, "device_firmware_upgrade" },
|
{5000, "device_disconnection"}, {6000, "device_statistics"}};
|
||||||
{ 4000, "device_connection" },
|
|
||||||
{ 5000, "device_disconnection" },
|
|
||||||
{ 6000, "device_statistics" }
|
|
||||||
};
|
|
||||||
|
|
||||||
UI_WebSocketClientServer()->RegisterNotifications(Notifications);
|
UI_WebSocketClientServer()->RegisterNotifications(Notifications);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace OpenWifi::GWWebSocketNotifications
|
||||||
@@ -11,7 +11,7 @@ namespace OpenWifi::GWWebSocketNotifications {
|
|||||||
|
|
||||||
struct SingleDevice {
|
struct SingleDevice {
|
||||||
std::string serialNumber;
|
std::string serialNumber;
|
||||||
inline void to_json(Poco::JSON::Object &Obj) const ;
|
inline void to_json(Poco::JSON::Object &Obj) const;
|
||||||
inline bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
inline bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -20,30 +20,31 @@ namespace OpenWifi::GWWebSocketNotifications {
|
|||||||
uint64_t oldUUID;
|
uint64_t oldUUID;
|
||||||
uint64_t newUUID;
|
uint64_t newUUID;
|
||||||
|
|
||||||
inline void to_json(Poco::JSON::Object &Obj) const ;
|
inline void to_json(Poco::JSON::Object &Obj) const;
|
||||||
inline bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
inline bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SingleDeviceFirmwareChange {
|
struct SingleDeviceFirmwareChange {
|
||||||
std::string serialNumber;
|
std::string serialNumber;
|
||||||
std::string newFirmware;
|
std::string newFirmware;
|
||||||
inline void to_json(Poco::JSON::Object &Obj) const ;
|
inline void to_json(Poco::JSON::Object &Obj) const;
|
||||||
inline bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
inline bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NumberOfConnection {
|
struct NumberOfConnection {
|
||||||
std::uint64_t numberOfDevices=0;
|
std::uint64_t numberOfDevices = 0;
|
||||||
std::uint64_t averageConnectedTime=0;
|
std::uint64_t averageConnectedTime = 0;
|
||||||
std::uint64_t numberOfConnectingDevices=0;
|
std::uint64_t numberOfConnectingDevices = 0;
|
||||||
|
|
||||||
inline void to_json(Poco::JSON::Object &Obj) const ;
|
inline void to_json(Poco::JSON::Object &Obj) const;
|
||||||
inline bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
inline bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
void Register();
|
void Register();
|
||||||
|
|
||||||
typedef WebSocketNotification<SingleDevice> SingleDevice_t;
|
typedef WebSocketNotification<SingleDevice> SingleDevice_t;
|
||||||
typedef WebSocketNotification<SingleDeviceConfigurationChange> SingleDeviceConfigurationChange_t;
|
typedef WebSocketNotification<SingleDeviceConfigurationChange>
|
||||||
|
SingleDeviceConfigurationChange_t;
|
||||||
typedef WebSocketNotification<SingleDeviceFirmwareChange> SingleDeviceFirmwareChange_t;
|
typedef WebSocketNotification<SingleDeviceFirmwareChange> SingleDeviceFirmwareChange_t;
|
||||||
typedef WebSocketNotification<NumberOfConnection> NumberOfConnection_t;
|
typedef WebSocketNotification<NumberOfConnection> NumberOfConnection_t;
|
||||||
|
|
||||||
@@ -54,11 +55,11 @@ namespace OpenWifi::GWWebSocketNotifications {
|
|||||||
void DeviceDisconnected(SingleDevice_t &N);
|
void DeviceDisconnected(SingleDevice_t &N);
|
||||||
void DeviceStatistics(SingleDevice_t &N);
|
void DeviceStatistics(SingleDevice_t &N);
|
||||||
|
|
||||||
void NumberOfConnections(const std::string & User, NumberOfConnection_t &N);
|
void NumberOfConnections(const std::string &User, NumberOfConnection_t &N);
|
||||||
void DeviceConfigurationChange(const std::string & User, SingleDeviceConfigurationChange_t &N);
|
void DeviceConfigurationChange(const std::string &User, SingleDeviceConfigurationChange_t &N);
|
||||||
void DeviceFirmwareUpdated(const std::string & User, SingleDeviceFirmwareChange_t &);
|
void DeviceFirmwareUpdated(const std::string &User, SingleDeviceFirmwareChange_t &);
|
||||||
void DeviceConnected(const std::string & User, SingleDevice_t &N);
|
void DeviceConnected(const std::string &User, SingleDevice_t &N);
|
||||||
void DeviceDisconnected(const std::string & User, SingleDevice_t &N);
|
void DeviceDisconnected(const std::string &User, SingleDevice_t &N);
|
||||||
void DeviceStatistics(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/Notification.h"
|
||||||
#include "Poco/NotificationQueue.h"
|
#include "Poco/NotificationQueue.h"
|
||||||
|
|
||||||
#include "sdks/sdk_prov.h"
|
|
||||||
#include "AP_WS_Server.h"
|
#include "AP_WS_Server.h"
|
||||||
|
#include "sdks/sdk_prov.h"
|
||||||
|
|
||||||
#include "framework/MicroServiceFuncs.h"
|
#include "framework/MicroServiceFuncs.h"
|
||||||
#include "framework/SubSystemServer.h"
|
#include "framework/SubSystemServer.h"
|
||||||
@@ -18,15 +18,12 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
class VenueBroadcastNotification : public Poco::Notification {
|
class VenueBroadcastNotification : public Poco::Notification {
|
||||||
public:
|
public:
|
||||||
VenueBroadcastNotification(const std::string &SourceSerialNumber, const std::string &Data, uint64_t TimeStamp) :
|
VenueBroadcastNotification(const std::string &SourceSerialNumber, const std::string &Data,
|
||||||
SourceSerialNumber_(SourceSerialNumber),
|
uint64_t TimeStamp)
|
||||||
Data_(Data),
|
: SourceSerialNumber_(SourceSerialNumber), Data_(Data), TimeStamp_(TimeStamp) {}
|
||||||
TimeStamp_(TimeStamp) {
|
|
||||||
|
|
||||||
}
|
|
||||||
std::string SourceSerialNumber_;
|
std::string SourceSerialNumber_;
|
||||||
std::string Data_;
|
std::string Data_;
|
||||||
uint64_t TimeStamp_=Utils::Now();
|
uint64_t TimeStamp_ = Utils::Now();
|
||||||
};
|
};
|
||||||
|
|
||||||
class VenueBroadcaster : public SubSystemServer, Poco::Runnable {
|
class VenueBroadcaster : public SubSystemServer, Poco::Runnable {
|
||||||
@@ -37,40 +34,42 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline int Start() override {
|
inline int Start() override {
|
||||||
Enabled_ = MicroServiceConfigGetBool("venue_broadcast.enabled",true);
|
Enabled_ = MicroServiceConfigGetBool("venue_broadcast.enabled", true);
|
||||||
if(Enabled_) {
|
if (Enabled_) {
|
||||||
BroadcastManager_.start(*this);
|
BroadcastManager_.start(*this);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Stop() override {
|
inline void Stop() override {
|
||||||
poco_information(Logger(),"Stopping...");
|
poco_information(Logger(), "Stopping...");
|
||||||
if(Enabled_ && Running_) {
|
if (Enabled_ && Running_) {
|
||||||
BroadcastQueue_.wakeUpAll();
|
BroadcastQueue_.wakeUpAll();
|
||||||
BroadcastManager_.wakeUp();
|
BroadcastManager_.wakeUp();
|
||||||
BroadcastManager_.join();
|
BroadcastManager_.join();
|
||||||
}
|
}
|
||||||
poco_information(Logger(),"Stopped...");
|
poco_information(Logger(), "Stopped...");
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void reinitialize([[maybe_unused]] Poco::Util::Application &self) override {
|
inline void reinitialize([[maybe_unused]] Poco::Util::Application &self) override {
|
||||||
poco_information(Logger(),"Reinitializing.");
|
poco_information(Logger(), "Reinitializing.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct VenueInfo {
|
struct VenueInfo {
|
||||||
uint64_t timestamp=Utils::Now();
|
uint64_t timestamp = Utils::Now();
|
||||||
Types::StringVec serialNumbers;
|
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...
|
// Can we find our serial number in any of the lists so far...
|
||||||
for(const auto &venue:Venues_) {
|
for (const auto &venue : Venues_) {
|
||||||
auto entry = std::find(venue.second.serialNumbers.begin(),venue.second.serialNumbers.end(),Source);
|
auto entry = std::find(venue.second.serialNumbers.begin(),
|
||||||
if(entry!=venue.second.serialNumbers.end() && (Utils::Now()-venue.second.timestamp)<600) {
|
venue.second.serialNumbers.end(), Source);
|
||||||
|
if (entry != venue.second.serialNumbers.end() &&
|
||||||
|
(Utils::Now() - venue.second.timestamp) < 600) {
|
||||||
SerialNumbers = venue.second.serialNumbers;
|
SerialNumbers = venue.second.serialNumbers;
|
||||||
auto entry2 = std::find(SerialNumbers.begin(),SerialNumbers.end(),Source);
|
auto entry2 = std::find(SerialNumbers.begin(), SerialNumbers.end(), Source);
|
||||||
SerialNumbers.erase(entry2);
|
SerialNumbers.erase(entry2);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -79,12 +78,13 @@ namespace OpenWifi {
|
|||||||
// get the venue from Prov and the serial numbers.
|
// get the venue from Prov and the serial numbers.
|
||||||
Types::UUID_t Venue;
|
Types::UUID_t Venue;
|
||||||
Types::StringVec TmpSerialNumbers;
|
Types::StringVec TmpSerialNumbers;
|
||||||
if(OpenWifi::SDK::Prov::GetSerialNumbersForVenueOfSerialNumber(Source,Venue,TmpSerialNumbers,Logger())) {
|
if (OpenWifi::SDK::Prov::GetSerialNumbersForVenueOfSerialNumber(
|
||||||
std::sort(TmpSerialNumbers.begin(),TmpSerialNumbers.end());
|
Source, Venue, TmpSerialNumbers, Logger())) {
|
||||||
VenueInfo V{.timestamp=Utils::Now(), .serialNumbers=TmpSerialNumbers};
|
std::sort(TmpSerialNumbers.begin(), TmpSerialNumbers.end());
|
||||||
|
VenueInfo V{.timestamp = Utils::Now(), .serialNumbers = TmpSerialNumbers};
|
||||||
Venues_[Venue] = V;
|
Venues_[Venue] = V;
|
||||||
auto p = std::find(TmpSerialNumbers.begin(),TmpSerialNumbers.end(),Source);
|
auto p = std::find(TmpSerialNumbers.begin(), TmpSerialNumbers.end(), Source);
|
||||||
if(p!=TmpSerialNumbers.end()) {
|
if (p != TmpSerialNumbers.end()) {
|
||||||
TmpSerialNumbers.erase(p);
|
TmpSerialNumbers.erase(p);
|
||||||
SerialNumbers = TmpSerialNumbers;
|
SerialNumbers = TmpSerialNumbers;
|
||||||
return true;
|
return true;
|
||||||
@@ -94,57 +94,58 @@ namespace OpenWifi {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void SendToDevice(const std::string &SerialNumber,const std::string &Payload) {
|
inline void SendToDevice(const std::string &SerialNumber, const std::string &Payload) {
|
||||||
AP_WS_Server()->SendFrame(SerialNumber,Payload);
|
AP_WS_Server()->SendFrame(SerialNumber, Payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void run() final {
|
inline void run() final {
|
||||||
Running_ = true;
|
Running_ = true;
|
||||||
Utils::SetThreadName("venue-bcast");
|
Utils::SetThreadName("venue-bcast");
|
||||||
Poco::AutoPtr<Poco::Notification> NextNotification(BroadcastQueue_.waitDequeueNotification());
|
Poco::AutoPtr<Poco::Notification> NextNotification(
|
||||||
|
BroadcastQueue_.waitDequeueNotification());
|
||||||
while (NextNotification && Running_) {
|
while (NextNotification && Running_) {
|
||||||
auto Notification = dynamic_cast<VenueBroadcastNotification *>(NextNotification.get());
|
auto Notification =
|
||||||
|
dynamic_cast<VenueBroadcastNotification *>(NextNotification.get());
|
||||||
if (Notification != nullptr) {
|
if (Notification != nullptr) {
|
||||||
Types::StringVec SerialNumbers;
|
Types::StringVec SerialNumbers;
|
||||||
if(FindSerialNumberList(Notification->SourceSerialNumber_,SerialNumbers)) {
|
if (FindSerialNumberList(Notification->SourceSerialNumber_, SerialNumbers)) {
|
||||||
Poco::JSON::Object Payload;
|
Poco::JSON::Object Payload;
|
||||||
Payload.set("jsonrpc","2.0");
|
Payload.set("jsonrpc", "2.0");
|
||||||
Payload.set("method","venue_broadcast");
|
Payload.set("method", "venue_broadcast");
|
||||||
Poco::JSON::Object ParamBlock;
|
Poco::JSON::Object ParamBlock;
|
||||||
ParamBlock.set("serial",Notification->SourceSerialNumber_);
|
ParamBlock.set("serial", Notification->SourceSerialNumber_);
|
||||||
ParamBlock.set("timestamp",Notification->TimeStamp_);
|
ParamBlock.set("timestamp", Notification->TimeStamp_);
|
||||||
ParamBlock.set("data",Notification->Data_);
|
ParamBlock.set("data", Notification->Data_);
|
||||||
Payload.set("params", ParamBlock);
|
Payload.set("params", ParamBlock);
|
||||||
std::ostringstream o;
|
std::ostringstream o;
|
||||||
Payload.stringify(o);
|
Payload.stringify(o);
|
||||||
for(const auto &Device:SerialNumbers) {
|
for (const auto &Device : SerialNumbers) {
|
||||||
SendToDevice(Device,o.str());
|
SendToDevice(Device, o.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NextNotification = BroadcastQueue_.waitDequeueNotification();
|
NextNotification = BroadcastQueue_.waitDequeueNotification();
|
||||||
}
|
}
|
||||||
Running_=false;
|
Running_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Broadcast(const std::string &SourceSerial, const std::string &Data, uint64_t TimeStamp) {
|
inline void Broadcast(const std::string &SourceSerial, const std::string &Data,
|
||||||
BroadcastQueue_.enqueueNotification(new VenueBroadcastNotification(SourceSerial,Data,TimeStamp));
|
uint64_t TimeStamp) {
|
||||||
|
BroadcastQueue_.enqueueNotification(
|
||||||
|
new VenueBroadcastNotification(SourceSerial, Data, TimeStamp));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::atomic_bool Running_=false;
|
std::atomic_bool Running_ = false;
|
||||||
bool Enabled_=false;
|
bool Enabled_ = false;
|
||||||
Poco::NotificationQueue BroadcastQueue_;
|
Poco::NotificationQueue BroadcastQueue_;
|
||||||
Poco::Thread BroadcastManager_;
|
Poco::Thread BroadcastManager_;
|
||||||
|
|
||||||
std::map<OpenWifi::Types::UUID_t,VenueInfo> Venues_;
|
std::map<OpenWifi::Types::UUID_t, VenueInfo> Venues_;
|
||||||
|
|
||||||
VenueBroadcaster() noexcept:
|
VenueBroadcaster() noexcept
|
||||||
SubSystemServer("VenueBroadcaster", "VENUE-BCAST", "venue.broacast")
|
: SubSystemServer("VenueBroadcaster", "VENUE-BCAST", "venue.broacast") {}
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline auto VenueBroadcaster() { return VenueBroadcaster::instance(); }
|
inline auto VenueBroadcaster() { return VenueBroadcaster::instance(); }
|
||||||
}
|
} // namespace OpenWifi
|
||||||
Reference in New Issue
Block a user