Compare commits
1 Commits
main
...
linux-spli
Author | SHA1 | Date | |
---|---|---|---|
43bad1f153 |
@ -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
|
||||
)
|
||||
|
||||
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
Reference in New Issue
Block a user