Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable setting access point ssid #154

Merged
merged 21 commits into from
Feb 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/common/wifi/core/AccessPointOperationStatus.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

#include <microsoft/net/wifi/AccessPointOperationStatus.hxx>

using namespace Microsoft::Net::Wifi;

/* static */
AccessPointOperationStatus
AccessPointOperationStatus::MakeSucceeded() noexcept
{
return AccessPointOperationStatus{ AccessPointOperationStatusCode::Succeeded };
}

AccessPointOperationStatus::operator bool() const noexcept
{
return (Code == AccessPointOperationStatusCode::Succeeded);
}
2 changes: 2 additions & 0 deletions src/common/wifi/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ target_sources(wifi-core
AccessPoint.cxx
AccessPointController.cxx
AccessPointControllerException.cxx
AccessPointOperationStatus.cxx
PUBLIC
FILE_SET HEADERS
BASE_DIRS ${WIFI_CORE_PUBLIC_INCLUDE}
FILES
${WIFI_CORE_PUBLIC_INCLUDE_PREFIX}/AccessPoint.hxx
${WIFI_CORE_PUBLIC_INCLUDE_PREFIX}/AccessPointController.hxx
${WIFI_CORE_PUBLIC_INCLUDE_PREFIX}/AccessPointOperationStatus.hxx
${WIFI_CORE_PUBLIC_INCLUDE_PREFIX}/IAccessPoint.hxx
${WIFI_CORE_PUBLIC_INCLUDE_PREFIX}/IAccessPointController.hxx
${WIFI_CORE_PUBLIC_INCLUDE_PREFIX}/Ieee80211.hxx
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@

#ifndef ACCESS_POINT_OPERATION_STATUS_HXX
#define ACCESS_POINT_OPERATION_STATUS_HXX

#include <string>

namespace Microsoft::Net::Wifi
{
/**
* @brief High-level status reported by various access point operations.
*/
enum class AccessPointOperationStatusCode {
Unknown,
Succeeded,
InvalidParameter,
AccessPointInvalid,
AccessPointNotEnabled,
OperationNotSupported,
InternalError,
};

/**
* @brief Coarse status of an access point operation.
*/
struct AccessPointOperationStatus
{
AccessPointOperationStatusCode Code{ AccessPointOperationStatusCode::Unknown };
std::string Message;

AccessPointOperationStatus() = default;
virtual ~AccessPointOperationStatus() = default;

/**
* @brief Create an AccessPointOperationStatus with the given status code.
*/
constexpr explicit AccessPointOperationStatus(AccessPointOperationStatusCode code) noexcept :
Code{ code }
{}

AccessPointOperationStatus(const AccessPointOperationStatus &) = default;
AccessPointOperationStatus(AccessPointOperationStatus &&) = default;
AccessPointOperationStatus &
operator=(const AccessPointOperationStatus &) = default;
AccessPointOperationStatus &
operator=(AccessPointOperationStatus &&) = default;

/**
* @brief Create an AccessPointOperationStatus describing an operation that succeeded.
*
* @return AccessPointOperationStatus
*/
static AccessPointOperationStatus
MakeSucceeded() noexcept;

/**
* @brief Implicit bool operator allowing AccessPointOperationStatus to be used directly in condition statements
* (eg. if (status) // ...).
*
* @return true
* @return false
*/
operator bool() const noexcept; // NOLINT(hicpp-explicit-conversions)
};
} // namespace Microsoft::Net::Wifi

#endif // ACCESS_POINT_OPERATION_STATUS_HXX
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <string_view>
#include <vector>

#include <microsoft/net/wifi/AccessPointOperationStatus.hxx>
#include <microsoft/net/wifi/Ieee80211.hxx>
#include <microsoft/net/wifi/Ieee80211AccessPointCapabilities.hxx>

Expand Down Expand Up @@ -41,12 +42,14 @@ struct IAccessPointController
virtual ~IAccessPointController() = default;

/**
* Prevent copying and moving of IAccessPointController objects.
* Prevent copying and moving of IAccessPointController objects.
*/
IAccessPointController(const IAccessPointController&) = delete;
IAccessPointController& operator=(const IAccessPointController&) = delete;
IAccessPointController&
operator=(const IAccessPointController&) = delete;
IAccessPointController(IAccessPointController&&) = delete;
IAccessPointController& operator=(IAccessPointController&&) = delete;
IAccessPointController&
operator=(IAccessPointController&&) = delete;

/**
* @brief Get the interface name associated with this controller.
Expand Down Expand Up @@ -93,6 +96,15 @@ struct IAccessPointController
*/
virtual bool
SetFrequencyBands(std::vector<Microsoft::Net::Wifi::Ieee80211FrequencyBand> frequencyBands) = 0;

/**
* @brief Set the SSID of the access point.
*
* @param ssid The SSID to be set.
* @return AccessPointOperationStatus
*/
virtual AccessPointOperationStatus
SetSssid(std::string_view ssid) = 0;
};

/**
Expand All @@ -105,12 +117,14 @@ struct IAccessPointControllerFactory
virtual ~IAccessPointControllerFactory() = default;

/**
* Prevent copying and moving of IAccessPointControllerFactory objects.
* Prevent copying and moving of IAccessPointControllerFactory objects.
*/
IAccessPointControllerFactory(const IAccessPointControllerFactory&) = delete;
IAccessPointControllerFactory& operator=(const IAccessPointControllerFactory&) = delete;
IAccessPointControllerFactory&
operator=(const IAccessPointControllerFactory&) = delete;
IAccessPointControllerFactory(IAccessPointControllerFactory&&) = delete;
IAccessPointControllerFactory& operator=(IAccessPointControllerFactory&&) = delete;
IAccessPointControllerFactory&
operator=(IAccessPointControllerFactory&&) = delete;

/**
* @brief Create a new IAccessPointController object.
Expand Down
35 changes: 35 additions & 0 deletions src/common/wifi/core/include/microsoft/net/wifi/Ieee80211.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
#ifndef IEEE_80211_HXX
#define IEEE_80211_HXX

#include <array>
#include <cmath>
#include <cstdint>
#include <initializer_list>
#include <string>

#include <notstd/Utility.hxx>

Expand Down Expand Up @@ -268,6 +270,39 @@ enum class Ieee80211CipherSuite : uint32_t {
Wep40 = MakeIeee80211Suite(Ieee80211CipherSuiteIdWep40),
};

/**
* @brief IEEE 802.11 BSS Types.
*
* Defined in IEEE 802.11-2020, Section 4.3.
*/
enum class Ieee80211BssType {
Unknown,
Infrastructure, // ESS
Independent, // IBSS
Personal, // PBSS
Mesh, // MBSS
};

/**
* @brief Number of octets per BSSID.
*/
static constexpr auto BssidNumOctets = 6;

/**
* @brief BSSID type.
*/
using Ieee80211Bssid = std::array<uint8_t, BssidNumOctets>;

/**
* @brief Information about a BSS.
*/
struct Ieee80211Bss
{
Ieee80211BssType Type;
Ieee80211Bssid Bssid;
std::string Ssid;
};

} // namespace Microsoft::Net::Wifi

#endif // IEEE_80211_HXX
48 changes: 48 additions & 0 deletions src/common/wifi/dot11/adapter/Ieee80211Dot11Adapters.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,61 @@

#include <microsoft/net/remote/protocol/NetRemoteWifi.pb.h>
#include <microsoft/net/remote/protocol/WifiCore.pb.h>
#include <microsoft/net/wifi/AccessPointOperationStatus.hxx>
#include <microsoft/net/wifi/Ieee80211.hxx>
#include <microsoft/net/wifi/Ieee80211AccessPointCapabilities.hxx>
#include <microsoft/net/wifi/Ieee80211Dot11Adapters.hxx>
#include <notstd/Exceptions.hxx>

namespace Microsoft::Net::Wifi
{
using Microsoft::Net::Remote::Wifi::WifiAccessPointOperationStatusCode;
using Microsoft::Net::Wifi::AccessPointOperationStatusCode;

WifiAccessPointOperationStatusCode
ToDot11AccessPointOperationStatusCode(AccessPointOperationStatusCode& accessPointOperationStatusCode) noexcept
{
switch (accessPointOperationStatusCode) {
case AccessPointOperationStatusCode::Succeeded:
return WifiAccessPointOperationStatusCode::WifiAccessPointOperationStatusCodeSucceeded;
case AccessPointOperationStatusCode::InvalidParameter:
return WifiAccessPointOperationStatusCode::WifiAccessPointOperationStatusCodeInvalidParameter;
case AccessPointOperationStatusCode::AccessPointInvalid:
return WifiAccessPointOperationStatusCode::WifiAccessPointOperationStatusCodeAccessPointInvalid;
case AccessPointOperationStatusCode::AccessPointNotEnabled:
return WifiAccessPointOperationStatusCode::WifiAccessPointOperationStatusCodeAccessPointNotEnabled;
case AccessPointOperationStatusCode::OperationNotSupported:
return WifiAccessPointOperationStatusCode::WifiAccessPointOperationStatusCodeOperationNotSupported;
case AccessPointOperationStatusCode::InternalError:
return WifiAccessPointOperationStatusCode::WifiAccessPointOperationStatusCodeInternalError;
case AccessPointOperationStatusCode::Unknown:
default:
return WifiAccessPointOperationStatusCode::WifiAccessPointOperationStatusCodeUnknown;
}
}

AccessPointOperationStatusCode
FromDot11AccessPointOperationStatusCode(WifiAccessPointOperationStatusCode wifiAccessPointOperationStatusCode) noexcept
{
switch (wifiAccessPointOperationStatusCode) {
case WifiAccessPointOperationStatusCode::WifiAccessPointOperationStatusCodeSucceeded:
return AccessPointOperationStatusCode::Succeeded;
case WifiAccessPointOperationStatusCode::WifiAccessPointOperationStatusCodeInvalidParameter:
return AccessPointOperationStatusCode::InvalidParameter;
case WifiAccessPointOperationStatusCode::WifiAccessPointOperationStatusCodeAccessPointInvalid:
return AccessPointOperationStatusCode::AccessPointInvalid;
case WifiAccessPointOperationStatusCode::WifiAccessPointOperationStatusCodeAccessPointNotEnabled:
return AccessPointOperationStatusCode::AccessPointNotEnabled;
case WifiAccessPointOperationStatusCode::WifiAccessPointOperationStatusCodeOperationNotSupported:
return AccessPointOperationStatusCode::OperationNotSupported;
case WifiAccessPointOperationStatusCode::WifiAccessPointOperationStatusCodeInternalError:
return AccessPointOperationStatusCode::InternalError;
case WifiAccessPointOperationStatusCode::WifiAccessPointOperationStatusCodeUnknown:
default:
return AccessPointOperationStatusCode::Unknown;
}
}

using Microsoft::Net::Wifi::Dot11PhyType;
using Microsoft::Net::Wifi::Ieee80211Protocol;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,32 @@

#include <vector>

#include <microsoft/net/remote/protocol/NetRemoteWifi.pb.h>
#include <microsoft/net/remote/protocol/WifiCore.pb.h>
#include <microsoft/net/wifi/AccessPointOperationStatus.hxx>
#include <microsoft/net/wifi/Ieee80211.hxx>
#include <microsoft/net/wifi/Ieee80211AccessPointCapabilities.hxx>

namespace Microsoft::Net::Wifi
{
/**
* @brief Convert the specified WifiAccessPointOperationStatusCode to the equivalent AccessPointOperationStatus.
*
* @param accessPointOperationStatusCode The WifiAccessPointOperationStatusCode to convert.
* @return Microsoft::Net::Remote::Wifi::WifiAccessPointOperationStatusCode
*/
Microsoft::Net::Remote::Wifi::WifiAccessPointOperationStatusCode
ToDot11AccessPointOperationStatusCode(Microsoft::Net::Wifi::AccessPointOperationStatusCode& accessPointOperationStatusCode) noexcept;

/**
* @brief Convert the specified AccessPointOperationStatus to the equivalent WifiAccessPointOperationStatusCode.
*
* @param wifiAccessPointOperationStatusCode The AccessPointOperationStatus to convert.
* @return Microsoft::Net::Wifi::AccessPointOperationStatusCode
*/
Microsoft::Net::Wifi::AccessPointOperationStatusCode
FromDot11AccessPointOperationStatusCode(Microsoft::Net::Remote::Wifi::WifiAccessPointOperationStatusCode wifiAccessPointOperationStatusCode) noexcept;

/**
* @brief Convert the specified Dot11PhyType to the equivalent IEEE 802.11 protocol.
*
Expand Down
53 changes: 51 additions & 2 deletions src/linux/wifi/core/AccessPointControllerLinux.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <microsoft/net/netlink/nl80211/Netlink80211Wiphy.hxx>
#include <microsoft/net/wifi/AccessPointController.hxx>
#include <microsoft/net/wifi/AccessPointControllerLinux.hxx>
#include <microsoft/net/wifi/AccessPointOperationStatus.hxx>
#include <microsoft/net/wifi/IAccessPointController.hxx>
#include <microsoft/net/wifi/Ieee80211.hxx>
#include <microsoft/net/wifi/Ieee80211AccessPointCapabilities.hxx>
Expand Down Expand Up @@ -193,7 +194,7 @@ bool
AccessPointControllerLinux::SetProtocol(Microsoft::Net::Wifi::Ieee80211Protocol ieeeProtocol)
{
bool isOk = false;
Wpa::HostapdHwMode hwMode = detail::IeeeProtocolToHostapdHwMode(ieeeProtocol);
const Wpa::HostapdHwMode hwMode = detail::IeeeProtocolToHostapdHwMode(ieeeProtocol);

try {
// Set the hostapd hw_mode property.
Expand Down Expand Up @@ -249,7 +250,7 @@ AccessPointControllerLinux::SetFrequencyBands(std::vector<Ieee80211FrequencyBand
}

std::string setBandArgumentAll = setBandArgumentBuilder.str();
std::string_view setBandArgument(std::data(setBandArgumentAll), std::size(setBandArgumentAll) - 1); // Remove trailing comma
const std::string_view setBandArgument(std::data(setBandArgumentAll), std::size(setBandArgumentAll) - 1); // Remove trailing comma

bool isOk = false;
try {
Expand All @@ -273,6 +274,54 @@ AccessPointControllerLinux::SetFrequencyBands(std::vector<Ieee80211FrequencyBand
return true;
}

AccessPointOperationStatus
AccessPointControllerLinux::SetSssid(std::string_view ssid)
{
AccessPointOperationStatus status{};

// Ensure the ssid is not empty.
if (std::empty(ssid)) {
status.Code = AccessPointOperationStatusCode::InvalidParameter;
status.Message = "SSID cannot be empty";
LOGE << std::format("No SSID specified for interface {}", GetInterfaceName());
return status;
}

// Attempt to set the SSID.
try {
const bool propertyWasSet = m_hostapd.SetProperty(Wpa::ProtocolHostapd::PropertyNameSsid, ssid);
if (!propertyWasSet) {
LOGE << std::format("Failed to set SSID '{}' for interface {} (rejected)", ssid, GetInterfaceName());
status.Code = AccessPointOperationStatusCode::InternalError;
status.Message = std::format("Access point rejected SSID value '{}'", ssid);
return status;
}
} catch (Wpa::HostapdException& ex) {
LOGE << std::format("Failed to set SSID '{}' for interface {} ({})", ssid, GetInterfaceName(), ex.what());
status.Code = AccessPointOperationStatusCode::InternalError;
status.Message = ex.what();
return status;
}

// Reload the configuration to pick up the changes.
try {
const bool reloaded = m_hostapd.Reload();
if (!reloaded) {
LOGE << std::format("Failed to set SSID '{}' for interface {} (configuration reload failed)", ssid, GetInterfaceName());
status.Code = AccessPointOperationStatusCode::InternalError;
status.Message = "Failed to reload access point configuration";
return status;
}
} catch (Wpa::HostapdException& ex) {
LOGE << std::format("Failed to set SSID '{}' for interface {} ({})", ssid, GetInterfaceName(), ex.what());
status.Code = AccessPointOperationStatusCode::InternalError;
status.Message = ex.what();
return status;
}

return AccessPointOperationStatus::MakeSucceeded();
}

std::unique_ptr<IAccessPointController>
AccessPointControllerLinuxFactory::Create(std::string_view interfaceName)
{
Expand Down
Loading