Skip to content

Commit

Permalink
Merge pull request #32 from microsoft/wpagetsetcmds
Browse files Browse the repository at this point in the history
Add and implement IHostapd::[Get/Set]Property() commands
  • Loading branch information
abeltrano authored Nov 23, 2023
2 parents 0dfbef3 + 4a764b5 commit 389b2ed
Show file tree
Hide file tree
Showing 14 changed files with 306 additions and 41 deletions.
7 changes: 7 additions & 0 deletions linux/wpa-controller/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ target_sources(wpa-controller
${CMAKE_CURRENT_LIST_DIR}/ProtocolHostapd.cxx
${CMAKE_CURRENT_LIST_DIR}/ProtocolWpa.cxx
${CMAKE_CURRENT_LIST_DIR}/WpaCommand.cxx
${CMAKE_CURRENT_LIST_DIR}/WpaCommandGet.cxx
${CMAKE_CURRENT_LIST_DIR}/WpaCommandSet.cxx
${CMAKE_CURRENT_LIST_DIR}/WpaCommandStatus.cxx
${CMAKE_CURRENT_LIST_DIR}/WpaController.cxx
${CMAKE_CURRENT_LIST_DIR}/WpaCore.cxx
Expand All @@ -22,6 +24,8 @@ target_sources(wpa-controller
${WPA_CONTROLLER_PUBLIC_INCLUDE_PREFIX}/ProtocolHostapd.hxx
${WPA_CONTROLLER_PUBLIC_INCLUDE_PREFIX}/ProtocolWpa.hxx
${WPA_CONTROLLER_PUBLIC_INCLUDE_PREFIX}/WpaCommand.hxx
${WPA_CONTROLLER_PUBLIC_INCLUDE_PREFIX}/WpaCommandGet.hxx
${WPA_CONTROLLER_PUBLIC_INCLUDE_PREFIX}/WpaCommandSet.hxx
${WPA_CONTROLLER_PUBLIC_INCLUDE_PREFIX}/WpaCommandStatus.hxx
${WPA_CONTROLLER_PUBLIC_INCLUDE_PREFIX}/WpaController.hxx
${WPA_CONTROLLER_PUBLIC_INCLUDE_PREFIX}/WpaCore.hxx
Expand Down Expand Up @@ -49,11 +53,14 @@ list(APPEND WPA_CONTROLLER_PUBLIC_HEADERS
${WPA_CONTROLLER_PUBLIC_INCLUDE_PREFIX}/ProtocolHostapd.hxx
${WPA_CONTROLLER_PUBLIC_INCLUDE_PREFIX}/IHostapd.hxx
${WPA_CONTROLLER_PUBLIC_INCLUDE_PREFIX}/WpaCommand.hxx
${WPA_CONTROLLER_PUBLIC_INCLUDE_PREFIX}/WpaCommandGet.hxx
${WPA_CONTROLLER_PUBLIC_INCLUDE_PREFIX}/WpaCommandSet.hxx
${WPA_CONTROLLER_PUBLIC_INCLUDE_PREFIX}/WpaCommandStatus.hxx
${WPA_CONTROLLER_PUBLIC_INCLUDE_PREFIX}/WpaController.hxx
${WPA_CONTROLLER_PUBLIC_INCLUDE_PREFIX}/WpaCore.hxx
${WPA_CONTROLLER_PUBLIC_INCLUDE_PREFIX}/WpaKeyValuePair.hxx
${WPA_CONTROLLER_PUBLIC_INCLUDE_PREFIX}/WpaResponse.hxx
${WPA_CONTROLLER_PUBLIC_INCLUDE_PREFIX}/WpaResponseGet.hxx
${WPA_CONTROLLER_PUBLIC_INCLUDE_PREFIX}/WpaResponseParser.hxx
)

Expand Down
33 changes: 33 additions & 0 deletions linux/wpa-controller/Hostapd.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

#include <Wpa/Hostapd.hxx>
#include <Wpa/ProtocolHostapd.hxx>
#include <Wpa/WpaCommandGet.hxx>
#include <Wpa/WpaCommandSet.hxx>
#include <Wpa/WpaCommandStatus.hxx>
#include <Wpa/WpaResponseStatus.hxx>

Expand Down Expand Up @@ -48,6 +50,37 @@ HostapdStatus Hostapd::GetStatus()
return response->Status;
}

bool Hostapd::GetProperty(std::string_view propertyName, std::string& propertyValue)
{
const WpaCommandGet getCommand(propertyName);
const auto response = m_controller.SendCommand(getCommand);
if (!response)
{
throw HostapdException("Failed to send hostapd 'get' command");
}
// Check Failed() and not IsOk() since the response will indicate failure
// with "FAIL", otherwise, the payload is the property value (not "OK").
else if (response->Failed())
{
return false;
}

propertyValue = response->Payload;
return true;
}

bool Hostapd::SetProperty(std::string_view propertyName, std::string_view propertyValue)
{
const WpaCommandSet setCommand(propertyName, propertyValue);
const auto response = m_controller.SendCommand(setCommand);
if (!response)
{
throw HostapdException("Failed to send hostapd 'set' command");
}

return response->IsOk();
}

bool Hostapd::Enable()
{
static constexpr WpaCommand EnableCommand(ProtocolHostapd::CommandPayloadEnable);
Expand Down
5 changes: 5 additions & 0 deletions linux/wpa-controller/WpaCommand.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@

using namespace Wpa;

void WpaCommand::SetPayload(std::string_view payload)
{
Payload = payload;
}

std::shared_ptr<WpaResponse>
WpaCommand::ParseResponse(std::string_view responsePayload) const
{
Expand Down
14 changes: 14 additions & 0 deletions linux/wpa-controller/WpaCommandGet.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

#include <format>

#include <Wpa/WpaCommandGet.hxx>

using namespace Wpa;

WpaCommandGet::WpaCommandGet(std::string_view propertyName) :
WpaCommand(),
PropertyPayload(std::format("{} {}", ProtocolWpa::CommandPayloadGet, propertyName)),
PropertyName(propertyName)
{
SetPayload(PropertyPayload);
}
16 changes: 16 additions & 0 deletions linux/wpa-controller/WpaCommandSet.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

#include <format>

#include <Wpa/ProtocolWpa.hxx>
#include <Wpa/WpaCommandSet.hxx>

using namespace Wpa;

WpaCommandSet::WpaCommandSet(std::string_view propertyName, std::string_view propertyValue) :
WpaCommand(),
PropertyPayload(std::format("{} {} {}", ProtocolWpa::CommandPayloadSet, propertyName, propertyValue)),
PropertyName(propertyName),
PropertyValue(propertyValue)
{
SetPayload(PropertyPayload);
}
2 changes: 1 addition & 1 deletion linux/wpa-controller/WpaController.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ WpaController::SendCommand(const WpaCommand& command)
std::array<char, WpaControlSocket::MessageSizeMax> responseBuffer;
std::size_t responseSize = std::size(responseBuffer);

int ret = wpa_ctrl_request(controlSocket, std::data(command.Data), std::size(command.Data), std::data(responseBuffer), &responseSize, nullptr);
int ret = wpa_ctrl_request(controlSocket, std::data(command.Payload), std::size(command.Payload), std::data(responseBuffer), &responseSize, nullptr);
switch (ret)
{
case 0:
Expand Down
56 changes: 38 additions & 18 deletions linux/wpa-controller/include/Wpa/Hostapd.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -24,47 +24,67 @@ struct Hostapd :
Hostapd(std::string_view interfaceName);

/**
* @brief Get the name of the interface hostapd is managing.
* @brief Enables the interface for use.
*
* @return std::string_view
* @return true
* @return false
*/
std::string_view GetInterface() override;
bool Enable() override;

/**
* @brief Disables the interface for use.
*
* @return true
* @return false
*/
bool Disable() override;

/**
* @brief Terminates the process hosting the daemon.
*
* @return true
* @return false
*/
bool Terminate() override;

/**
* @brief Checks connectivity to the hostapd daemon.
*/
bool Ping() override;

/**
* @brief Get the status for the interface.
* @brief Get the name of the interface hostapd is managing.
*
* @return HostapdStatus
* @return std::string_view
*/
HostapdStatus GetStatus() override;
std::string_view GetInterface() override;

/**
* @brief Enables the interface for use.
* @brief Get the status for the interface.
*
* @return true
* @return false
* @return HostapdStatus
*/
bool Enable() override;
HostapdStatus GetStatus() override;

/**
* @brief Disables the interface for use.
* @brief Get a property value for the interface.
*
* @return true
* @return false
* @param propertyName The name of the property to retrieve.
* @param propertyValue The string to store the property value in.
* @return true If the property value was obtained and its value is in 'propertyValue'.
* @return false If t he property value could not be obtained due to an error.
*/
bool Disable() override;
bool GetProperty(std::string_view propertyName, std::string& propertyValue) override;

/**
* @brief Terminates the process hosting the daemon.
* @brief Set a property on the interface.
*
* @return true
* @return false
* @param propertyName The name of the property to set.
* @param propertyValue The value of the property to set.
* @return true The property was set successfully.
* @return false The property was not set successfully.
*/
bool Terminate() override;
bool SetProperty(std::string_view propertyName, std::string_view propertyValue) override;

private:
const std::string m_interface;
Expand Down
56 changes: 38 additions & 18 deletions linux/wpa-controller/include/Wpa/IHostapd.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -24,47 +24,67 @@ struct IHostapd
virtual ~IHostapd() = default;

/**
* @brief Get the name of the interface hostapd is managing.
* @brief Enables the interface for use.
*
* @return std::string_view
* @return true
* @return false
*/
virtual std::string_view GetInterface() = 0;
virtual bool Enable() = 0;

/**
* @brief Disables the interface for use.
*
* @return true
* @return false
*/
virtual bool Disable() = 0;

/**
* @brief Terminates the process hosting the daemon.
*
* @return true
* @return false
*/
virtual bool Terminate() = 0;

/**
* @brief Checks connectivity to the hostapd daemon.
*/
virtual bool Ping() = 0;

/**
* @brief Get the status for the interface.
* @brief Get the name of the interface hostapd is managing.
*
* @return HostapdStatus
* @return std::string_view
*/
virtual HostapdStatus GetStatus() = 0;
virtual std::string_view GetInterface() = 0;

/**
* @brief Enables the interface for use.
* @brief Get the status for the interface.
*
* @return true
* @return false
* @return HostapdStatus
*/
virtual bool Enable() = 0;
virtual HostapdStatus GetStatus() = 0;

/**
* @brief Disables the interface for use.
* @brief Get a property value for the interface.
*
* @return true
* @return false
* @param propertyName The name of the property to retrieve.
* @param propertyValue The string to store the property value in.
* @return true If the property value was obtained and its value is in 'propertyValue'.
* @return false If t he property value could not be obtained due to an error.
*/
virtual bool Disable() = 0;
virtual bool GetProperty(std::string_view propertyName, std::string& propertyValue) = 0;

/**
* @brief Terminates the process hosting the daemon.
* @brief Set a property on the interface.
*
* @return true
* @return false
* @param propertyName The name of the property to set.
* @param propertyValue The value of the property to set.
* @return true The property was set successfully.
* @return false The property was not set successfully.
*/
virtual bool Terminate() = 0;
virtual bool SetProperty(std::string_view propertyName, std::string_view propertyValue) = 0;
};

/**
Expand Down
13 changes: 13 additions & 0 deletions linux/wpa-controller/include/Wpa/ProtocolHostapd.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,19 @@ struct ProtocolHostapd :
static constexpr auto ResponsePayloadStatusNoIr = "NO_IR";
static constexpr auto ResponsePayloadStatusUnknown = "UNKNOWN";

// Property names for "GET" commands.
static constexpr auto PropertyNameVersion = "version";
static constexpr auto PropertyNameTlsLibrary = "tls_library";
// Note: this value must be updated if the version of hostapd changes.
static constexpr auto PropertyVersionValue = "2.10-hostap_2_10";

// Property names for "SET" commands.
static constexpr auto PropertyNameSetBand = "setband";
static constexpr auto PropertySetBandValueAuto = "AUTO";
static constexpr auto PropertySetBandValue2G = "2G";
static constexpr auto PropertySetBandValue5G = "5G";
static constexpr auto PropertySetBandValue6G = "6G";

// Response properties for the "STATUS" command.
// Note: all properties must be terminated with the key-value delimeter (=).
static constexpr auto ResponseStatusPropertyKeyState = "state=";
Expand Down
15 changes: 11 additions & 4 deletions linux/wpa-controller/include/Wpa/WpaCommand.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
namespace Wpa
{
/**
* @brief Object to hold generic command data for a wpa_supplicant or hostapd
* @brief Object to hold generic command payload for a wpa_supplicant or hostapd
* request.
*/
struct WpaCommand :
Expand All @@ -20,11 +20,18 @@ struct WpaCommand :
virtual ~WpaCommand() = default;

constexpr WpaCommand() = default;
constexpr WpaCommand(std::string_view data) :
Data(data)
constexpr WpaCommand(std::string_view payload) :
Payload(payload)
{
}

/**
* @brief Set the payload of the command.
*
* @param payload The payload to assign.
*/
void SetPayload(std::string_view payload);

/**
* @brief Parse the response payload into a WpaResponse object.
*
Expand All @@ -34,7 +41,7 @@ struct WpaCommand :
std::shared_ptr<WpaResponse>
ParseResponse(std::string_view responsePayload) const;

std::string Data;
std::string Payload;

private:
/**
Expand Down
31 changes: 31 additions & 0 deletions linux/wpa-controller/include/Wpa/WpaCommandGet.hxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

#ifndef WPA_COMMAND_GET_HXX
#define WPA_COMMAND_GET_HXX

#include <string_view>
#include <string>

#include <Wpa/WpaCommand.hxx>

namespace Wpa
{
/**
* @brief Representation of the "GET" command.
*/
struct WpaCommandGet :
public WpaCommand
{
/**
* @brief Construct a new WpaCommandGet object for the specified property.
*
* @param propertyName The name of the property to retrieve.
*/
WpaCommandGet(std::string_view propertyName);

std::string PropertyPayload;
std::string_view PropertyName;
};

} // namespace Wpa

#endif // WPA_COMMAND_GET_HXX
Loading

0 comments on commit 389b2ed

Please sign in to comment.