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

Add and implement IHostapd::[Get/Set]Property() commands #32

Merged
merged 8 commits into from
Nov 23, 2023
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
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