From 132b31b06b469cb759af2fa99fb262a69c1ceb0c Mon Sep 17 00:00:00 2001 From: Ivan Chvets Date: Wed, 11 Sep 2024 15:50:30 -0400 Subject: [PATCH 1/7] feat: add fixedconfig command https://telecominfraproject.atlassian.net/browse/WIFI-13126 Summary of changes: - Added `fixedconfig` command. Signed-off-by: Ivan Chvets --- src/RESTAPI/RESTAPI_device_commandHandler.cpp | 41 ++++++++++++++++++- src/RESTAPI/RESTAPI_device_commandHandler.h | 2 + src/RESTObjects/RESTAPI_GWobjects.cpp | 9 ++++ src/RESTObjects/RESTAPI_GWobjects.h | 6 +++ src/framework/ow_constants.h | 8 +++- 5 files changed, 64 insertions(+), 2 deletions(-) diff --git a/src/RESTAPI/RESTAPI_device_commandHandler.cpp b/src/RESTAPI/RESTAPI_device_commandHandler.cpp index e0a6f0d4..d6a3dcd2 100644 --- a/src/RESTAPI/RESTAPI_device_commandHandler.cpp +++ b/src/RESTAPI/RESTAPI_device_commandHandler.cpp @@ -167,7 +167,9 @@ namespace OpenWifi { {APCommands::Commands::certupdate, false, true, &RESTAPI_device_commandHandler::CertUpdate, 60000ms}, {APCommands::Commands::transfer, false, true, &RESTAPI_device_commandHandler::Transfer, 60000ms}, {APCommands::Commands::script, false, true, &RESTAPI_device_commandHandler::Script, 60000ms}, - {APCommands::Commands::powercycle, false, true, &RESTAPI_device_commandHandler::PowerCycle, 60000ms} + {APCommands::Commands::powercycle, false, true, &RESTAPI_device_commandHandler::PowerCycle, 60000ms}, + {APCommands::Commands::fixedconfig, false, true, &RESTAPI_device_commandHandler::FixedConfig, 120000ms}, + }; void RESTAPI_device_commandHandler::DoPost() { @@ -1548,4 +1550,41 @@ namespace OpenWifi { Logger_); } + // `fixedconfig` command is used set country propery on AP + // This handler uses `fixedconfig` command definitions + void RESTAPI_device_commandHandler::FixedConfig( + const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, + [[maybe_unused]] const GWObjects::DeviceRestrictions &Restrictions) { + poco_debug(Logger_, fmt::format("FIXEDCONFIG({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, + TransactionId_, Requester(), SerialNumber_)); + // do not allow `fixedconfig` command for simulated devices + if(IsDeviceSimulated(SerialNumber_)) { + CallCanceled("FIXEDCONFIG", CMD_UUID, CMD_RPC, RESTAPI::Errors::SimulatedDeviceNotSupported); + return BadRequest(RESTAPI::Errors::SimulatedDeviceNotSupported); + } + + // setup and validate fixedconfig object + GWObjects::FixedConfig fixed_config; + if(!fixed_config.from_json(ParsedBody_)) { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } + + // setup command message + GWObjects::CommandDetails Cmd; + Cmd.SerialNumber = SerialNumber_; + Cmd.SubmittedBy = Requester(); + Cmd.UUID = CMD_UUID; + Cmd.Command = uCentralProtocol::FIXEDCONFIG; + std::ostringstream os; + ParsedBody_->stringify(os); + Cmd.Details = os.str(); + Cmd.RunAt = 0; + Cmd.ErrorCode = 0; + Cmd.WaitingForFile = 0; + + // send fixedconfig command to device and return status + return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::fixedconfig, false, Cmd, + *ParsedBody_, *Request, *Response, timeout, nullptr, this, + Logger_); + } } // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_device_commandHandler.h b/src/RESTAPI/RESTAPI_device_commandHandler.h index e20800f3..1b7a2937 100644 --- a/src/RESTAPI/RESTAPI_device_commandHandler.h +++ b/src/RESTAPI/RESTAPI_device_commandHandler.h @@ -70,6 +70,8 @@ namespace OpenWifi { const GWObjects::DeviceRestrictions &R); void PowerCycle(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R); + void FixedConfig(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, + const GWObjects::DeviceRestrictions &R); static auto PathName() { return std::list{"/api/v1/device/{serialNumber}/{command}"}; diff --git a/src/RESTObjects/RESTAPI_GWobjects.cpp b/src/RESTObjects/RESTAPI_GWobjects.cpp index 09da2c36..9c50afc1 100644 --- a/src/RESTObjects/RESTAPI_GWobjects.cpp +++ b/src/RESTObjects/RESTAPI_GWobjects.cpp @@ -799,4 +799,13 @@ namespace OpenWifi::GWObjects { return false; } + bool FixedConfig::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "serial", serialNumber); + field_from_json(Obj, "country", country); + return true; + } catch (const Poco::Exception &E) { + } + return false; + } } // namespace OpenWifi::GWObjects diff --git a/src/RESTObjects/RESTAPI_GWobjects.h b/src/RESTObjects/RESTAPI_GWobjects.h index ed17aba7..d70f0c02 100644 --- a/src/RESTObjects/RESTAPI_GWobjects.h +++ b/src/RESTObjects/RESTAPI_GWobjects.h @@ -532,6 +532,12 @@ namespace OpenWifi::GWObjects { std::uint64_t when; std::vector ports; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + struct FixedConfig { + std::string serialNumber; + std::string country; + bool from_json(const Poco::JSON::Object::Ptr &Obj); }; } // namespace OpenWifi::GWObjects diff --git a/src/framework/ow_constants.h b/src/framework/ow_constants.h index 2e838ff2..2fed9536 100644 --- a/src/framework/ow_constants.h +++ b/src/framework/ow_constants.h @@ -580,6 +580,8 @@ namespace OpenWifi::RESTAPI::Protocol { static const char *INTERVAL = "interval"; static const char *UI = "UI"; static const char *BANDWIDTH = "bandwidth"; + + static const char *FIXEDCONFIG = "fixedconfig"; } // namespace OpenWifi::RESTAPI::Protocol namespace OpenWifi::uCentralProtocol { @@ -692,6 +694,8 @@ namespace OpenWifi::uCentralProtocol { static const char *RRM = "rrm"; static const char *ACTIONS = "actions"; + static const char *FIXEDCONFIG = "fixedconfig"; + } // namespace OpenWifi::uCentralProtocol namespace OpenWifi::uCentralProtocol::Events { @@ -788,6 +792,7 @@ namespace OpenWifi::APCommands { certupdate, transfer, powercycle, + fixedconfig, unknown }; @@ -802,7 +807,8 @@ namespace OpenWifi::APCommands { RESTAPI::Protocol::EVENTQUEUE, RESTAPI::Protocol::TELEMETRY, RESTAPI::Protocol::PING, RESTAPI::Protocol::SCRIPT, RESTAPI::Protocol::RRM, RESTAPI::Protocol::CERTUPDATE, - RESTAPI::Protocol::TRANSFER, RESTAPI::Protocol::POWERCYCLE + RESTAPI::Protocol::TRANSFER, RESTAPI::Protocol::POWERCYCLE, + RESTAPI::Protocol::FIXEDCONFIG }; inline const char *to_string(Commands Cmd) { return uCentralAPCommands[(uint8_t)Cmd]; } From b1be0604d67cf39e7c2f98acdb257674d62a2eaf Mon Sep 17 00:00:00 2001 From: Ivan Chvets Date: Fri, 13 Sep 2024 10:46:35 -0400 Subject: [PATCH 2/7] feat: fixedconfig doc update https://telecominfraproject.atlassian.net/browse/WIFI-13126 Summary of changes: - Updated documentation. Signed-off-by: Ivan Chvets --- PROTOCOL.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/PROTOCOL.md b/PROTOCOL.md index c84eb1fc..a3af296d 100644 --- a/PROTOCOL.md +++ b/PROTOCOL.md @@ -306,8 +306,40 @@ The device should answer: }, "id" : } +``` + +#### Controller wants the device to apply a given fixed configuration + +Controller sends this command when it requires the device to apply fixed configuration, eg. country code. The device +should respond with message indicating failure or success. +```json +{ "jsonrpc" : "2.0", + "method" : "fixedconfig", + "params" : { + "serial" : , + "when" : Optional - + "country" : "" + }, +} ``` + +The device should answer: +```json +{ "jsonrpc" : "2.0", + "result" : { + "serial": , + "status": { + "error": 0 or an error number, + "text": + }, + "uuid": + } +} + +``` + + ##### The Answer The device can answer and tell the controller it has rejected certain parts of the config and potentially replaced them with appropriate values. This could be used to allow a device to replace frequencies for the regions it is located in. The device From b3deba5606fb124d6b987548e6da7409ca9670f0 Mon Sep 17 00:00:00 2001 From: Ivan Chvets Date: Wed, 18 Sep 2024 10:52:35 -0400 Subject: [PATCH 3/7] feat: add cable diagnostics command https://telecominfraproject.atlassian.net/browse/OLS-246 Summary of changes: - Added `cablediagnostics` command. Signed-off-by: Ivan Chvets --- src/RESTAPI/RESTAPI_device_commandHandler.cpp | 42 +++++++++++++++++++ src/RESTAPI/RESTAPI_device_commandHandler.h | 2 + src/RESTObjects/RESTAPI_GWobjects.cpp | 11 +++++ src/RESTObjects/RESTAPI_GWobjects.h | 7 ++++ src/framework/ow_constants.h | 5 ++- 5 files changed, 66 insertions(+), 1 deletion(-) diff --git a/src/RESTAPI/RESTAPI_device_commandHandler.cpp b/src/RESTAPI/RESTAPI_device_commandHandler.cpp index d6a3dcd2..6d0ef9d3 100644 --- a/src/RESTAPI/RESTAPI_device_commandHandler.cpp +++ b/src/RESTAPI/RESTAPI_device_commandHandler.cpp @@ -169,6 +169,7 @@ namespace OpenWifi { {APCommands::Commands::script, false, true, &RESTAPI_device_commandHandler::Script, 60000ms}, {APCommands::Commands::powercycle, false, true, &RESTAPI_device_commandHandler::PowerCycle, 60000ms}, {APCommands::Commands::fixedconfig, false, true, &RESTAPI_device_commandHandler::FixedConfig, 120000ms}, + {APCommands::Commands::cablediagnostics, false, true, &RESTAPI_device_commandHandler::CableDiagnostics, 120000ms}, }; @@ -1587,4 +1588,45 @@ namespace OpenWifi { *ParsedBody_, *Request, *Response, timeout, nullptr, this, Logger_); } + + void RESTAPI_device_commandHandler::CableDiagnostics( + const std::string &CMD_UUID, uint64_t CMD_RPC, + [[maybe_unused]] std::chrono::milliseconds timeout, + [[maybe_unused]] const GWObjects::DeviceRestrictions &Restrictions) { + + if(UserInfo_.userinfo.userRole != SecurityObjects::ROOT && + UserInfo_.userinfo.userRole != SecurityObjects::ADMIN) { + CallCanceled("CABLEDIAGNOSTICS", CMD_UUID, CMD_RPC, RESTAPI::Errors::ACCESS_DENIED); + return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); + } + + poco_debug(Logger_, fmt::format("CABLEDIAGNOSTICS({},{}): TID={} user={} serial={}", CMD_UUID, + CMD_RPC, TransactionId_, Requester(), SerialNumber_)); + + if(IsDeviceSimulated(SerialNumber_)) { + CallCanceled("CABLEDIAGNOSTICS", CMD_UUID, CMD_RPC, RESTAPI::Errors::SimulatedDeviceNotSupported); + return BadRequest(RESTAPI::Errors::SimulatedDeviceNotSupported); + } + + GWObjects::CableDiagnostics PR; + if(!PR.from_json(ParsedBody_)) { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } + + GWObjects::CommandDetails Cmd; + Cmd.SerialNumber = SerialNumber_; + Cmd.SubmittedBy = Requester(); + Cmd.UUID = CMD_UUID; + Cmd.Command = uCentralProtocol::CABLEDIAGNOSTICS; + std::ostringstream os; + ParsedBody_->stringify(os); + Cmd.Details = os.str(); + Cmd.RunAt = PR.when; + Cmd.ErrorCode = 0; + Cmd.WaitingForFile = 0; + + return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::cablediagnostics, false, Cmd, + *ParsedBody_, *Request, *Response, timeout, nullptr, this, + Logger_); + } } // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_device_commandHandler.h b/src/RESTAPI/RESTAPI_device_commandHandler.h index 1b7a2937..25f22d9f 100644 --- a/src/RESTAPI/RESTAPI_device_commandHandler.h +++ b/src/RESTAPI/RESTAPI_device_commandHandler.h @@ -72,6 +72,8 @@ namespace OpenWifi { const GWObjects::DeviceRestrictions &R); void FixedConfig(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R); + void CableDiagnostics(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, + const GWObjects::DeviceRestrictions &R); static auto PathName() { return std::list{"/api/v1/device/{serialNumber}/{command}"}; diff --git a/src/RESTObjects/RESTAPI_GWobjects.cpp b/src/RESTObjects/RESTAPI_GWobjects.cpp index 9c50afc1..ead5968d 100644 --- a/src/RESTObjects/RESTAPI_GWobjects.cpp +++ b/src/RESTObjects/RESTAPI_GWobjects.cpp @@ -808,4 +808,15 @@ namespace OpenWifi::GWObjects { } return false; } + + bool CableDiagnostics::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "serial", serialNumber); + field_from_json(Obj, "when", when); + field_from_json(Obj, "ports", ports); + return true; + } catch (const Poco::Exception &E) { + } + return false; + } } // namespace OpenWifi::GWObjects diff --git a/src/RESTObjects/RESTAPI_GWobjects.h b/src/RESTObjects/RESTAPI_GWobjects.h index d70f0c02..c2136c45 100644 --- a/src/RESTObjects/RESTAPI_GWobjects.h +++ b/src/RESTObjects/RESTAPI_GWobjects.h @@ -538,6 +538,13 @@ namespace OpenWifi::GWObjects { std::string serialNumber; std::string country; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + struct CableDiagnostics { + std::string serialNumber; + std::uint64_t when; + std::vector ports; + bool from_json(const Poco::JSON::Object::Ptr &Obj); }; } // namespace OpenWifi::GWObjects diff --git a/src/framework/ow_constants.h b/src/framework/ow_constants.h index 2fed9536..3de98529 100644 --- a/src/framework/ow_constants.h +++ b/src/framework/ow_constants.h @@ -582,6 +582,7 @@ namespace OpenWifi::RESTAPI::Protocol { static const char *BANDWIDTH = "bandwidth"; static const char *FIXEDCONFIG = "fixedconfig"; + static const char *CABLEDIAGNOSTICS = "cablediagnostics"; } // namespace OpenWifi::RESTAPI::Protocol namespace OpenWifi::uCentralProtocol { @@ -695,6 +696,7 @@ namespace OpenWifi::uCentralProtocol { static const char *ACTIONS = "actions"; static const char *FIXEDCONFIG = "fixedconfig"; + static const char *CABLEDIAGNOSTICS = "cablediagnostics"; } // namespace OpenWifi::uCentralProtocol @@ -793,6 +795,7 @@ namespace OpenWifi::APCommands { transfer, powercycle, fixedconfig, + cablediagnostics, unknown }; @@ -808,7 +811,7 @@ namespace OpenWifi::APCommands { RESTAPI::Protocol::PING, RESTAPI::Protocol::SCRIPT, RESTAPI::Protocol::RRM, RESTAPI::Protocol::CERTUPDATE, RESTAPI::Protocol::TRANSFER, RESTAPI::Protocol::POWERCYCLE, - RESTAPI::Protocol::FIXEDCONFIG + RESTAPI::Protocol::FIXEDCONFIG, RESTAPI::Protocol::CABLEDIAGNOSTICS }; inline const char *to_string(Commands Cmd) { return uCentralAPCommands[(uint8_t)Cmd]; } From b9f00f660370f87954e71e3041d7f8198b267b2c Mon Sep 17 00:00:00 2001 From: Ivan Chvets Date: Thu, 19 Sep 2024 10:26:51 -0400 Subject: [PATCH 4/7] fix: sync-ed up ucentral schema with code https://telecominfraproject.atlassian.net/browse/WIFI-14140 Summary of changes: - Synchronized built-in schema in configuration validation code with ucentral schema. Signed-off-by: Ivan Chvets --- src/framework/ConfigurationValidator.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/framework/ConfigurationValidator.cpp b/src/framework/ConfigurationValidator.cpp index e170dd9a..ba7bcf98 100644 --- a/src/framework/ConfigurationValidator.cpp +++ b/src/framework/ConfigurationValidator.cpp @@ -6603,10 +6603,17 @@ static std::string DefaultSWITCHSchema = R"foo( "$ref": "#/$defs/interface.ssid.encryption" }, "multi-psk": { - "type": "array", - "items": { - "$ref": "#/$defs/interface.ssid.multi-psk" - } + "anyOf": [ + { + "type": "array", + "items": { + "$ref": "#/$defs/interface.ssid.multi-psk" + } + }, + { + "type": "boolean" + } + ] }, "rrm": { "$ref": "#/$defs/interface.ssid.rrm" From f9ee19af912eb2fb82db20f2af3d836fe3045650 Mon Sep 17 00:00:00 2001 From: Ivan Chvets Date: Wed, 25 Sep 2024 08:30:58 -0400 Subject: [PATCH 5/7] fix: sync-ed up ucentral schema with code - added missing code https://telecominfraproject.atlassian.net/browse/WIFI-14140 Summary of changes: - Synchronized built-in schema in configuration validation code with ucentral schema. Added missing code. Signed-off-by: Ivan Chvets --- src/framework/ConfigurationValidator.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/framework/ConfigurationValidator.cpp b/src/framework/ConfigurationValidator.cpp index ba7bcf98..807d416c 100644 --- a/src/framework/ConfigurationValidator.cpp +++ b/src/framework/ConfigurationValidator.cpp @@ -2411,11 +2411,18 @@ static std::string DefaultAPSchema = R"foo( "$ref": "#/$defs/interface.ssid.encryption" }, "multi-psk": { - "type": "array", - "items": { - "$ref": "#/$defs/interface.ssid.multi-psk" - } - }, + "anyOf": [ + { + "type": "array", + "items": { + "$ref": "#/$defs/interface.ssid.multi-psk" + } + }, + { + "type": "boolean" + } + ] + }, "rrm": { "$ref": "#/$defs/interface.ssid.rrm" }, From 9c9987e1903cc530c54d50f79f546b2ad6d4029e Mon Sep 17 00:00:00 2001 From: Ivan Chvets Date: Wed, 25 Sep 2024 10:17:52 -0400 Subject: [PATCH 6/7] feat: add cable diagnostics command https://telecominfraproject.atlassian.net/browse/OLS-246 Summary of changes: - Modified code to match spec, ie. command is `cable-diagnostics`. Signed-off-by: Ivan Chvets --- src/framework/ow_constants.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/framework/ow_constants.h b/src/framework/ow_constants.h index 3de98529..adac0cc6 100644 --- a/src/framework/ow_constants.h +++ b/src/framework/ow_constants.h @@ -582,7 +582,7 @@ namespace OpenWifi::RESTAPI::Protocol { static const char *BANDWIDTH = "bandwidth"; static const char *FIXEDCONFIG = "fixedconfig"; - static const char *CABLEDIAGNOSTICS = "cablediagnostics"; + static const char *CABLEDIAGNOSTICS = "cable-diagnostics"; } // namespace OpenWifi::RESTAPI::Protocol namespace OpenWifi::uCentralProtocol { @@ -696,7 +696,7 @@ namespace OpenWifi::uCentralProtocol { static const char *ACTIONS = "actions"; static const char *FIXEDCONFIG = "fixedconfig"; - static const char *CABLEDIAGNOSTICS = "cablediagnostics"; + static const char *CABLEDIAGNOSTICS = "cable-diagnostics"; } // namespace OpenWifi::uCentralProtocol From 38bc0f0d69f23ca63db065e8a62ab48471b57357 Mon Sep 17 00:00:00 2001 From: Adam Capparelli Date: Wed, 25 Sep 2024 10:40:06 -0400 Subject: [PATCH 7/7] Fix wrong port in openapi.yaml Signed-off-by: Adam Capparelli --- openapi/owgw.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openapi/owgw.yaml b/openapi/owgw.yaml index a03a1d27..2ff02dae 100644 --- a/openapi/owgw.yaml +++ b/openapi/owgw.yaml @@ -12,7 +12,7 @@ info: url: https://www.ucentral.info/support servers: - - url: 'https://localhost:16001/api/v1' + - url: 'https://localhost:16002/api/v1' security: - bearerAuth: []