Imported existing sources
This commit is contained in:
39
CMakeLists.txt
Normal file
39
CMakeLists.txt
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
set(headers
|
||||||
|
src/espwifistack.h
|
||||||
|
src/espwifistackconfig.h
|
||||||
|
src/espwifistackenums.h
|
||||||
|
src/espwifiutils.h
|
||||||
|
)
|
||||||
|
|
||||||
|
set(sources
|
||||||
|
src/espwifistack.cpp
|
||||||
|
src/espwifistackenums.cpp
|
||||||
|
src/espwifiutils.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
set(dependencies
|
||||||
|
cpputils
|
||||||
|
espchrono
|
||||||
|
espcpputils
|
||||||
|
expected
|
||||||
|
)
|
||||||
|
|
||||||
|
idf_component_register(
|
||||||
|
INCLUDE_DIRS
|
||||||
|
src
|
||||||
|
SRCS
|
||||||
|
${headers}
|
||||||
|
${sources}
|
||||||
|
REQUIRES
|
||||||
|
${dependencies}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_options(${COMPONENT_TARGET}
|
||||||
|
PRIVATE
|
||||||
|
-fstack-reuse=all
|
||||||
|
-fstack-protector-all
|
||||||
|
-Wno-unused-function
|
||||||
|
-Wno-deprecated-declarations
|
||||||
|
-Wno-missing-field-initializers
|
||||||
|
-Wno-parentheses
|
||||||
|
)
|
39
Kconfig.projbuild
Normal file
39
Kconfig.projbuild
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
menu "Simple WiFi Stack settings"
|
||||||
|
|
||||||
|
choice LOG_LOCAL_LEVEL_WIFI_STACK
|
||||||
|
bool "WIFI_STACK log verbosity"
|
||||||
|
default LOG_LOCAL_LEVEL_WIFI_STACK_INFO
|
||||||
|
help
|
||||||
|
Specify how much output to compile into the binary.
|
||||||
|
You can set lower verbosity level at runtime using
|
||||||
|
esp_log_level_set function.
|
||||||
|
|
||||||
|
Note that this setting limits which log statements
|
||||||
|
are compiled into the program. So setting this to,
|
||||||
|
say, "Warning" would mean that changing log level
|
||||||
|
to "Debug" at runtime will not be possible.
|
||||||
|
|
||||||
|
config LOG_LOCAL_LEVEL_WIFI_STACK_NONE
|
||||||
|
bool "No output"
|
||||||
|
config LOG_LOCAL_LEVEL_WIFI_STACK_ERROR
|
||||||
|
bool "Error"
|
||||||
|
config LOG_LOCAL_LEVEL_WIFI_STACK_WARN
|
||||||
|
bool "Warning"
|
||||||
|
config LOG_LOCAL_LEVEL_WIFI_STACK_INFO
|
||||||
|
bool "Info"
|
||||||
|
config LOG_LOCAL_LEVEL_WIFI_STACK_DEBUG
|
||||||
|
bool "Debug"
|
||||||
|
config LOG_LOCAL_LEVEL_WIFI_STACK_VERBOSE
|
||||||
|
bool "Verbose"
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
config LOG_LOCAL_LEVEL_WIFI_STACK
|
||||||
|
int
|
||||||
|
default 0 if LOG_LOCAL_LEVEL_WIFI_STACK_NONE
|
||||||
|
default 1 if LOG_LOCAL_LEVEL_WIFI_STACK_ERROR
|
||||||
|
default 2 if LOG_LOCAL_LEVEL_WIFI_STACK_WARN
|
||||||
|
default 3 if LOG_LOCAL_LEVEL_WIFI_STACK_INFO
|
||||||
|
default 4 if LOG_LOCAL_LEVEL_WIFI_STACK_DEBUG
|
||||||
|
default 5 if LOG_LOCAL_LEVEL_WIFI_STACK_VERBOSE
|
||||||
|
|
||||||
|
endmenu
|
2027
src/espwifistack.cpp
Normal file
2027
src/espwifistack.cpp
Normal file
File diff suppressed because it is too large
Load Diff
59
src/espwifistack.h
Normal file
59
src/espwifistack.h
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// system includes
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
// esp-idf includes
|
||||||
|
#include <esp_wifi.h>
|
||||||
|
#include <esp_wifi_types.h>
|
||||||
|
#include <esp_netif_types.h>
|
||||||
|
|
||||||
|
// 3rdparty lib includes
|
||||||
|
#include <tl/expected.hpp>
|
||||||
|
|
||||||
|
// local includes
|
||||||
|
#include "espwifistackconfig.h"
|
||||||
|
#include "espwifistackenums.h"
|
||||||
|
#include "espwifiutils.h"
|
||||||
|
#include "espchrono.h"
|
||||||
|
#include "cppsignal.h"
|
||||||
|
|
||||||
|
namespace wifi_stack {
|
||||||
|
struct scan_result
|
||||||
|
{
|
||||||
|
std::vector<wifi_ap_record_t> entries;
|
||||||
|
espchrono::millis_clock::time_point finished;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern esp_netif_t* esp_netifs[ESP_IF_MAX];
|
||||||
|
|
||||||
|
extern const WiFiState &wifiStateMachineState;
|
||||||
|
|
||||||
|
extern cpputils::Signal<> scanResultChanged;
|
||||||
|
|
||||||
|
//! Call once at startup
|
||||||
|
void init(const config &config);
|
||||||
|
|
||||||
|
//! Call repeatedly, approx. every 100ms
|
||||||
|
void update(const config &config);
|
||||||
|
|
||||||
|
//! Tells the status of the STA interface (connected, ...)
|
||||||
|
WiFiStaStatus get_sta_status();
|
||||||
|
|
||||||
|
//! Tries to begin a new scan, if succeeds clears the old scan result
|
||||||
|
esp_err_t begin_scan(const config &config);
|
||||||
|
|
||||||
|
//! Tells the status of the currently running scan (finished, ...)
|
||||||
|
WiFiScanStatus get_scan_status();
|
||||||
|
|
||||||
|
//! Retrieves the current scan result (TODO: create a fresh container
|
||||||
|
//! every time to free memory and avoid cross thread access crashes)
|
||||||
|
const std::optional<scan_result> &get_scan_result();
|
||||||
|
|
||||||
|
//! Clears the scan result
|
||||||
|
void delete_scan_result();
|
||||||
|
|
||||||
|
tl::expected<wifi_ap_record_t, std::string> get_sta_ap_info();
|
||||||
|
|
||||||
|
} // namespace wifi_stack
|
94
src/espwifistackconfig.h
Normal file
94
src/espwifistackconfig.h
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// system includes
|
||||||
|
#include <string>
|
||||||
|
#include <array>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
// esp-idf includes
|
||||||
|
#include <esp_wifi_types.h>
|
||||||
|
|
||||||
|
// local includes
|
||||||
|
#include "espwifiutils.h"
|
||||||
|
|
||||||
|
namespace wifi_stack {
|
||||||
|
struct wifi_entry
|
||||||
|
{
|
||||||
|
std::string ssid;
|
||||||
|
std::string key;
|
||||||
|
|
||||||
|
friend bool operator==(const wifi_entry &left, const wifi_entry &right)
|
||||||
|
{
|
||||||
|
return left.ssid == right.ssid &&
|
||||||
|
left.key == right.key;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator!=(const wifi_entry &left, const wifi_entry &right)
|
||||||
|
{
|
||||||
|
return !(left == right);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ap_config : public wifi_entry
|
||||||
|
{
|
||||||
|
int channel;
|
||||||
|
wifi_auth_mode_t authmode;
|
||||||
|
bool ssid_hidden;
|
||||||
|
int max_connection;
|
||||||
|
uint16_t beacon_interval;
|
||||||
|
ip_address_t ip;
|
||||||
|
ip_address_t subnet;
|
||||||
|
|
||||||
|
friend bool operator==(const ap_config &left, const ap_config &right)
|
||||||
|
{
|
||||||
|
return *static_cast<const wifi_entry *>(&left) == *static_cast<const wifi_entry *>(&right) &&
|
||||||
|
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.ip == right.ip &&
|
||||||
|
left.subnet == right.subnet;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator!=(const ap_config &left, const ap_config &right)
|
||||||
|
{
|
||||||
|
return !(left == right);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ip_setting
|
||||||
|
{
|
||||||
|
bool dhcpEnabled;
|
||||||
|
ip_address_t staticIp;
|
||||||
|
ip_address_t staticGateway;
|
||||||
|
ip_address_t staticSubnet;
|
||||||
|
ip_address_t staticDns1;
|
||||||
|
ip_address_t staticDns2;
|
||||||
|
|
||||||
|
friend bool operator==(const ip_setting &left, const ip_setting &right)
|
||||||
|
{
|
||||||
|
return left.dhcpEnabled == right.dhcpEnabled &&
|
||||||
|
left.staticIp == right.staticIp &&
|
||||||
|
left.staticGateway == right.staticGateway &&
|
||||||
|
left.staticSubnet == right.staticSubnet &&
|
||||||
|
left.staticDns1 == right.staticDns1 &&
|
||||||
|
left.staticDns2 == right.staticDns2;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator!=(const ip_setting &left, const ip_setting &right)
|
||||||
|
{
|
||||||
|
return !(left == right);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct config
|
||||||
|
{
|
||||||
|
bool wifiEnabled;
|
||||||
|
std::string hostname;
|
||||||
|
std::array<wifi_entry, 10> wifis;
|
||||||
|
ip_setting sta_ip;
|
||||||
|
ap_config ap;
|
||||||
|
int8_t min_rssi;
|
||||||
|
};
|
||||||
|
} // namespace wifi_stack
|
9
src/espwifistackenums.cpp
Normal file
9
src/espwifistackenums.cpp
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#include "espwifistackenums.h"
|
||||||
|
|
||||||
|
namespace wifi_stack {
|
||||||
|
|
||||||
|
IMPLEMENT_TYPESAFE_ENUM(WiFiState, : uint8_t, WiFiStateValues)
|
||||||
|
IMPLEMENT_TYPESAFE_ENUM(WiFiStaStatus, : uint8_t, WiFiStaStatusValues)
|
||||||
|
IMPLEMENT_TYPESAFE_ENUM(WiFiScanStatus, : uint8_t, WiFiScanStatusValues)
|
||||||
|
|
||||||
|
} // namespace wifi_stack
|
35
src/espwifistackenums.h
Normal file
35
src/espwifistackenums.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// local 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(WL_IDLE_STATUS) \
|
||||||
|
x(WL_NO_SSID_AVAIL) \
|
||||||
|
x(WL_SCAN_COMPLETED) \
|
||||||
|
x(WL_CONNECTED) \
|
||||||
|
x(WL_CONNECT_FAILED) \
|
||||||
|
x(WL_CONNECTION_LOST) \
|
||||||
|
x(WL_DISCONNECTED) \
|
||||||
|
x(WL_CONNECTING) \
|
||||||
|
x(WL_DISCONNECTING) \
|
||||||
|
x(WL_NO_SHIELD)
|
||||||
|
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
|
193
src/espwifiutils.cpp
Normal file
193
src/espwifiutils.cpp
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
#include "espwifiutils.h"
|
||||||
|
|
||||||
|
// esp-idf includes
|
||||||
|
#include <esp_log.h>
|
||||||
|
|
||||||
|
namespace wifi_stack {
|
||||||
|
namespace {
|
||||||
|
constexpr const char * const TAG = "WIFI_STACK";
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
bool goe_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 goe_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 encryptionType)
|
||||||
|
{
|
||||||
|
switch (encryptionType)
|
||||||
|
{
|
||||||
|
case WIFI_AUTH_OPEN: return "WIFI_AUTH_OPEN";
|
||||||
|
case WIFI_AUTH_WEP: return "WIFI_AUTH_WEP";
|
||||||
|
case WIFI_AUTH_WPA_PSK: return "WIFI_AUTH_WPA_PSK";
|
||||||
|
case WIFI_AUTH_WPA2_PSK: return "WIFI_AUTH_WPA2_PSK";
|
||||||
|
case WIFI_AUTH_WPA_WPA2_PSK: return "WIFI_AUTH_WPA_WPA2_PSK";
|
||||||
|
case WIFI_AUTH_WPA2_ENTERPRISE: return "WIFI_AUTH_WPA2_ENTERPRISE";
|
||||||
|
case WIFI_AUTH_WPA3_PSK: return "WIFI_AUTH_WPA3_PSK";
|
||||||
|
case WIFI_AUTH_WPA2_WPA3_PSK: return "WIFI_AUTH_WPA2_WPA3_PSK";
|
||||||
|
case WIFI_AUTH_WAPI_PSK: return "WIFI_AUTH_WAPI_PSK";
|
||||||
|
case WIFI_AUTH_MAX: return "WIFI_AUTH_MAX";
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::string{"Unknown wifi_auth_mode_t("} + std::to_string(int(encryptionType)) + ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string toString(const mac_t &mac)
|
||||||
|
{
|
||||||
|
char macStr[18]{0};
|
||||||
|
std::snprintf(macStr, 18, "%02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX",
|
||||||
|
mac.at(0), mac.at(1), mac.at(2), mac.at(3), mac.at(4), mac.at(5));
|
||||||
|
return std::string{macStr};
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ip_address_t::fromString(std::string_view address)
|
||||||
|
{
|
||||||
|
// TODO: add support for "a", "a.b", "a.b.c" formats
|
||||||
|
// TODO: replace with scanf for better performance
|
||||||
|
|
||||||
|
uint16_t acc = 0; // Accumulator
|
||||||
|
uint8_t dots = 0;
|
||||||
|
|
||||||
|
for (char c : address)
|
||||||
|
{
|
||||||
|
if (c >= '0' && c <= '9')
|
||||||
|
{
|
||||||
|
acc = acc * 10 + (c - '0');
|
||||||
|
if (acc > 255) {
|
||||||
|
// Value out of [0..255] range
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (c == '.')
|
||||||
|
{
|
||||||
|
if (dots == 3) {
|
||||||
|
// Too much dots (there must be 3 dots)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_bytes[dots++] = acc;
|
||||||
|
acc = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Invalid char
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dots != 3) {
|
||||||
|
// Too few dots (there must be 3 dots)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_bytes[3] = acc;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string toString(const ip_address_t &address)
|
||||||
|
{
|
||||||
|
char szRet[16];
|
||||||
|
sprintf(szRet,"%hhu.%hhu.%hhu.%hhu", address[0], address[1], address[2], address[3]);
|
||||||
|
return std::string{szRet};
|
||||||
|
}
|
||||||
|
|
||||||
|
ip_address_t goe_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 goe_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 goe_wifi_calculate_subnet_cidr(ip_address_t subnetMask)
|
||||||
|
{
|
||||||
|
uint8_t CIDR = 0;
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < 4; i++) {
|
||||||
|
if (subnetMask[i] == 0x80) // 128
|
||||||
|
CIDR += 1;
|
||||||
|
else if (subnetMask[i] == 0xC0) // 192
|
||||||
|
CIDR += 2;
|
||||||
|
else if (subnetMask[i] == 0xE0) // 224
|
||||||
|
CIDR += 3;
|
||||||
|
else if (subnetMask[i] == 0xF0) // 242
|
||||||
|
CIDR += 4;
|
||||||
|
else if (subnetMask[i] == 0xF8) // 248
|
||||||
|
CIDR += 5;
|
||||||
|
else if (subnetMask[i] == 0xFC) // 252
|
||||||
|
CIDR += 6;
|
||||||
|
else if (subnetMask[i] == 0xFE) // 254
|
||||||
|
CIDR += 7;
|
||||||
|
else if (subnetMask[i] == 0xFF) // 255
|
||||||
|
CIDR += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CIDR;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
default:
|
||||||
|
ESP_LOGW(TAG, "unknown ipv%i", val.type);
|
||||||
|
return "unknown ipv" + std::to_string(val.type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace wifi_stack
|
103
src/espwifiutils.h
Normal file
103
src/espwifiutils.h
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// system includes
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
// esp-idf includes
|
||||||
|
#include <esp_wifi_types.h>
|
||||||
|
#include <esp_netif_ip_addr.h>
|
||||||
|
#include <lwip/ip_addr.h>
|
||||||
|
|
||||||
|
namespace wifi_stack {
|
||||||
|
bool goe_wifi_ap_config_equal(const wifi_ap_config_t& lhs, const wifi_ap_config_t& rhs);
|
||||||
|
bool goe_wifi_sta_config_equal(const wifi_sta_config_t& lhs, const wifi_sta_config_t& rhs);
|
||||||
|
|
||||||
|
std::string toString(wifi_auth_mode_t encryptionType);
|
||||||
|
|
||||||
|
// A class to make it easier to handle and pass around mac addresses / bssids
|
||||||
|
|
||||||
|
class mac_t : public std::array<uint8_t, 6>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using std::array<uint8_t, 6>::array;
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string toString(const mac_t &mac);
|
||||||
|
|
||||||
|
// 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} {}
|
||||||
|
|
||||||
|
bool fromString(std::string_view address);
|
||||||
|
|
||||||
|
// 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 std::array<uint8_t, 4> bytes() const noexcept { return _bytes; }
|
||||||
|
|
||||||
|
constexpr 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 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; }
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string toString(const ip_address_t &val);
|
||||||
|
|
||||||
|
ip_address_t goe_wifi_calculate_network_id(ip_address_t ip, ip_address_t subnet);
|
||||||
|
ip_address_t goe_wifi_calculate_broadcast(ip_address_t ip, ip_address_t subnet);
|
||||||
|
uint8_t goe_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)); }
|
||||||
|
|
||||||
|
} // namespace wifi_stack
|
Reference in New Issue
Block a user