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