1 Commits

Author SHA1 Message Date
43bad1f153 Linux splitups, removing the parts that dont work under linux 2023-10-12 11:11:28 +02:00
5 changed files with 1 additions and 792 deletions

View File

@ -1,14 +1,10 @@
set(headers
src/espwifistack.h
src/espwifistackconfig.h
src/espwifistackenums.h
src/espwifiutils.h
src/udpsender.h
)
set(sources
src/espwifistack.cpp
src/espwifiutils.cpp
src/udpsender.cpp
)
@ -24,6 +20,7 @@ set(dependencies
cpputils
espchrono
espcpputils
espwifiutils
fmt
)

View File

@ -1,277 +0,0 @@
#pragma once
#include "sdkconfig.h"
// system includes
#include <string>
#include <array>
#include <cstdint>
#include <optional>
#include <variant>
// esp-idf includes
#include <esp_wifi_types.h>
#include <hal/gpio_types.h>
// 3rdparty lib includes
#include <espchrono.h>
// local includes
#include "espwifiutils.h"
inline bool operator==(const wifi_country_t &left, const wifi_country_t &right)
{
return std::equal(std::begin(left.cc), std::end(left.cc), std::begin(right.cc)) &&
left.schan == right.schan &&
left.nchan == right.nchan &&
left.max_tx_power == right.max_tx_power &&
left.policy == right.policy;
}
namespace wifi_stack {
struct static_ip_config
{
ip_address_t ip;
ip_address_t subnet;
ip_address_t gateway;
friend bool operator==(const static_ip_config &left, const static_ip_config &right)
{
return left.ip == right.ip &&
left.subnet == right.subnet &&
left.gateway == right.gateway;
}
friend bool operator!=(const static_ip_config &left, const static_ip_config &right)
{
return !(left == right);
}
};
struct static_dns_config
{
std::optional<ip_address_t> main;
std::optional<ip_address_t> backup;
std::optional<ip_address_t> fallback;
friend bool operator==(const static_dns_config &left, const static_dns_config &right)
{
return left.main == right.main &&
left.backup == right.backup &&
left.fallback == right.fallback;
}
friend bool operator!=(const static_dns_config &left, const static_dns_config &right)
{
return !(left == right);
}
};
struct wifi_entry
{
std::string ssid;
std::string key;
std::optional<static_ip_config> static_ip;
static_dns_config static_dns;
friend bool operator==(const wifi_entry &left, const wifi_entry &right)
{
return left.ssid == right.ssid &&
left.key == right.key &&
left.static_ip == right.static_ip &&
left.static_dns == right.static_dns;
}
friend bool operator!=(const wifi_entry &left, const wifi_entry &right)
{
return !(left == right);
}
};
struct sta_active_scan_config
{
espchrono::milliseconds32 min_per_chan{100};
espchrono::milliseconds32 max_per_chan{300};
friend bool operator==(const sta_active_scan_config &left, const sta_active_scan_config &right)
{
return left.min_per_chan == right.min_per_chan &&
left.max_per_chan == right.max_per_chan;
}
friend bool operator!=(const sta_active_scan_config &left, const sta_active_scan_config &right)
{
return !(left == right);
}
};
struct sta_passive_scan_config
{
espchrono::milliseconds32 max_per_chan{300};
friend bool operator==(const sta_passive_scan_config &left, const sta_passive_scan_config &right)
{
return left.max_per_chan == right.max_per_chan;
}
friend bool operator!=(const sta_passive_scan_config &left, const sta_passive_scan_config &right)
{
return !(left == right);
}
};
struct sta_scan_config
{
std::optional<espchrono::milliseconds32> interval = espchrono::minutes32{10};
uint8_t channel = 0;
bool show_hidden = false;
std::variant<sta_active_scan_config, sta_passive_scan_config> time = sta_active_scan_config{};
friend bool operator==(const sta_scan_config &left, const sta_scan_config &right)
{
return left.interval == right.interval &&
left.channel == right.channel &&
left.show_hidden == right.show_hidden &&
left.time == right.time;
}
friend bool operator!=(const sta_scan_config &left, const sta_scan_config &right)
{
return !(left == right);
}
};
#ifdef CONFIG_WIFI_DUAL_ANT
struct dual_ant_config
{
gpio_num_t selectPin0{GPIO_NUM_2};
gpio_num_t selectPin1{GPIO_NUM_25};
friend bool operator==(const dual_ant_config &left, const dual_ant_config &right)
{
return left.selectPin0 == right.selectPin0 &&
left.selectPin1 == right.selectPin1;
}
friend bool operator!=(const dual_ant_config &left, const dual_ant_config &right)
{
return !(left == right);
}
};
#endif
struct sta_config
{
std::string hostname;
std::array<wifi_entry, 10> wifis;
int8_t min_rssi = -90;
bool long_range = false;
wifi_bandwidth_t bandwidth = WIFI_BW_HT20;
sta_scan_config scan;
friend bool operator==(const sta_config &left, const sta_config &right)
{
return left.hostname == right.hostname &&
left.wifis == right.wifis &&
left.min_rssi == right.min_rssi &&
left.long_range == right.long_range &&
left.bandwidth == right.bandwidth &&
left.scan == right.scan;
}
friend bool operator!=(const sta_config &left, const sta_config &right)
{
return !(left == right);
}
};
struct ap_config
{
std::string hostname;
std::string ssid;
std::string key;
static_ip_config static_ip;
uint8_t channel = 1;
wifi_auth_mode_t authmode = WIFI_AUTH_WPA2_PSK;
bool ssid_hidden = false;
int max_connection = 4;
uint16_t beacon_interval = 100;
bool long_range = false;
wifi_bandwidth_t bandwidth = WIFI_BW_HT20;
friend bool operator==(const ap_config &left, const ap_config &right)
{
return left.hostname == right.hostname &&
left.ssid == right.ssid &&
left.key == right.key &&
left.static_ip == right.static_ip &&
left.channel == right.channel &&
left.authmode == right.authmode &&
left.ssid_hidden == right.ssid_hidden &&
left.max_connection == right.max_connection &&
left.beacon_interval == right.beacon_interval &&
left.long_range == right.long_range &&
left.bandwidth == right.bandwidth;
}
friend bool operator!=(const ap_config &left, const ap_config &right)
{
return !(left == right);
}
};
#ifdef CONFIG_ETH_ENABLED
struct eth_config
{
std::string hostname;
std::optional<static_ip_config> static_ip;
static_dns_config static_dns;
friend bool operator==(const eth_config &left, const eth_config &right)
{
return left.hostname == right.hostname &&
left.static_ip == right.static_ip &&
left.static_dns == right.static_dns;
}
friend bool operator!=(const eth_config &left, const eth_config &right)
{
return !(left == right);
}
};
#endif
struct config
{
std::optional<mac_t> base_mac_override;
#ifdef CONFIG_WIFI_DUAL_ANT
std::optional<dual_ant_config> dual_ant;
#endif
std::optional<sta_config> sta;
std::optional<ap_config> ap;
#ifdef CONFIG_ETH_ENABLED
std::optional<eth_config> eth;
#endif
std::optional<wifi_country_t> country;
friend bool operator==(const config &left, const config &right)
{
return left.base_mac_override == right.base_mac_override &&
#ifdef CONFIG_WIFI_DUAL_ANT
left.dual_ant == right.dual_ant &&
#endif
left.sta == right.sta &&
left.ap == right.ap &&
#ifdef CONFIG_ETH_ENABLED
left.eth == right.eth &&
#endif
left.country == right.country;
}
friend bool operator!=(const config &left, const config &right)
{
return !(left == right);
}
};
} // namespace wifi_stack

View File

@ -1,36 +0,0 @@
#pragma once
// 3rdparty lib includes
#include <cpptypesafeenum.h>
namespace wifi_stack {
#define WiFiStateValues(x) \
x(None) \
x(Scanning) \
x(Connecting) \
x(Connected)
DECLARE_TYPESAFE_ENUM(WiFiState, : uint8_t, WiFiStateValues)
#define WiFiStaStatusValues(x) \
x(IDLE_STATUS, = 0) \
x(NO_SSID_AVAIL, = 1) \
x(SCAN_COMPLETED, = 2) \
x(CONNECTED, = 3) \
x(CONNECT_FAILED, = 4) \
x(CONNECTION_LOST, = 5) \
x(DISCONNECTED, = 6) \
x(CONNECTING, = 7) \
x(DISCONNECTING, = 8) \
x(NO_SHIELD, = 9) \
x(WAITING_FOR_IP, = 10)
DECLARE_TYPESAFE_ENUM(WiFiStaStatus, : uint8_t, WiFiStaStatusValues)
#define WiFiScanStatusValues(x) \
x(None) \
x(Scanning) \
x(Finished) \
x(Failed)
DECLARE_TYPESAFE_ENUM(WiFiScanStatus, : uint8_t, WiFiScanStatusValues)
} // namespace wifi_stack

View File

@ -1,349 +0,0 @@
#include "espwifiutils.h"
// system includes
#include <cstdio>
#include <bitset>
#include <utility>
// esp-idf includes
#include <esp_log.h>
// 3rdparty lib includes
#include <fmt/core.h>
namespace wifi_stack {
namespace {
constexpr const char * const TAG = "WIFI_STACK";
} // namespace
bool wifi_ap_config_equal(const wifi_ap_config_t& lhs, const wifi_ap_config_t& rhs)
{
auto leftSsid = lhs.ssid_len ?
std::string_view{reinterpret_cast<const char*>(lhs.ssid), lhs.ssid_len} :
std::string_view{reinterpret_cast<const char*>(lhs.ssid)};
auto rightSsid = rhs.ssid_len ?
std::string_view{reinterpret_cast<const char*>(rhs.ssid), rhs.ssid_len} :
std::string_view{reinterpret_cast<const char*>(rhs.ssid)};
return leftSsid == rightSsid &&
std::string_view{reinterpret_cast<const char*>(lhs.password)} == std::string_view{reinterpret_cast<const char*>(rhs.password)} &&
lhs.channel == rhs.channel &&
lhs.authmode == rhs.authmode &&
lhs.ssid_hidden == rhs.ssid_hidden &&
lhs.max_connection == rhs.max_connection &&
lhs.beacon_interval == rhs.beacon_interval &&
lhs.pairwise_cipher == rhs.pairwise_cipher;
}
bool wifi_sta_config_equal(const wifi_sta_config_t& lhs, const wifi_sta_config_t& rhs)
{
return std::string_view{reinterpret_cast<const char*>(lhs.ssid)} == std::string_view{reinterpret_cast<const char*>(rhs.ssid)} &&
std::string_view{reinterpret_cast<const char*>(lhs.password)} == std::string_view{reinterpret_cast<const char*>(rhs.password)} &&
lhs.scan_method == rhs.scan_method &&
lhs.bssid_set == rhs.bssid_set &&
(lhs.bssid_set ? (*reinterpret_cast<const mac_t *>(lhs.bssid) == *reinterpret_cast<const mac_t *>(rhs.bssid)) : true) &&
lhs.channel == rhs.channel &&
lhs.listen_interval == rhs.listen_interval &&
lhs.sort_method == rhs.sort_method &&
lhs.threshold.rssi == rhs.threshold.rssi &&
lhs.threshold.authmode == rhs.threshold.authmode &&
lhs.pmf_cfg.capable == rhs.pmf_cfg.capable &&
lhs.pmf_cfg.required == rhs.pmf_cfg.required &&
bool(lhs.rm_enabled) == bool(rhs.rm_enabled) &&
bool(lhs.btm_enabled) == bool(rhs.btm_enabled);
}
std::string toString(wifi_auth_mode_t authMode)
{
switch (authMode)
{
case WIFI_AUTH_OPEN: return "OPEN";
case WIFI_AUTH_WEP: return "WEP";
case WIFI_AUTH_WPA_PSK: return "WPA_PSK";
case WIFI_AUTH_WPA2_PSK: return "WPA2_PSK";
case WIFI_AUTH_WPA_WPA2_PSK: return "WPA_WPA2_PSK";
case WIFI_AUTH_WPA2_ENTERPRISE: return "WPA2_ENTERPRISE";
case WIFI_AUTH_WPA3_PSK: return "WPA3_PSK";
case WIFI_AUTH_WPA2_WPA3_PSK: return "WPA2_WPA3_PSK";
case WIFI_AUTH_WAPI_PSK: return "WAPI_PSK";
case WIFI_AUTH_OWE: return "OWE";
case WIFI_AUTH_MAX: return "MAX";
}
ESP_LOGW(TAG, "Unknown wifi_auth_mode_t(%i)", std::to_underlying(authMode));
return fmt::format("Unknown wifi_auth_mode_t({})", std::to_underlying(authMode));
}
std::string toString(wifi_cipher_type_t cipherType)
{
switch (cipherType)
{
case WIFI_CIPHER_TYPE_NONE: return "NONE";
case WIFI_CIPHER_TYPE_WEP40: return "WEP40";
case WIFI_CIPHER_TYPE_WEP104: return "WEP104";
case WIFI_CIPHER_TYPE_TKIP: return "TKIP";
case WIFI_CIPHER_TYPE_CCMP: return "CCMP";
case WIFI_CIPHER_TYPE_TKIP_CCMP: return "TKIP_CCMP";
case WIFI_CIPHER_TYPE_AES_CMAC128: return "AES_CMAC128";
case WIFI_CIPHER_TYPE_SMS4: return "SMS4";
case WIFI_CIPHER_TYPE_GCMP: return "GCMP";
case WIFI_CIPHER_TYPE_GCMP256: return "GCMP256";
case WIFI_CIPHER_TYPE_AES_GMAC128: return "AES_GMAC128";
case WIFI_CIPHER_TYPE_AES_GMAC256: return "AES_GMAC256";
case WIFI_CIPHER_TYPE_UNKNOWN: return "UNKNOWN";
}
ESP_LOGW(TAG, "Unknown wifi_cipher_type_t(%i)", std::to_underlying(cipherType));
return fmt::format("Unknown wifi_cipher_type_t({})", std::to_underlying(cipherType));
}
std::string toString(wifi_bandwidth_t bandwidth)
{
switch (bandwidth)
{
case WIFI_BW_HT20: return "HT20";
case WIFI_BW_HT40: return "HT40";
}
ESP_LOGW(TAG, "Unknown wifi_bandwidth_t(%i)", std::to_underlying(bandwidth));
return fmt::format("Unknown wifi_bandwidth_t({})", std::to_underlying(bandwidth));
}
std::string toString(esp_interface_t interface)
{
switch (interface)
{
case ESP_IF_WIFI_STA: return "STA";
case ESP_IF_WIFI_AP: return "AP";
case ESP_IF_WIFI_NAN: return "NAN";
case ESP_IF_ETH: return "ETH";
case ESP_IF_MAX: return "MAX";
}
ESP_LOGW(TAG, "Unknown esp_interface_t(%i)", std::to_underlying(interface));
return fmt::format("Unknown esp_interface_t({})", std::to_underlying(interface));
}
std::string toString(esp_netif_dhcp_status_t status)
{
switch (status)
{
case ESP_NETIF_DHCP_INIT: return "INIT";
case ESP_NETIF_DHCP_STARTED: return "STARTED";
case ESP_NETIF_DHCP_STOPPED: return "STOPPED";
case ESP_NETIF_DHCP_STATUS_MAX: return "STATUS_MAX";
}
ESP_LOGW(TAG, "Unknown esp_netif_dhcp_status_t(%i)", std::to_underlying(status));
return fmt::format("Unknown esp_netif_dhcp_status_t({})", std::to_underlying(status));
}
const char * toString(wifi_err_reason_t reason)
{
switch (reason)
{
case WIFI_REASON_UNSPECIFIED: return "UNSPECIFIED";
case WIFI_REASON_AUTH_EXPIRE: return "AUTH_EXPIRE";
case WIFI_REASON_AUTH_LEAVE: return "AUTH_LEAVE";
case WIFI_REASON_ASSOC_EXPIRE: return "ASSOC_EXPIRE";
case WIFI_REASON_ASSOC_TOOMANY: return "ASSOC_TOOMANY";
case WIFI_REASON_NOT_AUTHED: return "NOT_AUTHED";
case WIFI_REASON_NOT_ASSOCED: return "NOT_ASSOCED";
case WIFI_REASON_ASSOC_LEAVE: return "ASSOC_LEAVE";
case WIFI_REASON_ASSOC_NOT_AUTHED: return "ASSOC_NOT_AUTHED";
case WIFI_REASON_DISASSOC_PWRCAP_BAD: return "DISASSOC_PWRCAP_BAD";
case WIFI_REASON_DISASSOC_SUPCHAN_BAD: return "DISASSOC_SUPCHAN_BAD";
case WIFI_REASON_BSS_TRANSITION_DISASSOC: return "BSS_TRANSITION_DISASSOC";
case WIFI_REASON_IE_INVALID: return "IE_INVALID";
case WIFI_REASON_MIC_FAILURE: return "MIC_FAILURE";
case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT: return "4WAY_HANDSHAKE_TIMEOUT";
case WIFI_REASON_GROUP_KEY_UPDATE_TIMEOUT: return "GROUP_KEY_UPDATE_TIMEOUT";
case WIFI_REASON_IE_IN_4WAY_DIFFERS: return "IE_IN_4WAY_DIFFERS";
case WIFI_REASON_GROUP_CIPHER_INVALID: return "GROUP_CIPHER_INVALID";
case WIFI_REASON_PAIRWISE_CIPHER_INVALID: return "PAIRWISE_CIPHER_INVALID";
case WIFI_REASON_AKMP_INVALID: return "AKMP_INVALID";
case WIFI_REASON_UNSUPP_RSN_IE_VERSION: return "UNSUPP_RSN_IE_VERSION";
case WIFI_REASON_INVALID_RSN_IE_CAP: return "INVALID_RSN_IE_CAP";
case WIFI_REASON_802_1X_AUTH_FAILED: return "802_1X_AUTH_FAILED";
case WIFI_REASON_CIPHER_SUITE_REJECTED: return "CIPHER_SUITE_REJECTED";
case WIFI_REASON_TDLS_PEER_UNREACHABLE: return "TDLS_PEER_UNREACHABLE";
case WIFI_REASON_TDLS_UNSPECIFIED: return "TDLS_UNSPECIFIED";
case WIFI_REASON_SSP_REQUESTED_DISASSOC: return "SSP_REQUESTED_DISASSOC";
case WIFI_REASON_NO_SSP_ROAMING_AGREEMENT: return "NO_SSP_ROAMING_AGREEMENT";
case WIFI_REASON_BAD_CIPHER_OR_AKM: return "BAD_CIPHER_OR_AKM";
case WIFI_REASON_NOT_AUTHORIZED_THIS_LOCATION: return "NOT_AUTHORIZED_THIS_LOCATION";
case WIFI_REASON_SERVICE_CHANGE_PERCLUDES_TS: return "SERVICE_CHANGE_PERCLUDES_TS";
case WIFI_REASON_UNSPECIFIED_QOS: return "UNSPECIFIED_QOS";
case WIFI_REASON_NOT_ENOUGH_BANDWIDTH: return "NOT_ENOUGH_BANDWIDTH";
case WIFI_REASON_MISSING_ACKS: return "MISSING_ACKS";
case WIFI_REASON_EXCEEDED_TXOP: return "EXCEEDED_TXOP";
case WIFI_REASON_STA_LEAVING: return "STA_LEAVING";
case WIFI_REASON_END_BA: return "END_BA";
case WIFI_REASON_UNKNOWN_BA: return "UNKNOWN_BA";
case WIFI_REASON_TIMEOUT: return "TIMEOUT";
case WIFI_REASON_PEER_INITIATED: return "PEER_INITIATED";
case WIFI_REASON_AP_INITIATED: return "AP_INITIATED";
case WIFI_REASON_INVALID_FT_ACTION_FRAME_COUNT: return "INVALID_FT_ACTION_FRAME_COUNT";
case WIFI_REASON_INVALID_PMKID: return "INVALID_PMKID";
case WIFI_REASON_INVALID_MDE: return "INVALID_MDE";
case WIFI_REASON_INVALID_FTE: return "INVALID_FTE";
case WIFI_REASON_TRANSMISSION_LINK_ESTABLISH_FAILED: return "TRANSMISSION_LINK_ESTABLISH_FAILED";
case WIFI_REASON_ALTERATIVE_CHANNEL_OCCUPIED: return "ALTERATIVE_CHANNEL_OCCUPIED";
case WIFI_REASON_BEACON_TIMEOUT: return "BEACON_TIMEOUT";
case WIFI_REASON_NO_AP_FOUND: return "NO_AP_FOUND";
case WIFI_REASON_AUTH_FAIL: return "AUTH_FAIL";
case WIFI_REASON_ASSOC_FAIL: return "ASSOC_FAIL";
case WIFI_REASON_HANDSHAKE_TIMEOUT: return "HANDSHAKE_TIMEOUT";
case WIFI_REASON_CONNECTION_FAIL: return "CONNECTION_FAIL";
case WIFI_REASON_AP_TSF_RESET: return "AP_TSF_RESET";
case WIFI_REASON_ROAMING: return "ROAMING";
case WIFI_REASON_ASSOC_COMEBACK_TIME_TOO_LONG: return "ASSOC_COMEBACK_TIME_TOO_LONG";
case WIFI_REASON_SA_QUERY_TIMEOUT: return "SA_QUERY_TIMEOUT";
}
ESP_LOGE(TAG, "unknown reason %" PRIu8, reason);
return "UNKNOWN";
}
#ifdef CONFIG_PPP_SUPPORT
std::string toString(esp_netif_auth_type_t authType)
{
switch (authType)
{
case NETIF_PPP_AUTHTYPE_NONE: return "NONE";
case NETIF_PPP_AUTHTYPE_PAP: return "PAP";
case NETIF_PPP_AUTHTYPE_CHAP: return "CHAP";
case NETIF_PPP_AUTHTYPE_MSCHAP: return "MSCHAP";
case NETIF_PPP_AUTHTYPE_MSCHAP_V2: return "MSCHAP_V2";
case NETIF_PPP_AUTHTYPE_EAP: return "EAP";
}
ESP_LOGW(TAG, "Unknown esp_netif_auth_type_t(%i)", std::to_underlying(authType));
return fmt::format("Unknown esp_netif_auth_type_t({})", std::to_underlying(authType));
}
#endif
template<> std::expected<mac_t, std::string> fromString<mac_t>(std::string_view str)
{
mac_t result{};
if (std::sscanf(str.data(), "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx",
&result[0], &result[1], &result[2], &result[3], &result[4], &result[5]) == 6)
return result;
return std::unexpected(fmt::format("invalid format ({})", str));
}
std::string toString(const mac_t &val)
{
return fmt::format("{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}",
val.at(0), val.at(1), val.at(2), val.at(3), val.at(4), val.at(5));
}
std::string toString(const std::optional<mac_t> &val)
{
return val ? toString(*val) : "nullopt";
}
template<> std::expected<ip_address_t, std::string> fromString<ip_address_t>(std::string_view str)
{
// TODO: add support for "a", "a.b", "a.b.c" formats
// TODO: replace with scanf for better performance
ip_address_t result;
uint16_t acc = 0; // Accumulator
uint8_t dots = 0;
for (char c : str)
{
if (c >= '0' && c <= '9')
{
acc = acc * 10 + (c - '0');
if (acc > 255)
return std::unexpected("Value out of [0..255] range");
}
else if (c == '.')
{
if (dots == 3)
return std::unexpected("Too many dots (there must be 3 dots)");
result[dots++] = acc;
acc = 0;
}
else
return std::unexpected("Invalid char");
}
if (dots != 3)
return std::unexpected("Too few dots (there must be 3 dots)");
result[3] = acc;
return result;
}
std::string toString(ip_address_t val)
{
return fmt::format("{}.{}.{}.{}", val[0], val[1], val[2], val[3]);
}
std::string toString(const std::optional<ip_address_t> &val)
{
return val ? toString(*val) : "nullopt";
}
ip_address_t wifi_calculate_network_id(ip_address_t ip, ip_address_t subnet)
{
ip_address_t networkID;
for (size_t i = 0; i < 4; i++)
networkID[i] = subnet[i] & ip[i];
return networkID;
}
ip_address_t wifi_calculate_broadcast(ip_address_t ip, ip_address_t subnet)
{
ip_address_t broadcastIp;
for (int i = 0; i < 4; i++)
broadcastIp[i] = ~subnet[i] | ip[i];
return broadcastIp;
}
uint8_t wifi_calculate_subnet_cidr(ip_address_t subnetMask)
{
return std::bitset<32>{subnetMask.value()}.count();
}
std::string toString(ip4_addr_t val)
{
return toString(ip_address_t{val.addr});
}
std::string toString(const ip6_addr_t &val)
{
char str[40];
ip6addr_ntoa_r(&val, str, sizeof(str));
return std::string{str};
}
std::string toString(ip_addr_t val)
{
switch (val.type)
{
case IPADDR_TYPE_V4: return toString(val.u_addr.ip4);
case IPADDR_TYPE_V6: return toString(val.u_addr.ip6);
}
//ESP_LOGW(TAG, "Unknown ipv%hhu", val.type);
return fmt::format("Unknown ipv{}", val.type);
}
std::string toString(const esp_ip_addr_t &val)
{
switch (val.type)
{
case IPADDR_TYPE_V4: return toString(val.u_addr.ip4);
case IPADDR_TYPE_V6: return toString(val.u_addr.ip6);
}
ESP_LOGW(TAG, "Unknown ipv%hhu", val.type);
return fmt::format("Unknown ipv{}", val.type);
}
} // namespace wifi_stack

View File

@ -1,126 +0,0 @@
#pragma once
// system includes
#include <stdint.h>
#include <string>
#include <string_view>
#include <array>
#include <optional>
#include <expected>
// esp-idf includes
#include <esp_wifi_types.h>
#include <esp_netif_ip_addr.h>
#include <esp_netif_types.h>
#include <lwip/ip_addr.h>
#ifdef CONFIG_PPP_SUPPORT
#include <esp_netif_ppp.h>
#endif
namespace wifi_stack {
bool wifi_ap_config_equal(const wifi_ap_config_t& lhs, const wifi_ap_config_t& rhs);
bool wifi_sta_config_equal(const wifi_sta_config_t& lhs, const wifi_sta_config_t& rhs);
std::string toString(wifi_auth_mode_t authMode);
std::string toString(wifi_cipher_type_t cipherType);
std::string toString(wifi_bandwidth_t bandwidth);
std::string toString(esp_interface_t interface);
std::string toString(esp_netif_dhcp_status_t status);
const char * toString(wifi_err_reason_t reason);
#ifdef CONFIG_PPP_SUPPORT
std::string toString(esp_netif_auth_type_t);
#endif
template<typename T> std::expected<T, std::string> fromString(std::string_view str) = delete;
// A class to make it easier to handle and pass around mac addresses / bssids
class mac_t : public std::array<uint8_t, 6>
{
public:
static constexpr const size_t static_size = 6;
using std::array<uint8_t, 6>::array;
using std::array<uint8_t, 6>::operator=;
constexpr explicit mac_t(const uint8_t (&arr)[6]) noexcept
{
std::copy(std::begin(arr), std::end(arr), std::begin(*this));
}
void copyTo(uint8_t (&arr)[6]) const noexcept
{
std::copy(std::begin(*this), std::end(*this), std::begin(arr));
}
};
template<> std::expected<mac_t, std::string> fromString<mac_t>(std::string_view str);
std::string toString(const mac_t &val);
std::string toString(const std::optional<mac_t> &val);
// A class to make it easier to handle and pass around IP addresses
// Implementation taken from arduino-esp32
class ip_address_t
{
public:
using value_t = uint32_t;
private:
union {
std::array<uint8_t, 4> _bytes; // IPv4 address
value_t _value;
static_assert(sizeof(_bytes) == sizeof(_value));
};
public:
// Constructors
constexpr ip_address_t() noexcept : _value{0} {}
constexpr ip_address_t(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3) noexcept : _bytes{b0, b1, b2, b3} {}
constexpr explicit ip_address_t(value_t address) noexcept : _value{address} {}
constexpr explicit ip_address_t(ip4_addr_t address) noexcept : _value{address.addr} {}
constexpr explicit ip_address_t(esp_ip4_addr_t address) noexcept : _value{address.addr} {}
constexpr ip_address_t(std::array<uint8_t, 4> bytes) noexcept : _bytes{bytes} {}
// Access the raw byte array containing the address. Because this returns a pointer
// to the internal structure rather than a copy of the address this function should only
// be used when you know that the usage of the returned uint8_t* will be transient and not
// stored.
constexpr std::array<uint8_t, 4> &bytes() noexcept { return _bytes; }
constexpr const std::array<uint8_t, 4> &bytes() const noexcept { return _bytes; }
constexpr value_t &value() noexcept { return _value; }
constexpr const value_t &value() const noexcept { return _value; }
friend constexpr bool operator==(const ip_address_t &left, const ip_address_t &right) noexcept { return left._value == right._value; }
friend constexpr bool operator!=(const ip_address_t &left, const ip_address_t &right) noexcept { return !(left == right); }
// Overloaded index operator to allow getting and setting individual octets of the address
constexpr uint8_t &operator[](int index) noexcept { return _bytes[index]; }
constexpr const uint8_t &operator[](int index) const noexcept { return _bytes[index]; }
// Overloaded copy operators to allow initialisation of ip_address_t objects from other types
//constexpr ip_address_t& operator=(const ip_address_t &other) noexcept { _value = other._value; return *this; }
constexpr ip_address_t& operator=(std::array<uint8_t, 4> bytes) noexcept { _bytes = bytes; return *this; }
constexpr ip_address_t& operator=(value_t value) noexcept { _value = value; return *this; }
};
template<> std::expected<ip_address_t, std::string> fromString<ip_address_t>(std::string_view str);
std::string toString(ip_address_t val);
std::string toString(const std::optional<ip_address_t> &val);
ip_address_t wifi_calculate_network_id(ip_address_t ip, ip_address_t subnet);
ip_address_t wifi_calculate_broadcast(ip_address_t ip, ip_address_t subnet);
uint8_t wifi_calculate_subnet_cidr(ip_address_t subnetMask);
std::string toString(ip4_addr_t val);
std::string toString(const ip6_addr_t &val);
std::string toString(ip_addr_t val);
inline std::string toString(const esp_ip4_addr_t &val)
{ return toString(*reinterpret_cast<const ip4_addr_t *>(&val)); }
inline std::string toString(const esp_ip6_addr_t &val)
{ return toString(*reinterpret_cast<const ip6_addr_t *>(&val)); }
std::string toString(const esp_ip_addr_t &val);
} // namespace wifi_stack