diff --git a/src/common/tools/cli/NetRemoteCli.cxx b/src/common/tools/cli/NetRemoteCli.cxx index 0048eb86..0011a265 100644 --- a/src/common/tools/cli/NetRemoteCli.cxx +++ b/src/common/tools/cli/NetRemoteCli.cxx @@ -1,11 +1,13 @@ #include +#include #include #include #include #include #include +#include #include #include #include @@ -98,7 +100,7 @@ NetRemoteCli::AddSubcommandWifiAccessPointsEnumerate(CLI::App* parent) { auto* cliAppWifiAccessPointsEnumerate = parent->add_subcommand("enumerate-access-points", "Enumerate available Wi-Fi access points"); cliAppWifiAccessPointsEnumerate->add_flag("--detailed", m_cliData->DetailedOutput, "Show detailed information about each access point"); - cliAppWifiAccessPointsEnumerate->alias("enumaps"); + cliAppWifiAccessPointsEnumerate->alias("enumaps")->alias("enum")->alias("aps"); cliAppWifiAccessPointsEnumerate->callback([this] { OnWifiAccessPointsEnumerate(m_cliData->DetailedOutput.value_or(false)); }); @@ -109,13 +111,33 @@ NetRemoteCli::AddSubcommandWifiAccessPointsEnumerate(CLI::App* parent) CLI::App* NetRemoteCli::AddSubcommandWifiAccessPointEnable(CLI::App* parent) { + const std::map Ieee80211PhyTypeNames{ + { "a", Ieee80211PhyType::A }, + { "b", Ieee80211PhyType::B }, + { "g", Ieee80211PhyType::G }, + { "n", Ieee80211PhyType::N }, + { "ac", Ieee80211PhyType::AC }, + { "ax", Ieee80211PhyType::AX }, + }; + auto* cliAppWifiAccessPointEnable = parent->add_subcommand("access-point-enable", "Enable a Wi-Fi access point"); - cliAppWifiAccessPointEnable->alias("ap-enable"); + cliAppWifiAccessPointEnable->alias("ap-enable")->alias("enable")->alias("ap-en"); cliAppWifiAccessPointEnable->callback([this] { - OnWifiAccessPointEnable(); + Ieee80211AccessPointConfiguration ieee80211AccessPointConfiguration{}; + if (!std::empty(m_cliData->WifiAccessPointSsid)) { + ieee80211AccessPointConfiguration.Ssid = m_cliData->WifiAccessPointSsid; + } + if (m_cliData->WifiAccessPointPhyType != Ieee80211PhyType::Unknown) { + ieee80211AccessPointConfiguration.PhyType = m_cliData->WifiAccessPointPhyType; + } + + OnWifiAccessPointEnable(m_cliData->WifiAccessPointId, &ieee80211AccessPointConfiguration); }); cliAppWifiAccessPointEnable->add_option("id", m_cliData->WifiAccessPointId, "The identifier of the access point to enable")->required(); + cliAppWifiAccessPointEnable->add_option("--ssid", m_cliData->WifiAccessPointSsid, "The SSID of the access point to enable"); + cliAppWifiAccessPointEnable->add_option("--phy,--phyType,", m_cliData->WifiAccessPointPhyType, "The PHY type of the access point to enable") + ->transform(CLI::CheckedTransformer(Ieee80211PhyTypeNames, CLI::ignore_case)); return cliAppWifiAccessPointEnable; } @@ -124,9 +146,9 @@ CLI::App* NetRemoteCli::AddSubcommandWifiAccessPointDisable(CLI::App* parent) { auto* cliAppWifiAccessPointDisable = parent->add_subcommand("access-point-disable", "Disable a Wi-Fi access point"); - cliAppWifiAccessPointDisable->alias("ap-disable"); + cliAppWifiAccessPointDisable->alias("ap-disable")->alias("disable")->alias("ap-dis"); cliAppWifiAccessPointDisable->callback([this] { - OnWifiAccessPointEnable(); + OnWifiAccessPointDisable(m_cliData->WifiAccessPointId); }); cliAppWifiAccessPointDisable->add_option("id", m_cliData->WifiAccessPointId, "The identifier of the access point to disable")->required(); @@ -163,13 +185,13 @@ NetRemoteCli::OnWifiAccessPointsEnumerate(bool detailedOutput) } void -NetRemoteCli::OnWifiAccessPointEnable(const Ieee80211AccessPointConfiguration* ieee80211AccessPointConfiguration) +NetRemoteCli::OnWifiAccessPointEnable(std::string_view accessPointId, const Ieee80211AccessPointConfiguration* ieee80211AccessPointConfiguration) { - m_cliHandler->HandleCommandWifiAccessPointEnable(m_cliData->WifiAccessPointId, ieee80211AccessPointConfiguration); + m_cliHandler->HandleCommandWifiAccessPointEnable(accessPointId, ieee80211AccessPointConfiguration); } void -NetRemoteCli::OnWifiAccessPointDisable() +NetRemoteCli::OnWifiAccessPointDisable(std::string_view accessPointId) { - m_cliHandler->HandleCommandWifiAccessPointDisable(m_cliData->WifiAccessPointId); + m_cliHandler->HandleCommandWifiAccessPointDisable(accessPointId); } diff --git a/src/common/tools/cli/include/microsoft/net/remote/NetRemoteCli.hxx b/src/common/tools/cli/include/microsoft/net/remote/NetRemoteCli.hxx index cc9794a8..5e83a12b 100644 --- a/src/common/tools/cli/include/microsoft/net/remote/NetRemoteCli.hxx +++ b/src/common/tools/cli/include/microsoft/net/remote/NetRemoteCli.hxx @@ -132,16 +132,19 @@ private: /** * @brief Handle the 'wifi ap-enable' command. * + * @param accessPointId The identifier of the access point to enable. * @param ieee80211AccessPointConfiguration Optional configuration for the access point to enable. */ void - OnWifiAccessPointEnable(const Microsoft::Net::Wifi::Ieee80211AccessPointConfiguration* ieee80211AccessPointConfiguration = nullptr); + OnWifiAccessPointEnable(std::string_view accessPointId, const Microsoft::Net::Wifi::Ieee80211AccessPointConfiguration* ieee80211AccessPointConfiguration = nullptr); /** * @brief Handle the 'wifi ap-disable' command. + * + * @param accessPointId The identifier of the access point to disable. */ void - OnWifiAccessPointDisable(); + OnWifiAccessPointDisable(std::string_view accessPointId); private: std::shared_ptr m_cliData; diff --git a/src/common/tools/cli/include/microsoft/net/remote/NetRemoteCliData.hxx b/src/common/tools/cli/include/microsoft/net/remote/NetRemoteCliData.hxx index 1e1f1b5d..e42dfb78 100644 --- a/src/common/tools/cli/include/microsoft/net/remote/NetRemoteCliData.hxx +++ b/src/common/tools/cli/include/microsoft/net/remote/NetRemoteCliData.hxx @@ -6,6 +6,7 @@ #include #include +#include namespace Microsoft::Net::Remote { @@ -21,6 +22,8 @@ struct NetRemoteCliData std::optional DetailedOutput; std::string WifiAccessPointId{}; + std::string WifiAccessPointSsid{}; + Microsoft::Net::Wifi::Ieee80211PhyType WifiAccessPointPhyType{ Microsoft::Net::Wifi::Ieee80211PhyType::Unknown }; }; } // namespace Microsoft::Net::Remote diff --git a/src/linux/libnl-helpers/Netlink80211.cxx b/src/linux/libnl-helpers/Netlink80211.cxx index 887f842f..0f321da3 100644 --- a/src/linux/libnl-helpers/Netlink80211.cxx +++ b/src/linux/libnl-helpers/Netlink80211.cxx @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -425,36 +426,12 @@ Nl80211CommandToString(nl80211_commands command) noexcept std::string_view Nl80211InterfaceTypeToString(nl80211_iftype interfaceType) noexcept { - switch (interfaceType) { - case NL80211_IFTYPE_UNSPECIFIED: - return "NL80211_IFTYPE_UNSPECIFIED"; - case NL80211_IFTYPE_ADHOC: - return "NL80211_IFTYPE_ADHOC"; - case NL80211_IFTYPE_STATION: - return "NL80211_IFTYPE_STATION"; - case NL80211_IFTYPE_AP: - return "NL80211_IFTYPE_AP"; - case NL80211_IFTYPE_AP_VLAN: - return "NL80211_IFTYPE_AP_VLAN"; - case NL80211_IFTYPE_WDS: - return "NL80211_IFTYPE_WDS"; - case NL80211_IFTYPE_MONITOR: - return "NL80211_IFTYPE_MONITOR"; - case NL80211_IFTYPE_MESH_POINT: - return "NL80211_IFTYPE_MESH_POINT"; - case NL80211_IFTYPE_P2P_CLIENT: - return "NL80211_IFTYPE_P2P_CLIENT"; - case NL80211_IFTYPE_P2P_GO: - return "NL80211_IFTYPE_P2P_GO"; - case NL80211_IFTYPE_P2P_DEVICE: - return "NL80211_IFTYPE_P2P_DEVICE"; - case NL80211_IFTYPE_OCB: - return "NL80211_IFTYPE_OCB"; - case NL80211_IFTYPE_NAN: - return "NL80211_IFTYPE_NAN"; - default: - return "NL80211_IFTYPE_UNKNOWN"; - } + static constexpr auto InterfaceTypePrefixLength{ std::size(std::string_view("NL80211_IFTYPE_")) }; + + auto interfaceTypeName{ magic_enum::enum_name(interfaceType) }; + interfaceTypeName.remove_prefix(InterfaceTypePrefixLength); + + return interfaceTypeName; } std::string_view diff --git a/src/linux/libnl-helpers/Netlink80211Interface.cxx b/src/linux/libnl-helpers/Netlink80211Interface.cxx index cfebcb23..ed909b8e 100644 --- a/src/linux/libnl-helpers/Netlink80211Interface.cxx +++ b/src/linux/libnl-helpers/Netlink80211Interface.cxx @@ -1,7 +1,10 @@ + +#include #include #include #include #include +#include #include #include #include @@ -41,7 +44,12 @@ Nl80211Interface::Nl80211Interface(std::string_view name, nl80211_iftype type, u std::string Nl80211Interface::ToString() const { - return std::format("[{}/{}] {} {}", Index, WiphyIndex, Name, magic_enum::enum_name(Type)); + static constexpr auto InterfaceTypePrefixLength{ std::size(std::string_view("NL80211_IFTYPE_")) }; + + auto interfaceType = std::string_view{ magic_enum::enum_name(Type) }; + interfaceType.remove_prefix(InterfaceTypePrefixLength); + + return std::format("[{}/{}] {} {}", Index, WiphyIndex, Name, interfaceType); } /* static */ @@ -65,18 +73,18 @@ Nl80211Interface::Parse(struct nl_msg *nl80211Message) noexcept const auto *genl80211MessageHeader{ static_cast(nlmsg_data(nl80211MessageHeader)) }; // Parse the message. - std::array newInterfaceMessageAttributes{}; - int ret = nla_parse(std::data(newInterfaceMessageAttributes), std::size(newInterfaceMessageAttributes) - 1, genlmsg_attrdata(genl80211MessageHeader, 0), genlmsg_attrlen(genl80211MessageHeader, 0), nullptr); + std::array interfaceMessageAttributes{}; + int ret = nla_parse(std::data(interfaceMessageAttributes), std::size(interfaceMessageAttributes) - 1, genlmsg_attrdata(genl80211MessageHeader, 0), genlmsg_attrlen(genl80211MessageHeader, 0), nullptr); if (ret < 0) { LOGE << std::format("Failed to parse netlink message attributes with error {} ({})", ret, strerror(-ret)); return std::nullopt; } // Tease out parameters to populate the Nl80211Interface instance. - const auto *interfaceName = static_cast(nla_data(newInterfaceMessageAttributes[NL80211_ATTR_IFNAME])); - auto interfaceType = static_cast(nla_get_u32(newInterfaceMessageAttributes[NL80211_ATTR_IFTYPE])); - auto interfaceIndex = static_cast(nla_get_u32(newInterfaceMessageAttributes[NL80211_ATTR_IFINDEX])); - auto wiphyIndex = static_cast(nla_get_u32(newInterfaceMessageAttributes[NL80211_ATTR_WIPHY])); + const auto *interfaceName = static_cast(nla_data(interfaceMessageAttributes[NL80211_ATTR_IFNAME])); + auto interfaceType = static_cast(nla_get_u32(interfaceMessageAttributes[NL80211_ATTR_IFTYPE])); + auto interfaceIndex = static_cast(nla_get_u32(interfaceMessageAttributes[NL80211_ATTR_IFINDEX])); + auto wiphyIndex = static_cast(nla_get_u32(interfaceMessageAttributes[NL80211_ATTR_WIPHY])); return Nl80211Interface(interfaceName, interfaceType, interfaceIndex, wiphyIndex); } @@ -169,7 +177,17 @@ Nl80211Interface::GetWiphy() const bool Nl80211Interface::IsAccessPoint() const noexcept { - return (Type == nl80211_iftype::NL80211_IFTYPE_AP); + return std::ranges::contains(Nl80211AccessPointInterfaceTypes, Type); +} + +bool +Nl80211Interface::SupportsAccessPointMode() const noexcept +{ + // clang-format off + return GetWiphy().transform([](const Nl80211Wiphy &wiphy) { + return std::ranges::find_first_of(wiphy.SupportedInterfaceTypes, Nl80211AccessPointInterfaceTypes) != std::cend(wiphy.SupportedInterfaceTypes); + }).value_or(false); + // clang-format on } // NOLINTEND(concurrency-mt-unsafe) diff --git a/src/linux/libnl-helpers/include/microsoft/net/netlink/nl80211/Netlink80211.hxx b/src/linux/libnl-helpers/include/microsoft/net/netlink/nl80211/Netlink80211.hxx index 11d414a3..792588c5 100644 --- a/src/linux/libnl-helpers/include/microsoft/net/netlink/nl80211/Netlink80211.hxx +++ b/src/linux/libnl-helpers/include/microsoft/net/netlink/nl80211/Netlink80211.hxx @@ -3,6 +3,7 @@ #define NETLINK_82011_HXX #include +#include #include #include @@ -32,6 +33,14 @@ static const std::unordered_map Nl80211 }; // NOLINTEND(cert-err58-cpp) +/** + * @brief List of interface types that indicate support for access point operation. + */ +constexpr std::initializer_list Nl80211AccessPointInterfaceTypes = { + nl80211_iftype::NL80211_IFTYPE_AP, + nl80211_iftype::NL80211_IFTYPE_AP_VLAN, +}; + /** * @brief Convert an nl80211_commands enum value to a string. * diff --git a/src/linux/libnl-helpers/include/microsoft/net/netlink/nl80211/Netlink80211Interface.hxx b/src/linux/libnl-helpers/include/microsoft/net/netlink/nl80211/Netlink80211Interface.hxx index 175fbf69..831c98fe 100644 --- a/src/linux/libnl-helpers/include/microsoft/net/netlink/nl80211/Netlink80211Interface.hxx +++ b/src/linux/libnl-helpers/include/microsoft/net/netlink/nl80211/Netlink80211Interface.hxx @@ -85,6 +85,15 @@ struct Nl80211Interface */ bool IsAccessPoint() const noexcept; + + /** + * @brief Indicates if the interface supports operating as an access point. + * + * @return true The interface can be used as an access point. + * @return false The interface cannot be used as an access point. + */ + bool + SupportsAccessPointMode() const noexcept; }; } // namespace Microsoft::Net::Netlink::Nl80211 diff --git a/src/linux/wifi/apmanager/AccessPointDiscoveryAgentOperationsNetlink.cxx b/src/linux/wifi/apmanager/AccessPointDiscoveryAgentOperationsNetlink.cxx index 0523ccdf..caab5d14 100644 --- a/src/linux/wifi/apmanager/AccessPointDiscoveryAgentOperationsNetlink.cxx +++ b/src/linux/wifi/apmanager/AccessPointDiscoveryAgentOperationsNetlink.cxx @@ -128,16 +128,16 @@ AccessPointDiscoveryAgentOperationsNetlink::Stop() namespace detail { /** - * @brief Helper function to determine if an nl80211 interface is an AP. To be used in range expressions. + * @brief Helper function to determine if an nl80211 interface supports interface mode. To be used in range expressions. * * @param nl80211Interface The nl80211 interface to check. * @return true * @return false */ bool -IsNl80211InterfaceTypeAp(const Nl80211Interface &nl80211Interface) +InterfaceSupportsAccessPointMode(const Nl80211Interface &nl80211Interface) { - return (nl80211Interface.Type == nl80211_iftype::NL80211_IFTYPE_AP); + return nl80211Interface.SupportsAccessPointMode(); } /** @@ -158,7 +158,7 @@ MakeAccessPoint(const std::shared_ptr &accessPointFacto std::future>> AccessPointDiscoveryAgentOperationsNetlink::ProbeAsync() { - const auto MakeAccessPoint = [this](const Nl80211Interface &nl80211Interface) { + const auto ToAccessPoint = [this](const Nl80211Interface &nl80211Interface) { return detail::MakeAccessPoint(m_accessPointFactory, nl80211Interface); }; @@ -167,7 +167,7 @@ AccessPointDiscoveryAgentOperationsNetlink::ProbeAsync() // Enumerate all nl80211 interfaces and filter out those that are not APs. auto nl80211Interfaces{ Nl80211Interface::Enumerate() }; - auto accessPointsView = nl80211Interfaces | std::views::filter(detail::IsNl80211InterfaceTypeAp) | std::views::transform(MakeAccessPoint); + auto accessPointsView = nl80211Interfaces | std::views::filter(detail::InterfaceSupportsAccessPointMode) | std::views::transform(ToAccessPoint); std::vector> accessPoints(std::make_move_iterator(std::begin(accessPointsView)), std::make_move_iterator(std::end(accessPointsView))); // Clear the vector since most of the items were moved out. @@ -200,63 +200,40 @@ AccessPointDiscoveryAgentOperationsNetlink::ProcessNetlinkMessage(struct nl_msg return NL_SKIP; } - if (genlMessageHeader->cmd != NL80211_CMD_NEW_INTERFACE && - genlMessageHeader->cmd != NL80211_CMD_DEL_INTERFACE && - genlMessageHeader->cmd != NL80211_CMD_SET_INTERFACE) { - LOGD << std::format("Ignoring {} nl80211 command message", nl80211CommandName); - return NL_SKIP; - } - LOGD << std::format("Received {} nl80211 command message", nl80211CommandName); - // Parse the message into an Nl80211Interface object. - auto nl80211InterfaceOpt = Nl80211Interface::Parse(netlinkMessage); - if (!nl80211InterfaceOpt.has_value()) { - LOGE << "Failed to parse nl80211 interface dump response"; - return NL_OK; - } - AccessPointPresenceEvent accessPointPresenceEvent{}; - auto &nl80211Interface = nl80211InterfaceOpt.value(); switch (genlMessageHeader->cmd) { case NL80211_CMD_NEW_INTERFACE: case NL80211_CMD_DEL_INTERFACE: { - if (!nl80211Interface.IsAccessPoint()) { - LOGD << std::format("Ignoring interface presence change nl80211 message for non-ap wi-fi interface (type={})", Nl80211InterfaceTypeToString(nl80211Interface.Type)); - return NL_OK; - } accessPointPresenceEvent = (genlMessageHeader->cmd == NL80211_CMD_NEW_INTERFACE) ? AccessPointPresenceEvent::Arrived : AccessPointPresenceEvent::Departed; break; } - case NL80211_CMD_SET_INTERFACE: { - accessPointPresenceEvent = nl80211Interface.IsAccessPoint() ? AccessPointPresenceEvent::Arrived : AccessPointPresenceEvent::Departed; - break; - } default: { LOGD << std::format("Ignoring {} nl80211 command message", nl80211CommandName); return NL_SKIP; } } - // Update interface seen cache, handling the case where the interface has already been seen. This happens for - // NL80211_CMD_SET_INTERFACE whern the interface type did not change. - auto interfaceSeenIterator = m_interfacesSeen.find(nl80211Interface); - if (interfaceSeenIterator == std::cend(m_interfacesSeen)) { - if (accessPointPresenceEvent == AccessPointPresenceEvent::Arrived) { - m_interfacesSeen.insert(nl80211Interface); - } - } else { - if (accessPointPresenceEvent == AccessPointPresenceEvent::Departed) { - m_interfacesSeen.erase(interfaceSeenIterator); - } + // Parse the message into an Nl80211Interface object. + auto nl80211Interface = Nl80211Interface::Parse(netlinkMessage); + if (!nl80211Interface.has_value()) { + LOGE << "Failed to parse nl80211 interface dump response"; + return NL_OK; + } + + // Ignore the interface if it doesn't support AP mode. + if (!nl80211Interface->SupportsAccessPointMode()) { + LOGD << std::format("Ignoring nl80211 interface presence change message for {} interface (type={}) which does not support AP mode", nl80211Interface->Name, Nl80211InterfaceTypeToString(nl80211Interface->Type)); + return NL_OK; } // Invoke presence event callback if present. if (accessPointPresenceEventCallback != nullptr) { - const auto interfaceName{ nl80211Interface.Name }; + const auto interfaceName{ nl80211Interface->Name }; LOGD << std::format("Invoking access point presence event callback with event args 'interface={}, presence={}'", interfaceName, magic_enum::enum_name(accessPointPresenceEvent)); - auto accessPointCreateArgs = std::make_unique(std::move(nl80211Interface)); + auto accessPointCreateArgs = std::make_unique(std::move(nl80211Interface.value())); auto accessPoint = m_accessPointFactory->Create(interfaceName, std::move(accessPointCreateArgs)); accessPointPresenceEventCallback(accessPointPresenceEvent, accessPoint); diff --git a/src/linux/wifi/apmanager/include/microsoft/net/wifi/AccessPointDiscoveryAgentOperationsNetlink.hxx b/src/linux/wifi/apmanager/include/microsoft/net/wifi/AccessPointDiscoveryAgentOperationsNetlink.hxx index 1d7d9c2f..23cec943 100644 --- a/src/linux/wifi/apmanager/include/microsoft/net/wifi/AccessPointDiscoveryAgentOperationsNetlink.hxx +++ b/src/linux/wifi/apmanager/include/microsoft/net/wifi/AccessPointDiscoveryAgentOperationsNetlink.hxx @@ -7,7 +7,6 @@ #include #include #include -#include #include #include @@ -126,7 +125,6 @@ private: int m_eventLoopStopFd{ -1 }; std::jthread m_netlinkMessageProcessingThread; - std::unordered_set m_interfacesSeen; Microsoft::Net::Netlink::Nl80211::Nl80211ProtocolState &m_netlink80211ProtocolState; }; } // namespace Microsoft::Net::Wifi diff --git a/src/linux/wifi/core/AccessPointControllerLinux.cxx b/src/linux/wifi/core/AccessPointControllerLinux.cxx index b1b42471..9927690a 100644 --- a/src/linux/wifi/core/AccessPointControllerLinux.cxx +++ b/src/linux/wifi/core/AccessPointControllerLinux.cxx @@ -3,7 +3,6 @@ #include #include #include -#include #include #include #include @@ -172,10 +171,8 @@ AccessPointControllerLinux::SetPhyType(Ieee80211PhyType ieeePhyType) noexcept break; } - std::optional errorDetails; std::string_view propertyKeyToSet; std::string_view propertyValueToSet; - bool hostapdOperationSucceeded{ false }; // Attempt to set all required properties. try { @@ -184,13 +181,8 @@ AccessPointControllerLinux::SetPhyType(Ieee80211PhyType ieeePhyType) noexcept m_hostapd.SetProperty(propertyKeyToSet, propertyValueToSet, EnforceConfigurationChange::Defer); } } catch (const Wpa::HostapdException& ex) { - hostapdOperationSucceeded = false; - errorDetails = ex.what(); - } - - if (!hostapdOperationSucceeded) { status.Code = AccessPointOperationStatusCode::InternalError; - status.Details = std::format("failed to set hostapd property '{}' to '{}' - {}", propertyKeyToSet, propertyValueToSet, errorDetails.value_or("unspecified error")); + status.Details = std::format("failed to set hostapd property '{}' to '{}' - {}", propertyKeyToSet, propertyValueToSet, ex.what()); return status; } @@ -231,8 +223,6 @@ AccessPointControllerLinux::SetFrequencyBands(std::vector errorDetails{}; std::string_view propertyKeyToSet{ Wpa::ProtocolHostapd::PropertyNameSetBand }; std::string_view propertyValueToSet{ setBandArgument }; @@ -240,13 +230,8 @@ AccessPointControllerLinux::SetFrequencyBands(std::vector errorDetails{}; - // Attempt to set the SSID. try { m_hostapd.SetProperty(Wpa::ProtocolHostapd::PropertyNameSsid, ssid, EnforceConfigurationChange::Now); } catch (Wpa::HostapdException& ex) { - hostapdOperationSucceeded = false; - errorDetails = ex.what(); - } - - if (!hostapdOperationSucceeded) { status.Code = AccessPointOperationStatusCode::InternalError; - status.Details = std::format("failed to set 'ssid' property to {} - {}", ssid, errorDetails.value_or("unspecified error")); + status.Details = std::format("failed to set 'ssid' property to {} - {}", ssid, ex.what()); return status; } diff --git a/src/linux/wpa-controller/WpaController.cxx b/src/linux/wpa-controller/WpaController.cxx index 7367b28f..f825673b 100644 --- a/src/linux/wpa-controller/WpaController.cxx +++ b/src/linux/wpa-controller/WpaController.cxx @@ -15,6 +15,7 @@ #include #include #include +#include #include using namespace Wpa; @@ -82,6 +83,8 @@ WpaController::GetCommandControlSocket() return nullptr; } + LOGD << std::format("Opened {} control socket for {} interface at {}.", magic_enum::enum_name(m_type), m_interfaceName, controlSocketPath.c_str()); + // Update the member and return it. m_controlSocketCommand = controlSocket; return controlSocket;