From 61996fe1172a9aea373c8cd3faf42bea5db4dd2c Mon Sep 17 00:00:00 2001 From: Andrew Beltrano Date: Fri, 23 Feb 2024 23:03:42 +0000 Subject: [PATCH] IAccessPointController::GetCapabilities return AccessPointOperationStatus. --- src/common/service/NetRemoteService.cxx | 38 ++++++++------- src/common/wifi/core/CMakeLists.txt | 3 ++ .../core/Ieee80211AccessPointCapabilities.cxx | 44 +++++++++++++++++ .../net/wifi/IAccessPointController.hxx | 9 ++-- .../wifi/Ieee80211AccessPointCapabilities.hxx | 9 ++++ .../wifi/core/AccessPointControllerLinux.cxx | 48 ++++++++++++------- .../net/wifi/AccessPointControllerLinux.hxx | 9 ++-- .../helpers/AccessPointControllerTest.cxx | 7 +-- .../wifi/test/AccessPointControllerTest.hxx | 11 +++-- 9 files changed, 126 insertions(+), 52 deletions(-) create mode 100644 src/common/wifi/core/Ieee80211AccessPointCapabilities.cxx diff --git a/src/common/service/NetRemoteService.cxx b/src/common/service/NetRemoteService.cxx index 1b2796d4..055b048d 100644 --- a/src/common/service/NetRemoteService.cxx +++ b/src/common/service/NetRemoteService.cxx @@ -188,15 +188,17 @@ IAccessPointToNetRemoteAccessPointResultItem(IAccessPoint& accessPoint) return MakeInvalidAccessPointResultItem(); } - Dot11AccessPointCapabilities dot11AccessPointCapabilities{}; - try { - auto ieee80211AccessPointCapabilities = accessPointController->GetCapabilities(); - dot11AccessPointCapabilities = ToDot11AccessPointCapabilities(ieee80211AccessPointCapabilities); - } catch (const AccessPointControllerException& apce) { - LOGE << std::format("Failed to get capabilities for access point {} ({})", interfaceName, apce.what()); + // Obtain capabilities of the access point. + Ieee80211AccessPointCapabilities ieee80211AccessPointCapabilities{}; + operationStatus = accessPointController->GetCapabilities(ieee80211AccessPointCapabilities); + if (!operationStatus) { + LOGE << std::format("Failed to get capabilities for access point {}", interfaceName); return MakeInvalidAccessPointResultItem(); } + Dot11AccessPointCapabilities dot11AccessPointCapabilities{}; + dot11AccessPointCapabilities = ToDot11AccessPointCapabilities(ieee80211AccessPointCapabilities); + const bool isEnabled{ operationalState == AccessPointOperationalState::Enabled }; // Populate the result item. @@ -346,14 +348,15 @@ NetRemoteService::WifiAccessPointSetPhyType([[maybe_unused]] grpc::ServerContext auto ieee80211Protocol = FromDot11PhyType(request->phytype()); // Check if Ieee80211 protocol is supported by AP. - try { - auto accessPointCapabilities = accessPointController->GetCapabilities(); - const auto& supportedIeee80211Protocols = accessPointCapabilities.Protocols; - if (std::ranges::find(supportedIeee80211Protocols, ieee80211Protocol) == std::cend(supportedIeee80211Protocols)) { - return HandleFailure(request, result, WifiAccessPointOperationStatusCode::WifiAccessPointOperationStatusCodeOperationNotSupported, std::format("PHY type not supported by access point {}", request->accesspointid())); - } - } catch (const AccessPointControllerException& apce) { - return HandleFailure(request, result, WifiAccessPointOperationStatusCode::WifiAccessPointOperationStatusCodeInternalError, std::format("Failed to get capabilities for access point {} ({})", request->accesspointid(), apce.what())); + Ieee80211AccessPointCapabilities accessPointCapabilities{}; + auto operationStatus = accessPointController->GetCapabilities(accessPointCapabilities); + if (!operationStatus) { + return HandleFailure(request, result, operationStatus.Code, std::format("Failed to get capabilities for access point {}", request->accesspointid())); + } + + const auto& supportedIeee80211Protocols = accessPointCapabilities.Protocols; + if (std::ranges::find(supportedIeee80211Protocols, ieee80211Protocol) == std::cend(supportedIeee80211Protocols)) { + return HandleFailure(request, result, WifiAccessPointOperationStatusCode::WifiAccessPointOperationStatusCodeOperationNotSupported, std::format("PHY type not supported by access point {}", request->accesspointid())); } // Set the Ieee80211 protocol. @@ -409,10 +412,9 @@ NetRemoteService::WifiAccessPointSetFrequencyBands([[maybe_unused]] grpc::Server // Obtain capabilities of the access point. Ieee80211AccessPointCapabilities accessPointCapabilities{}; - try { - accessPointCapabilities = accessPointController->GetCapabilities(); - } catch (const AccessPointControllerException& apce) { - return HandleFailure(request, result, WifiAccessPointOperationStatusCode::WifiAccessPointOperationStatusCodeInternalError, std::format("Failed to get capabilities for access point {} ({})", request->accesspointid(), apce.what())); + auto operationStatus = accessPointController->GetCapabilities(accessPointCapabilities); + if (!operationStatus) { + return HandleFailure(request, result, operationStatus.Code, std::format("Failed to get capabilities for access point {}", request->accesspointid())); } // Check if requested bands are supported by the AP. diff --git a/src/common/wifi/core/CMakeLists.txt b/src/common/wifi/core/CMakeLists.txt index bbf872ba..db996074 100644 --- a/src/common/wifi/core/CMakeLists.txt +++ b/src/common/wifi/core/CMakeLists.txt @@ -11,6 +11,7 @@ target_sources(wifi-core AccessPointController.cxx AccessPointControllerException.cxx AccessPointOperationStatus.cxx + Ieee80211AccessPointCapabilities.cxx PUBLIC FILE_SET HEADERS BASE_DIRS ${WIFI_CORE_PUBLIC_INCLUDE} @@ -25,6 +26,8 @@ target_sources(wifi-core ) target_link_libraries(wifi-core + PRIVATE + magic_enum::magic_enum PUBLIC notstd ) diff --git a/src/common/wifi/core/Ieee80211AccessPointCapabilities.cxx b/src/common/wifi/core/Ieee80211AccessPointCapabilities.cxx new file mode 100644 index 00000000..57f5547c --- /dev/null +++ b/src/common/wifi/core/Ieee80211AccessPointCapabilities.cxx @@ -0,0 +1,44 @@ + +#include +#include + +#include +#include + +using namespace Microsoft::Net::Wifi; + +std::string +Ieee80211AccessPointCapabilities::ToString() const +{ + std::ostringstream result{}; + + result << "Protocols: "; + for (const auto& protocol : Protocols) { + result << magic_enum::enum_name(protocol); + result << ' '; + } + + result << '\n' + << "Frequency Bands: "; + for (const auto& frequencyBand : FrequencyBands) { + result << magic_enum::enum_name(frequencyBand); + result << ' '; + } + + result << '\n' + << "Akm Suites: "; + for (const auto& akmSuite : AkmSuites) { + result << magic_enum::enum_name(akmSuite); + result << ' '; + } + + result << '\n' + << "Cipher Suites: "; + for (const auto& cipherSuite : CipherSuites) { + result << magic_enum::enum_name(cipherSuite); + result << ' '; + } + result << '\n'; + + return result.str(); +} diff --git a/src/common/wifi/core/include/microsoft/net/wifi/IAccessPointController.hxx b/src/common/wifi/core/include/microsoft/net/wifi/IAccessPointController.hxx index 2896b51c..82baa9c9 100644 --- a/src/common/wifi/core/include/microsoft/net/wifi/IAccessPointController.hxx +++ b/src/common/wifi/core/include/microsoft/net/wifi/IAccessPointController.hxx @@ -74,10 +74,11 @@ struct IAccessPointController /** * @brief Get the capabilities of the access point. * - * @return Ieee80211AccessPointCapabilities + * @param ieee80211AccessPointCapabilities The value to store the capabilities. + * @return AccessPointOperationStatus */ - virtual Ieee80211AccessPointCapabilities - GetCapabilities() = 0; + virtual AccessPointOperationStatus + GetCapabilities(Ieee80211AccessPointCapabilities& ieee80211AccessPointCapabilities) = 0; /** * @brief Set the operational state of the access point. @@ -92,7 +93,7 @@ struct IAccessPointController * @brief Set the Ieee80211 protocol of the access point. * * @param ieeeProtocol The Ieee80211 protocol to be set. - * @return AccessPointOperationStatus + * @return AccessPointOperationStatus */ virtual AccessPointOperationStatus SetProtocol(Ieee80211Protocol ieeeProtocol) = 0; diff --git a/src/common/wifi/core/include/microsoft/net/wifi/Ieee80211AccessPointCapabilities.hxx b/src/common/wifi/core/include/microsoft/net/wifi/Ieee80211AccessPointCapabilities.hxx index 560aa834..ab993cd2 100644 --- a/src/common/wifi/core/include/microsoft/net/wifi/Ieee80211AccessPointCapabilities.hxx +++ b/src/common/wifi/core/include/microsoft/net/wifi/Ieee80211AccessPointCapabilities.hxx @@ -2,6 +2,7 @@ #ifndef IEEE_80211_ACCESS_POINT_CAPABILITIES_HXX #define IEEE_80211_ACCESS_POINT_CAPABILITIES_HXX +#include #include #include @@ -17,6 +18,14 @@ struct Ieee80211AccessPointCapabilities std::vector FrequencyBands; std::vector AkmSuites; std::vector CipherSuites; + + /** + * @brief Get a string representation of the capabilities. + * + * @return std::string + */ + std::string + ToString() const; }; } // namespace Microsoft::Net::Wifi diff --git a/src/linux/wifi/core/AccessPointControllerLinux.cxx b/src/linux/wifi/core/AccessPointControllerLinux.cxx index 36a78ef2..f79a2d6e 100644 --- a/src/linux/wifi/core/AccessPointControllerLinux.cxx +++ b/src/linux/wifi/core/AccessPointControllerLinux.cxx @@ -150,32 +150,44 @@ IeeeFrequencyBandToHostapdBand(Ieee80211FrequencyBand ieeeFrequencyBand) } } // namespace detail -Ieee80211AccessPointCapabilities -AccessPointControllerLinux::GetCapabilities() +AccessPointOperationStatus +AccessPointControllerLinux::GetCapabilities(Ieee80211AccessPointCapabilities& ieee80211AccessPointCapabilities) { - auto wiphy = Nl80211Wiphy::FromInterfaceName(GetInterfaceName()); + AccessPointOperationStatus status{}; + + const auto wiphy = Nl80211Wiphy::FromInterfaceName(GetInterfaceName()); if (!wiphy.has_value()) { - throw AccessPointControllerException(std::format("Failed to get wiphy for interface {}", GetInterfaceName())); - } + status.Code = AccessPointOperationStatusCode::AccessPointInvalid; + status.Message = std::format("Failed to get wiphy for interface {}", GetInterfaceName()); + } else { + Ieee80211AccessPointCapabilities capabilities; - Ieee80211AccessPointCapabilities capabilities; + // Convert protocols. + capabilities.Protocols = detail::Nl80211WiphyToIeee80211Protocols(wiphy.value()); - // Convert protocols. - capabilities.Protocols = detail::Nl80211WiphyToIeee80211Protocols(wiphy.value()); + // Convert frequency bands. + capabilities.FrequencyBands = std::vector(std::size(wiphy->Bands)); + std::ranges::transform(std::views::keys(wiphy->Bands), std::begin(capabilities.FrequencyBands), detail::Nl80211BandToIeee80211FrequencyBand); - // Convert frequency bands. - capabilities.FrequencyBands = std::vector(std::size(wiphy->Bands)); - std::ranges::transform(std::views::keys(wiphy->Bands), std::begin(capabilities.FrequencyBands), detail::Nl80211BandToIeee80211FrequencyBand); + // Convert AKM suites. + capabilities.AkmSuites = std::vector(std::size(wiphy->AkmSuites)); + std::ranges::transform(wiphy->AkmSuites, std::begin(capabilities.AkmSuites), detail::Nl80211AkmSuiteToIeee80211AkmSuite); - // Convert AKM suites. - capabilities.AkmSuites = std::vector(std::size(wiphy->AkmSuites)); - std::ranges::transform(wiphy->AkmSuites, std::begin(capabilities.AkmSuites), detail::Nl80211AkmSuiteToIeee80211AkmSuite); + // Convert cipher suites. + capabilities.CipherSuites = std::vector(std::size(wiphy->CipherSuites)); + std::ranges::transform(wiphy->CipherSuites, std::begin(capabilities.CipherSuites), detail::Nl80211CipherSuiteToIeee80211CipherSuite); - // Convert cipher suites. - capabilities.CipherSuites = std::vector(std::size(wiphy->CipherSuites)); - std::ranges::transform(wiphy->CipherSuites, std::begin(capabilities.CipherSuites), detail::Nl80211CipherSuiteToIeee80211CipherSuite); + ieee80211AccessPointCapabilities = std::move(capabilities); + status = AccessPointOperationStatus::MakeSucceeded(); + } - return capabilities; + if (status.Succeeded()) { + LOGD << std::format("Got capabilities for interface {}", GetInterfaceName()); + } else { + LOGE << std::format("Failed to get capabilities for interface {} ({} - {})", GetInterfaceName(), magic_enum::enum_name(status.Code), status.Message); + } + + return status; } AccessPointOperationStatus diff --git a/src/linux/wifi/core/include/microsoft/net/wifi/AccessPointControllerLinux.hxx b/src/linux/wifi/core/include/microsoft/net/wifi/AccessPointControllerLinux.hxx index e4a0dbee..928a0214 100644 --- a/src/linux/wifi/core/include/microsoft/net/wifi/AccessPointControllerLinux.hxx +++ b/src/linux/wifi/core/include/microsoft/net/wifi/AccessPointControllerLinux.hxx @@ -52,12 +52,13 @@ struct AccessPointControllerLinux : GetOperationalState(AccessPointOperationalState& operationalState) override; /** - * @brief Get the Capabilities object + * @brief Get the capabilities of the access point. * - * @return Ieee80211AccessPointCapabilities + * @param ieee80211AccessPointCapabilities The value to store the capabilities. + * @return AccessPointOperationStatus */ - Ieee80211AccessPointCapabilities - GetCapabilities() override; + AccessPointOperationStatus + GetCapabilities(Ieee80211AccessPointCapabilities& ieee80211AccessPointCapabilities) override; /** * @brief Set the operational state of the access point. diff --git a/tests/unit/wifi/helpers/AccessPointControllerTest.cxx b/tests/unit/wifi/helpers/AccessPointControllerTest.cxx index c09d0885..bb3da4a6 100644 --- a/tests/unit/wifi/helpers/AccessPointControllerTest.cxx +++ b/tests/unit/wifi/helpers/AccessPointControllerTest.cxx @@ -45,14 +45,15 @@ AccessPointControllerTest::GetOperationalState(AccessPointOperationalState &oper return AccessPointOperationStatus::MakeSucceeded(); } -Ieee80211AccessPointCapabilities -AccessPointControllerTest::GetCapabilities() +AccessPointOperationStatus +AccessPointControllerTest::GetCapabilities(Ieee80211AccessPointCapabilities &ieee80211AccessPointCapabilities) { if (AccessPoint == nullptr) { throw std::runtime_error("AccessPointControllerTest::GetCapabilities called with null AccessPoint"); } - return AccessPoint->Capabilities; + ieee80211AccessPointCapabilities = AccessPoint->Capabilities; + return AccessPointOperationStatus::MakeSucceeded(); } AccessPointOperationStatus diff --git a/tests/unit/wifi/helpers/include/microsoft/net/wifi/test/AccessPointControllerTest.hxx b/tests/unit/wifi/helpers/include/microsoft/net/wifi/test/AccessPointControllerTest.hxx index 5ba95035..a1728832 100644 --- a/tests/unit/wifi/helpers/include/microsoft/net/wifi/test/AccessPointControllerTest.hxx +++ b/tests/unit/wifi/helpers/include/microsoft/net/wifi/test/AccessPointControllerTest.hxx @@ -59,18 +59,19 @@ struct AccessPointControllerTest final : * @brief Get the access point operational state. * * @param operationalState The value to store the operational state. - * @return AccessPointOperationStatus + * @return AccessPointOperationStatus */ AccessPointOperationStatus - GetOperationalState(AccessPointOperationalState& operationalState) override; + GetOperationalState(AccessPointOperationalState &operationalState) override; /** * @brief Get the capabilities of the access point. * - * @return Ieee80211AccessPointCapabilities + * @param ieee80211AccessPointCapabilities The value to store the capabilities. + * @return AccessPointOperationStatus */ - Ieee80211AccessPointCapabilities - GetCapabilities() override; + AccessPointOperationStatus + GetCapabilities(Ieee80211AccessPointCapabilities &ieee80211AccessPointCapabilities) override; /** * @brief Set the operational state of the access point.