diff --git a/src/common/server/NetRemoteServer.cxx b/src/common/server/NetRemoteServer.cxx index 83428a4a..72ac40bd 100644 --- a/src/common/server/NetRemoteServer.cxx +++ b/src/common/server/NetRemoteServer.cxx @@ -9,8 +9,9 @@ using namespace Microsoft::Net::Remote; -NetRemoteServer::NetRemoteServer(std::string_view serverAddress) : - m_serverAddress{ serverAddress } +NetRemoteServer::NetRemoteServer(NetRemoteServerConfiguration configuration) : + m_serverAddress(configuration.ServerAddress), + m_service(configuration.AccessPointManager) {} NetRemoteServer::~NetRemoteServer() @@ -24,6 +25,12 @@ NetRemoteServer::GetGrpcServer() noexcept return m_server; } +Service::NetRemoteService& +NetRemoteServer::GetService() noexcept +{ + return m_service; +} + void NetRemoteServer::Run() { @@ -36,7 +43,7 @@ NetRemoteServer::Run() builder.RegisterService(&m_service); m_server = builder.BuildAndStart(); - LOG_INFO << std::format("netremote server started listening on {}", m_serverAddress); + LOG_INFO << std::format("Netremote server started listening on {}", m_serverAddress); } void diff --git a/src/common/server/NetRemoteServerConfiguration.cxx b/src/common/server/NetRemoteServerConfiguration.cxx index d099f4fa..54332e36 100644 --- a/src/common/server/NetRemoteServerConfiguration.cxx +++ b/src/common/server/NetRemoteServerConfiguration.cxx @@ -19,12 +19,12 @@ ConfigureCliAppOptions(CLI::App& app, NetRemoteServerConfiguration& config) app.add_option( "-a,--address", config.ServerAddress, - "The address to listen on for incoming connections."); + "The address to listen on for incoming connections"); - app.add_option( + app.add_flag( "-v,--verbosity", config.LogVerbosity, - "The log verbosity level. Supply multiple times to increase verbosity (0=warnings, errors, and fatal messages, 1=info messages, 2=debug messages, 3=verbose messages)."); + "The log verbosity level. Supply multiple times to increase verbosity (0=warnings, errors, and fatal messages, 1=info messages, 2=debug messages, 3=verbose messages)"); return app; } diff --git a/src/common/server/include/microsoft/net/remote/NetRemoteServer.hxx b/src/common/server/include/microsoft/net/remote/NetRemoteServer.hxx index 69f57e07..63a4d92f 100644 --- a/src/common/server/include/microsoft/net/remote/NetRemoteServer.hxx +++ b/src/common/server/include/microsoft/net/remote/NetRemoteServer.hxx @@ -7,7 +7,9 @@ #include #include +#include #include +#include namespace Microsoft::Net::Remote { @@ -19,11 +21,11 @@ struct NetRemoteServer virtual ~NetRemoteServer(); /** - * @brief Construct a new NetRemoteServer object. + * @brief Construct a new NetRemoteServer object with the specified configuration. * - * @param serverAddress + * @param configuration */ - NetRemoteServer(std::string_view serverAddress); + NetRemoteServer(NetRemoteServerConfiguration configuration); /** * @brief Get the GrpcServer object. @@ -33,6 +35,14 @@ struct NetRemoteServer std::unique_ptr& GetGrpcServer() noexcept; + /** + * @brief Get the NetRemoteService object instance. + * + * @return Service::NetRemoteService& + */ + Service::NetRemoteService& + GetService() noexcept; + /** * @brief Start the server if not already started. */ diff --git a/src/common/server/include/microsoft/net/remote/NetRemoteServerConfiguration.hxx b/src/common/server/include/microsoft/net/remote/NetRemoteServerConfiguration.hxx index e8926067..e6d90722 100644 --- a/src/common/server/include/microsoft/net/remote/NetRemoteServerConfiguration.hxx +++ b/src/common/server/include/microsoft/net/remote/NetRemoteServerConfiguration.hxx @@ -3,11 +3,20 @@ #define NET_REMOTE_SERVER_CONFIGURATION_HXX #include +#include #include #include +namespace Microsoft::Net::Wifi +{ +class AccessPointManager; +} // namespace Microsoft::Net::Wifi + namespace Microsoft::Net::Remote { +/** + * @brief Collects configuration options for the NetRemoteServer class. + */ struct NetRemoteServerConfiguration { /** @@ -54,7 +63,12 @@ struct NetRemoteServerConfiguration * show all info messages, and a level of 2 will show all debug messages, * and a level of 3 or above will show all verbose messages. */ - uint8_t LogVerbosity{ 0 }; + uint32_t LogVerbosity{ 0 }; + + /** + * @brief Access point manager instance. + */ + std::shared_ptr AccessPointManager; }; } // namespace Microsoft::Net::Remote diff --git a/src/common/service/NetRemoteService.cxx b/src/common/service/NetRemoteService.cxx index c5357d7f..a7e648a6 100644 --- a/src/common/service/NetRemoteService.cxx +++ b/src/common/service/NetRemoteService.cxx @@ -1,6 +1,5 @@ #include -#include #include #include #include @@ -13,15 +12,25 @@ using namespace Microsoft::Net::Remote::Service; using Microsoft::Net::Wifi::AccessPointManager; NetRemoteService::NetRemoteService() : - m_accessPointManager(AccessPointManager::Create()) + NetRemoteService(AccessPointManager::Create()) {} +NetRemoteService::NetRemoteService(std::shared_ptr accessPointManager) : + m_accessPointManager(std::move(accessPointManager)) +{} + +std::shared_ptr +NetRemoteService::GetAccessPointManager() noexcept +{ + return m_accessPointManager; +} + ::grpc::Status NetRemoteService::WifiEnumerateAccessPoints([[maybe_unused]] ::grpc::ServerContext* context, [[maybe_unused]] const ::Microsoft::Net::Remote::Wifi::WifiEnumerateAccessPointsRequest* request, ::Microsoft::Net::Remote::Wifi::WifiEnumerateAccessPointsResult* response) { using Microsoft::Net::Remote::Wifi::WifiEnumerateAccessPointsResultItem; - LOG_VERBOSE << std::format("Received WifiEnumerateAccessPoints request\n"); + LOGD << std::format("Received WifiEnumerateAccessPoints request"); auto accessPoints = m_accessPointManager->GetAllAccessPoints(); std::vector accessPointResultItems(std::size(accessPoints)); @@ -53,7 +62,7 @@ using Microsoft::Net::Wifi::Dot11PhyType; ::grpc::Status NetRemoteService::WifiAccessPointEnable([[maybe_unused]] ::grpc::ServerContext* context, const ::Microsoft::Net::Remote::Wifi::WifiAccessPointEnableRequest* request, ::Microsoft::Net::Remote::Wifi::WifiAccessPointEnableResult* response) { - LOG_VERBOSE << std::format("Received WifiAccessPointEnable request for access point id {}\n", request->accesspointid()); + LOGD << std::format("Received WifiAccessPointEnable request for access point id {}", request->accesspointid()); WifiAccessPointOperationStatus status{}; @@ -72,7 +81,7 @@ NetRemoteService::WifiAccessPointEnable([[maybe_unused]] ::grpc::ServerContext* ::grpc::Status NetRemoteService::WifiAccessPointDisable([[maybe_unused]] ::grpc::ServerContext* context, const ::Microsoft::Net::Remote::Wifi::WifiAccessPointDisableRequest* request, ::Microsoft::Net::Remote::Wifi::WifiAccessPointDisableResult* response) { - LOG_VERBOSE << std::format("Received WifiAccessPointDisable request for access point id {}\n", request->accesspointid()); + LOGD << std::format("Received WifiAccessPointDisable request for access point id {}", request->accesspointid()); WifiAccessPointOperationStatus status{}; // TODO: Disable the access point. diff --git a/src/common/service/include/microsoft/net/remote/NetRemoteService.hxx b/src/common/service/include/microsoft/net/remote/NetRemoteService.hxx index eaaeee52..84dc0ec0 100644 --- a/src/common/service/include/microsoft/net/remote/NetRemoteService.hxx +++ b/src/common/service/include/microsoft/net/remote/NetRemoteService.hxx @@ -9,12 +9,33 @@ namespace Microsoft::Net::Remote::Service { +/** + * @brief Implementation of the NetRemote::Service gRPC service. + */ class NetRemoteService : public NetRemote::Service { public: + /** + * @brief Construct a new NetRemoteService object. + */ NetRemoteService(); + /** + * @brief Construct a new NetRemoteService object with the specified access point manager. + * + * @param accessPointManager The access point manager to use. + */ + NetRemoteService(std::shared_ptr accessPointManager); + + /** + * @brief Get the AccessPointManager object for this service. + * + * @return std::shared_ptr + */ + std::shared_ptr + GetAccessPointManager() noexcept; + private: virtual ::grpc::Status WifiEnumerateAccessPoints(::grpc::ServerContext* context, const ::Microsoft::Net::Remote::Wifi::WifiEnumerateAccessPointsRequest* request, ::Microsoft::Net::Remote::Wifi::WifiEnumerateAccessPointsResult* response) override; diff --git a/src/common/shared/logging/LogUtils.cxx b/src/common/shared/logging/LogUtils.cxx index c2adf5fe..0d4de50f 100644 --- a/src/common/shared/logging/LogUtils.cxx +++ b/src/common/shared/logging/LogUtils.cxx @@ -22,7 +22,7 @@ logging::GetLogName(std::string_view componentName) } plog::Severity -logging::LogVerbosityToPlogSeverity(uint8_t verbosity) noexcept +logging::LogVerbosityToPlogSeverity(uint32_t verbosity) noexcept { switch (verbosity) { case 0: diff --git a/src/common/shared/logging/include/logging/LogUtils.hxx b/src/common/shared/logging/include/logging/LogUtils.hxx index 6fde5dd7..f486941c 100644 --- a/src/common/shared/logging/include/logging/LogUtils.hxx +++ b/src/common/shared/logging/include/logging/LogUtils.hxx @@ -29,7 +29,7 @@ GetLogName(std::string_view componentName); * @return plog::Severity */ plog::Severity -LogVerbosityToPlogSeverity(uint8_t verbosity) noexcept; +LogVerbosityToPlogSeverity(uint32_t verbosity) noexcept; } // namespace logging diff --git a/src/common/tools/cli/NetRemoteCliHandlerOperations.cxx b/src/common/tools/cli/NetRemoteCliHandlerOperations.cxx index 167d7ada..95122b94 100644 --- a/src/common/tools/cli/NetRemoteCliHandlerOperations.cxx +++ b/src/common/tools/cli/NetRemoteCliHandlerOperations.cxx @@ -29,6 +29,12 @@ NetRemoteCliHandlerOperations::WifiEnumerateAccessPoints() LOGE << std::format("Failed to enumerate WiFi access points, error={} details={} message={}", magic_enum::enum_name(status.error_code()), status.error_details(), status.error_message()); return; } + + LOGI << std::format("{} access points discovered", result.accesspoints_size()); + + for (const auto& accessPoint : result.accesspoints()) { + LOGI << std::format(" - [{}]", accessPoint.accesspointid()); + } } std::unique_ptr diff --git a/src/common/wifi/apmanager/AccessPointDiscoveryAgent.cxx b/src/common/wifi/apmanager/AccessPointDiscoveryAgent.cxx index d7a66c1d..ca4a6787 100644 --- a/src/common/wifi/apmanager/AccessPointDiscoveryAgent.cxx +++ b/src/common/wifi/apmanager/AccessPointDiscoveryAgent.cxx @@ -2,6 +2,7 @@ #include #include #include +#include using namespace Microsoft::Net::Wifi; @@ -39,6 +40,7 @@ AccessPointDiscoveryAgent::DevicePresenceChanged(AccessPointPresenceEvent presen { std::shared_lock onDevicePresenceChangedLock{ m_onDevicePresenceChangedGate }; if (m_onDevicePresenceChanged) { + LOGD << "Access point discovery agent detected a device presence change"; m_onDevicePresenceChanged(presence, std::move(interfaceName)); } } @@ -54,6 +56,7 @@ AccessPointDiscoveryAgent::Start() { bool expected = false; if (m_started.compare_exchange_weak(expected, true)) { + LOGD << "Access point discovery agent starting"; m_operations->Start([weakThis = std::weak_ptr(GetInstance())](auto&& presence, auto&& interfaceName) { // Attempt to promote the weak pointer to a shared pointer to ensure this instance is still valid. if (auto strongThis = weakThis.lock(); strongThis) { @@ -68,6 +71,7 @@ AccessPointDiscoveryAgent::Stop() { bool expected = true; if (m_started.compare_exchange_weak(expected, false)) { + LOGD << "Access point discovery agent stopping"; m_operations->Stop(); } } @@ -75,5 +79,6 @@ AccessPointDiscoveryAgent::Stop() std::future> AccessPointDiscoveryAgent::ProbeAsync() { + LOGD << "Access point discovery agent probing for devices"; return m_operations->ProbeAsync(); } diff --git a/src/common/wifi/apmanager/AccessPointManager.cxx b/src/common/wifi/apmanager/AccessPointManager.cxx index 3f63d4e7..ded12885 100644 --- a/src/common/wifi/apmanager/AccessPointManager.cxx +++ b/src/common/wifi/apmanager/AccessPointManager.cxx @@ -89,6 +89,8 @@ AccessPointManager::AddDiscoveryAgent(std::shared_ptr { using namespace std::chrono_literals; + // Register a discovery event callback. + // // Use a weak_ptr below to ensure that the access point manager can // be safely destroyed prior to the discovery agent. This allows the // callback to be registered indefinitely, safely checking whether this @@ -100,28 +102,25 @@ AccessPointManager::AddDiscoveryAgent(std::shared_ptr } }); - // If this agent has already started, kick off a probe to ensure any access - // points already found will be added to this manager. - std::future> existingAccessPointInterfaceNamesProbe; - const bool isStarted = discoveryAgent->IsStarted(); - if (isStarted) { - existingAccessPointInterfaceNamesProbe = discoveryAgent->ProbeAsync(); - } else { + // Start the agent if not done already. + if (!discoveryAgent->IsStarted()) { discoveryAgent->Start(); } - // If the agent hasn't yet been started, start it now, then probe for - // existing access points in case they've already been discovered. + // Kick off a probe to ensure any access points already present will be added to this manager. + auto existingAccessPointInterfaceNamesProbe = discoveryAgent->ProbeAsync(); + + // Add the agent. { std::unique_lock discoveryAgentLock{ m_discoveryAgentsGate }; m_discoveryAgents.push_back(std::move(discoveryAgent)); } if (existingAccessPointInterfaceNamesProbe.valid()) { - static constexpr auto probeTimeout = 3s; + static constexpr auto ProbeTimeout = 3s; // Wait for the operation to complete. - const auto waitResult = existingAccessPointInterfaceNamesProbe.wait_for(probeTimeout); + const auto waitResult = existingAccessPointInterfaceNamesProbe.wait_for(ProbeTimeout); // If the operation completed, get the results and add those access points. if (waitResult == std::future_status::ready) { diff --git a/src/common/wifi/apmanager/CMakeLists.txt b/src/common/wifi/apmanager/CMakeLists.txt index 850fbf4f..84de0a74 100644 --- a/src/common/wifi/apmanager/CMakeLists.txt +++ b/src/common/wifi/apmanager/CMakeLists.txt @@ -21,6 +21,7 @@ target_sources(wifi-apmanager target_link_libraries(wifi-apmanager PRIVATE notstd + plog::plog PUBLIC ${PROJECT_NAME}-protocol wifi-core diff --git a/src/common/wifi/core/include/microsoft/net/wifi/Ieee80211.hxx b/src/common/wifi/core/include/microsoft/net/wifi/Ieee80211.hxx index ceb6ef03..42eb3830 100644 --- a/src/common/wifi/core/include/microsoft/net/wifi/Ieee80211.hxx +++ b/src/common/wifi/core/include/microsoft/net/wifi/Ieee80211.hxx @@ -3,6 +3,7 @@ #define IEEE_80211_HXX #include +#include namespace Microsoft::Net::Wifi { @@ -81,45 +82,159 @@ enum class IeeeProtocol { BE, }; -enum class IeeeAuthenticationAlgorithm { - Unknown, - Open, - SharedKey, - Wpa, - WpaPsk, - WpaNone, - Rsna, - RsnaPsk, - Wpa3, - Wpa3Enterprise192, - Wpa3Enterprise, - Sae, - Owe, +/** + * @brief OUI for IEEE 802.11 organization. + */ +static constexpr uint32_t OuiIeee80211 = 0x00000FAC; + +/** + * @brief OUI placeholder for signaling invalid values. + */ +static constexpr uint32_t OuiInvalid = 0x00FFFFFF; + +/** + * @brief Helper function to construct an IEEE cipher or AKM suite value. + * + * The OUI is 3 octets and the suite ID is 1 octet. + * + * @param oui The OUI value. + * @param suiteId The suite ID value. + * @return constexpr uint32_t + */ +constexpr uint32_t +MakeIeeeSuite(uint32_t oui, uint8_t suiteId) +{ + constexpr uint32_t OuiShiftAmount = 8; + constexpr uint32_t OuiMask = 0x00FFFFFF; + + return ((oui & OuiMask) << OuiShiftAmount) | suiteId; +} + +/** + * @brief Helper function to construct an IEEE 802.11 cipher suite value. This uses the IEEE 802.11 OUI. + * + * @param suiteId The suite ID value. + * @return constexpr uint32_t + */ +constexpr uint32_t +MakeIeee80211Suite(uint8_t suiteId) +{ + return MakeIeeeSuite(OuiIeee80211, suiteId); +} + +/** + * @brief Authentication algorithms. Each entry denotes a single algorithm, not a suite. + * + * Defined in IEEE 802.11-2020, Section 9.4.1.1, Figure 9-82. + */ +enum class IeeeAuthenticationAlgorithm : uint16_t { + OpenSystem = 0x0001, + SharedKey = 0x0002, + FastBssTransition = 0x0003, + Sae = 0x0004, + Fils = 0x0005, + FilsPfs = 0x0006, + FilsPublicKey = 0x0007, + VendorSpecific = 0xFFFF, }; -constexpr auto Wpa3Enterprise192 = IeeeAuthenticationAlgorithm::Wpa3; -constexpr auto Wpa3Personal = IeeeAuthenticationAlgorithm::Sae; +/** + * @brief AKM suite identifiers or "selectors". + * + * Defined in IEEE 802.11-2020, Section 9.4.2.24.3, Table 9-151. + */ +static constexpr uint8_t IeeeAkmSuiteIdReserved0 = 0; +static constexpr uint8_t IeeeAkmSuiteId8021x = 1; +static constexpr uint8_t IeeeAkmSuiteIdPsk = 2; +static constexpr uint8_t IeeeAkmSuiteIdFt8021x = 3; +static constexpr uint8_t IeeeAkmSuiteIdFtPsk = 4; +static constexpr uint8_t IeeeAkmSuiteId8021xSha256 = 5; +static constexpr uint8_t IeeeAkmSuiteIdPskSha256 = 6; +static constexpr uint8_t IeeeAkmSuiteIdTdls = 7; +static constexpr uint8_t IeeeAkmSuiteIdSae = 8; +static constexpr uint8_t IeeeAkmSuiteIdFtSae = 9; +static constexpr uint8_t IeeeAkmSuiteIdApPeerKey = 10; +static constexpr uint8_t IeeeAkmSuiteId8021xSuiteB = 11; +static constexpr uint8_t IeeeAkmSuiteId8021xSuiteB192 = 12; +static constexpr uint8_t IeeeAkmSuiteIdFt8021xSha384 = 13; +static constexpr uint8_t IeeeAkmSuiteIdFilsSha256 = 14; +static constexpr uint8_t IeeeAkmSuiteIdFilsSha384 = 15; +static constexpr uint8_t IeeeAkmSuiteIdFtFilsSha256 = 16; +static constexpr uint8_t IeeeAkmSuiteIdFtFilsSha384 = 17; +static constexpr uint8_t IeeeAkmSuiteIdOwe = 18; +static constexpr uint8_t IeeeAkmSuiteIdFtPskSha384 = 19; +static constexpr uint8_t IeeeAkmSuiteIdPskSha384 = 20; -enum class IeeeCipherAlgorithm { - Unknown, - None, - Wep, - Wep40, - Wep104, - Tkip, - BipCmac128, - BipGmac128, - BipGmac256, - BipCmac256, - Gcmp128, - Gcmp256, - Ccmp256, - WpaUseGroup, +/** + * @brief IEEE 802.11 Authentication and Key Management (AKM) Suites. + * + * Defined in IEEE 802.11-2020, Section 9.4.2.24.3, Table 9-151. + */ +enum class IeeeAkmSuite : uint32_t { + Reserved0 = MakeIeee80211Suite(IeeeAkmSuiteIdReserved0), + Ieee8021x = MakeIeee80211Suite(IeeeAkmSuiteId8021x), + Psk = MakeIeee80211Suite(IeeeAkmSuiteIdPsk), + Ft8021x = MakeIeee80211Suite(IeeeAkmSuiteIdFt8021x), + FtPsk = MakeIeee80211Suite(IeeeAkmSuiteIdFtPsk), + Ieee8021xSha256 = MakeIeee80211Suite(IeeeAkmSuiteId8021xSha256), + PskSha256 = MakeIeee80211Suite(IeeeAkmSuiteIdPskSha256), + Tdls = MakeIeee80211Suite(IeeeAkmSuiteIdTdls), + Sae = MakeIeee80211Suite(IeeeAkmSuiteIdSae), + FtSae = MakeIeee80211Suite(IeeeAkmSuiteIdFtSae), + ApPeerKey = MakeIeee80211Suite(IeeeAkmSuiteIdApPeerKey), + Ieee8021xSuiteB = MakeIeee80211Suite(IeeeAkmSuiteId8021xSuiteB), + Ieee8011xSuiteB192 = MakeIeee80211Suite(IeeeAkmSuiteId8021xSuiteB192), + Ft8021xSha384 = MakeIeee80211Suite(IeeeAkmSuiteIdFt8021xSha384), + FilsSha256 = MakeIeee80211Suite(IeeeAkmSuiteIdFilsSha256), + FilsSha284 = MakeIeee80211Suite(IeeeAkmSuiteIdFilsSha384), + FtFilsSha256 = MakeIeee80211Suite(IeeeAkmSuiteIdFtFilsSha256), + FtFilsSha384 = MakeIeee80211Suite(IeeeAkmSuiteIdFtFilsSha384), + Owe = MakeIeee80211Suite(IeeeAkmSuiteIdOwe), + FtPskSha384 = MakeIeee80211Suite(IeeeAkmSuiteIdFtPskSha384), + PskSha384 = MakeIeee80211Suite(IeeeAkmSuiteIdPskSha384), }; -constexpr auto Bip = IeeeCipherAlgorithm::BipCmac128; -constexpr auto Gcmp = IeeeCipherAlgorithm::Gcmp128; -constexpr auto RsnUseGroup = IeeeCipherAlgorithm::WpaUseGroup; +/** + * @brief Cipher suite identifiers or "selectors". + * + * Defined in IEEE 802.11-2020, Section 9.4.2.24.2, Table 9-149. + */ +static constexpr uint8_t Ieee80211CipherSuiteIdUseGroup = 0; +static constexpr uint8_t Ieee80211CipherSuiteIdWep40 = 1; +static constexpr uint8_t Ieee80211CipherSuiteIdTkip = 2; +static constexpr uint8_t Ieee80211CipherSuiteIdReserved = 3; +static constexpr uint8_t Ieee80211CipherSuiteCcmp128 = 4; +static constexpr uint8_t Ieee80211CipherSuiteIdWep104 = 5; +static constexpr uint8_t Ieee80211CipherSuiteIdBipCmac128 = 6; +static constexpr uint8_t Ieee80211CipherSuiteIdGroupAddressTrafficNotAllowed = 7; +static constexpr uint8_t Ieee80211CipherSuiteIdGcmp128 = 8; +static constexpr uint8_t Ieee80211CipherSuiteIdGcmp256 = 9; +static constexpr uint8_t Ieee80211CipherSuiteIdCcmp256 = 10; +static constexpr uint8_t Ieee80211CipherSuiteIdBipGmac128 = 11; +static constexpr uint8_t Ieee80211CipherSuiteIdBipGmac256 = 12; +static constexpr uint8_t Ieee80211CipherSuiteIdBipCmac256 = 13; + +/** + * @brief IEEE 802.11 Cipher Suites. + * + * Defined in IEEE 802.11-2020, Section 9.4.2.24.2, Table 9-149. + */ +enum class IeeeCipherSuite : uint32_t { + Unknown = MakeIeeeSuite(OuiInvalid, 0), + BipCmac128 = MakeIeee80211Suite(Ieee80211CipherSuiteIdBipCmac128), + BipCmac256 = MakeIeee80211Suite(Ieee80211CipherSuiteIdBipCmac256), + BipGmac128 = MakeIeee80211Suite(Ieee80211CipherSuiteIdBipGmac128), + BipGmac256 = MakeIeee80211Suite(Ieee80211CipherSuiteIdBipGmac256), + Ccmp128 = MakeIeee80211Suite(Ieee80211CipherSuiteCcmp128), + Ccmp256 = MakeIeee80211Suite(Ieee80211CipherSuiteIdCcmp256), + Gcmp128 = MakeIeee80211Suite(Ieee80211CipherSuiteIdGcmp128), + Gcmp256 = MakeIeee80211Suite(Ieee80211CipherSuiteIdGcmp256), + GroupAddressesTrafficNotAllowed = MakeIeee80211Suite(Ieee80211CipherSuiteIdGroupAddressTrafficNotAllowed), + Tkip = MakeIeee80211Suite(Ieee80211CipherSuiteIdTkip), + UseGroup = MakeIeee80211Suite(Ieee80211CipherSuiteIdUseGroup), + Wep104 = MakeIeee80211Suite(Ieee80211CipherSuiteIdWep104), + Wep40 = MakeIeee80211Suite(Ieee80211CipherSuiteIdWep40), +}; } // namespace Microsoft::Net::Wifi diff --git a/src/linux/server/CMakeLists.txt b/src/linux/server/CMakeLists.txt index 8577ab14..abcc3323 100644 --- a/src/linux/server/CMakeLists.txt +++ b/src/linux/server/CMakeLists.txt @@ -8,10 +8,11 @@ target_sources(${PROJECT_NAME}-server-linux target_link_libraries(${PROJECT_NAME}-server-linux PRIVATE - logging-utils ${PROJECT_NAME}-server + logging-utils notstd plog::plog + wifi-apmanager-linux ) set_target_properties(${PROJECT_NAME}-server-linux diff --git a/src/linux/server/Main.cxx b/src/linux/server/Main.cxx index ac21025c..e9e3d28d 100644 --- a/src/linux/server/Main.cxx +++ b/src/linux/server/Main.cxx @@ -5,6 +5,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -16,6 +19,10 @@ using namespace Microsoft::Net::Remote; +using Microsoft::Net::Wifi::AccessPointDiscoveryAgent; +using Microsoft::Net::Wifi::AccessPointDiscoveryAgentOperationsNetlink; +using Microsoft::Net::Wifi::AccessPointManager; + enum class LogInstanceId : int { // Default logger is 0 and is omitted from this enumeration. Console = 1, @@ -23,14 +30,14 @@ enum class LogInstanceId : int { }; int -main(int argc, char* argv[]) +main(int argc, char *argv[]) { // Create file and console log appenders. static plog::ColorConsoleAppender colorConsoleAppender{}; static plog::RollingFileAppender rollingFileAppender(logging::GetLogName("server").c_str()); // Parse command line arguments. - const auto configuration = NetRemoteServerConfiguration::FromCommandLineArguments(argc, argv); + auto configuration = NetRemoteServerConfiguration::FromCommandLineArguments(argc, argv); const auto logSeverity = logging::LogVerbosityToPlogSeverity(configuration.LogVerbosity); // Configure logging, appending all loggers to the default instance. @@ -40,8 +47,21 @@ main(int argc, char* argv[]) .addAppender(plog::get()) .addAppender(plog::get()); + // Create an access point manager and discovery agent. + { + configuration.AccessPointManager = AccessPointManager::Create(); + + auto &accessPointManager = configuration.AccessPointManager; + auto accessPointDiscoveryAgentOperationsNetlink = std::make_unique(); + auto accessPointDiscoveryAgent = AccessPointDiscoveryAgent::Create(std::move(accessPointDiscoveryAgentOperationsNetlink)); + accessPointManager->AddDiscoveryAgent(std::move(accessPointDiscoveryAgent)); + } + + // Create the server. + NetRemoteServer server{ std::move(configuration) }; + // Start the server. - NetRemoteServer server{ configuration.ServerAddress }; + LOGI << "Netremote server starting"; server.Run(); // If running in the background, daemonize the process. @@ -51,8 +71,8 @@ main(int argc, char* argv[]) if (daemon(nochdir, noclose) != 0) { const int error = errno; - const auto what = std::format("failed to daemonize (error={})", error); - LOG_ERROR << what; + const auto what = std::format("Failed to daemonize (error={})", error); + LOGE << what; throw std::runtime_error(what); } } @@ -61,7 +81,7 @@ main(int argc, char* argv[]) server.GetGrpcServer()->Wait(); } - LOG_INFO << "Server exiting."; + LOGI << "Netremote server stopping"; return 0; } diff --git a/tests/unit/TestNetRemoteServer.cxx b/tests/unit/TestNetRemoteServer.cxx index 306d1113..b7fa6ec2 100644 --- a/tests/unit/TestNetRemoteServer.cxx +++ b/tests/unit/TestNetRemoteServer.cxx @@ -12,10 +12,16 @@ TEST_CASE("Create a NetRemoteServer instance", "[basic][rpc][remote]") { using namespace Microsoft::Net::Remote; + using namespace Microsoft::Net::Wifi; + + NetRemoteServerConfiguration Configuration{ + .ServerAddress = Test::RemoteServiceAddressHttp, + .AccessPointManager = AccessPointManager::Create(), + }; SECTION("Create doesn't cause a crash") { - REQUIRE_NOTHROW(NetRemoteServer{ Test::RemoteServiceAddressHttp }); + REQUIRE_NOTHROW(NetRemoteServer{ Configuration }); } } @@ -23,8 +29,14 @@ TEST_CASE("Destroy a NetRemoteServer instance", "[basic][rpc][remote]") { using namespace Microsoft::Net::Remote; using namespace Microsoft::Net::Remote::Service; + using namespace Microsoft::Net::Wifi; + + NetRemoteServerConfiguration Configuration{ + .ServerAddress = Test::RemoteServiceAddressHttp, + .AccessPointManager = AccessPointManager::Create(), + }; - std::optional server{ Test::RemoteServiceAddressHttp }; + std::optional server{ Configuration }; server->Run(); SECTION("Destroy doesn't cause a crash") @@ -48,8 +60,14 @@ TEST_CASE("NetRemoteServer can be reached", "[basic][rpc][remote]") { using namespace Microsoft::Net::Remote; using namespace Microsoft::Net::Remote::Service; + using namespace Microsoft::Net::Wifi; + + NetRemoteServerConfiguration Configuration{ + .ServerAddress = Test::RemoteServiceAddressHttp, + .AccessPointManager = AccessPointManager::Create(), + }; - NetRemoteServer server{ Test::RemoteServiceAddressHttp }; + NetRemoteServer server{ Configuration }; server.Run(); SECTION("Can be reached using insecure channel") @@ -65,8 +83,14 @@ TEST_CASE("NetRemoteServer shuts down correctly", "[basic][rpc][remote]") { using namespace Microsoft::Net::Remote; using namespace Microsoft::Net::Remote::Service; + using namespace Microsoft::Net::Wifi; - NetRemoteServer server{ Test::RemoteServiceAddressHttp }; + NetRemoteServerConfiguration Configuration{ + .ServerAddress = Test::RemoteServiceAddressHttp, + .AccessPointManager = AccessPointManager::Create(), + }; + + NetRemoteServer server{ Configuration }; server.Run(); SECTION("Stop() doesn't cause a crash with no connected clients") @@ -114,8 +138,14 @@ TEST_CASE("NetRemoteServer can be cycled through run/stop states", "[basic][rpc] { using namespace Microsoft::Net::Remote; using namespace Microsoft::Net::Remote::Service; + using namespace Microsoft::Net::Wifi; + + NetRemoteServerConfiguration Configuration{ + .ServerAddress = Test::RemoteServiceAddressHttp, + .AccessPointManager = AccessPointManager::Create(), + }; - NetRemoteServer server{ Test::RemoteServiceAddressHttp }; + NetRemoteServer server{ Configuration }; REQUIRE_NOTHROW(server.Run()); SECTION("Can be cycled multiple times") diff --git a/tests/unit/TestNetRemoteServiceClient.cxx b/tests/unit/TestNetRemoteServiceClient.cxx index caa30b02..b5bf6136 100644 --- a/tests/unit/TestNetRemoteServiceClient.cxx +++ b/tests/unit/TestNetRemoteServiceClient.cxx @@ -9,6 +9,7 @@ #include #include #include +#include #include "TestNetRemoteCommon.hxx" @@ -17,8 +18,14 @@ TEST_CASE("WifiEnumerateAccessPoints API", "[basic][rpc][client][remote]") using namespace Microsoft::Net::Remote; using namespace Microsoft::Net::Remote::Service; using namespace Microsoft::Net::Remote::Wifi; + using namespace Microsoft::Net::Wifi; + + NetRemoteServerConfiguration Configuration{ + .ServerAddress = Test::RemoteServiceAddressHttp, + .AccessPointManager = AccessPointManager::Create(), + }; - NetRemoteServer server{ Test::RemoteServiceAddressHttp }; + NetRemoteServer server{ Configuration }; server.Run(); auto channel = grpc::CreateChannel(Test::RemoteServiceAddressHttp, grpc::InsecureChannelCredentials()); @@ -63,7 +70,12 @@ TEST_CASE("WifiAccessPointEnable API", "[basic][rpc][client][remote]") constexpr auto SsidName{ "TestWifiAccessPointEnable" }; - NetRemoteServer server{ Test::RemoteServiceAddressHttp }; + NetRemoteServerConfiguration Configuration{ + .ServerAddress = Test::RemoteServiceAddressHttp, + .AccessPointManager = AccessPointManager::Create(), + }; + + NetRemoteServer server{ Configuration }; server.Run(); auto channel = grpc::CreateChannel(Test::RemoteServiceAddressHttp, grpc::InsecureChannelCredentials());