Implemented separate statip ip configurations per sta entry

This commit is contained in:
2021-08-01 21:44:05 +02:00
parent 07ad3383eb
commit 502fb97e22
5 changed files with 181 additions and 178 deletions

View File

@@ -16,6 +16,7 @@ set(dependencies
espchrono espchrono
espcpputils espcpputils
expected expected
fmt
) )
idf_component_register( idf_component_register(

View File

@@ -20,6 +20,9 @@
#include <esp_netif_net_stack.h> #include <esp_netif_net_stack.h>
#endif #endif
// 3rdparty lib includes
#include <fmt/core.h>
// local includes // local includes
#include "strutils.h" #include "strutils.h"
#include "delayedconstruction.h" #include "delayedconstruction.h"
@@ -95,8 +98,7 @@ bool scanResultChangedFlag{};
struct ConnectPlanItem struct ConnectPlanItem
{ {
std::string ssid; wifi_entry config;
std::string key;
uint8_t channel; uint8_t channel;
wifi_auth_mode_t authmode; wifi_auth_mode_t authmode;
int8_t rssi; int8_t rssi;
@@ -247,15 +249,16 @@ esp_err_t goe_wifi_set_esp_interface_ip(esp_interface_t interface, const std::op
return ESP_FAIL; return ESP_FAIL;
} }
esp_netif_t *esp_netif = esp_netifs[interface]; esp_netif_t * const esp_netif = esp_netifs[interface];
{ {
esp_netif_dhcp_status_t status = ESP_NETIF_DHCP_INIT; esp_netif_dhcp_status_t status;
if (const auto result = esp_netif_dhcpc_get_status(esp_netif, &status); result != ESP_OK) if (const auto result = esp_netif_dhcpc_get_status(esp_netif, &status); result != ESP_OK)
{ {
ESP_LOGE(TAG, "esp_netif_dhcpc_get_status() failed with %s", esp_err_to_name(result)); ESP_LOGE(TAG, "esp_netif_dhcpc_get_status() failed with %s", esp_err_to_name(result));
return result; return result;
} }
ESP_LOGI(TAG, "esp_netif_dhcpc_get_status() resulted in %s", toString(status).c_str());
} }
if (const auto result = esp_netif_dhcpc_stop(esp_netif); !cpputils::is_in(result, ESP_OK, ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED)) if (const auto result = esp_netif_dhcpc_stop(esp_netif); !cpputils::is_in(result, ESP_OK, ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED))
@@ -512,9 +515,9 @@ cleanup:
} }
esp_err_t goe_wifi_sta_disconnect(const config &config, bool wifioff = false, bool eraseap = false); esp_err_t goe_wifi_sta_disconnect(const config &config, bool wifioff = false, bool eraseap = false);
esp_err_t goe_wifi_sta_begin(const config &config, const std::string &ssid, const std::string &passphrase = {}, int32_t channel = 0, esp_err_t goe_wifi_sta_begin(const config &config, const wifi_entry &sta_config,
std::optional<mac_t> bssid = {}, bool connect = true); int32_t channel = 0, std::optional<mac_t> bssid = {}, bool connect = true);
esp_err_t goe_wifi_sta_begin(const config &config); esp_err_t goe_wifi_sta_restart(const config &config);
void goe_wifi_event_callback(const config &config, const goe_wifi_event_t &event) void goe_wifi_event_callback(const config &config, const goe_wifi_event_t &event)
{ {
@@ -590,8 +593,8 @@ void goe_wifi_event_callback(const config &config, const goe_wifi_event_t &event
{ {
if (const auto result = goe_wifi_sta_disconnect(config); result != ESP_OK) if (const auto result = goe_wifi_sta_disconnect(config); result != ESP_OK)
ESP_LOGE(TAG, "goe_wifi_sta_disconnect() failed with %s", esp_err_to_name(result)); ESP_LOGE(TAG, "goe_wifi_sta_disconnect() failed with %s", esp_err_to_name(result));
if (const auto result = goe_wifi_sta_begin(config); result != ESP_OK) if (const auto result = goe_wifi_sta_restart(config); result != ESP_OK)
ESP_LOGE(TAG, "goe_wifi_sta_begin() failed with %s", esp_err_to_name(result)); ESP_LOGE(TAG, "goe_wifi_sta_restart() failed with %s", esp_err_to_name(result));
} }
break; break;
@@ -1202,16 +1205,21 @@ esp_err_t goe_wifi_set_mode(wifi_mode_t m, const config &config)
esp_err_t goe_wifi_set_ap_ip(const config &config, const static_ip_config &ip) esp_err_t goe_wifi_set_ap_ip(const config &config, const static_ip_config &ip)
{ {
using wifi_stack::toString;
ESP_LOGI(TAG, "ip=%s subnet=%s gateway=%s", toString(ip.ip).c_str(), toString(ip.subnet).c_str(), toString(ip.gateway).c_str()); ESP_LOGI(TAG, "ip=%s subnet=%s gateway=%s", toString(ip.ip).c_str(), toString(ip.subnet).c_str(), toString(ip.gateway).c_str());
esp_netif_t *esp_netif = esp_netifs[ESP_IF_WIFI_AP]; esp_netif_t * const esp_netif = esp_netifs[ESP_IF_WIFI_AP];
esp_netif_dhcp_status_t status = ESP_NETIF_DHCP_INIT; {
esp_netif_dhcp_status_t status;
if (const auto result = esp_netif_dhcps_get_status(esp_netif, &status); result != ESP_OK) if (const auto result = esp_netif_dhcps_get_status(esp_netif, &status); result != ESP_OK)
{ {
ESP_LOGE(TAG, "esp_netif_dhcps_get_status() failed with %s", esp_err_to_name(result)); ESP_LOGE(TAG, "esp_netif_dhcps_get_status() failed with %s", esp_err_to_name(result));
return result; return result;
} }
ESP_LOGI(TAG, "esp_netif_dhcps_get_status() resulted in %s", toString(status).c_str());
}
for (int i = 0; ; i++) for (int i = 0; ; i++)
{ {
@@ -1252,12 +1260,7 @@ esp_err_t goe_wifi_set_ap_ip(const config &config, const static_ip_config &ip)
lease.start_ip.addr = ip.ip.value() + (1 << 24); lease.start_ip.addr = ip.ip.value() + (1 << 24);
lease.end_ip.addr = ip.ip.value() + (11 << 24); lease.end_ip.addr = ip.ip.value() + (11 << 24);
if (const auto result = tcpip_adapter_dhcps_option( if (const auto result = tcpip_adapter_dhcps_option(ESP_NETIF_OP_SET, ESP_NETIF_REQUESTED_IP_ADDRESS, &lease, sizeof(dhcps_lease_t)); result != ESP_OK)
(tcpip_adapter_dhcp_option_mode_t)TCPIP_ADAPTER_OP_SET,
(tcpip_adapter_dhcp_option_id_t)REQUESTED_IP_ADDRESS,
(void*)&lease,
sizeof(dhcps_lease_t)
); result != ESP_OK)
{ {
ESP_LOGE(TAG, "tcpip_adapter_dhcps_option() failed with %s", esp_err_to_name(result)); ESP_LOGE(TAG, "tcpip_adapter_dhcps_option() failed with %s", esp_err_to_name(result));
return result; return result;
@@ -1311,8 +1314,8 @@ wifi_config_t make_sta_config(std::string_view ssid, std::string_view password,
return wifi_config; return wifi_config;
} }
esp_err_t goe_wifi_sta_begin(const config &config, const std::string &ssid, const std::string &passphrase, int32_t channel, esp_err_t goe_wifi_sta_begin(const config &config, const wifi_entry &sta_config,
std::optional<mac_t> bssid, bool connect) int32_t channel, std::optional<mac_t> bssid, bool connect)
{ {
if (const auto result = goe_wifi_enable_sta(true, config); result != ESP_OK) if (const auto result = goe_wifi_enable_sta(true, config); result != ESP_OK)
{ {
@@ -1320,34 +1323,34 @@ esp_err_t goe_wifi_sta_begin(const config &config, const std::string &ssid, cons
return result; return result;
} }
if (ssid.empty()) if (sta_config.ssid.empty())
{ {
ESP_LOGE(TAG, "SSID missing!"); ESP_LOGE(TAG, "SSID missing!");
return ESP_FAIL; return ESP_FAIL;
} }
if (ssid.size() > 31) if (sta_config.ssid.size() > 31)
{ {
ESP_LOGE(TAG, "SSID too long! (size=%zd)", ssid.size()); ESP_LOGE(TAG, "SSID too long! (size=%zd)", sta_config.ssid.size());
return ESP_FAIL; return ESP_FAIL;
} }
if (!passphrase.empty()) if (!sta_config.key.empty())
{ {
if (passphrase.size() < 8) if (sta_config.key.size() < 8)
{ {
ESP_LOGE(TAG, "passphrase too short! (size=%zd)", passphrase.size()); ESP_LOGE(TAG, "key too short! (size=%zd)", sta_config.key.size());
return ESP_FAIL; return ESP_FAIL;
} }
if (passphrase.size() > 63) if (sta_config.key.size() > 63)
{ {
ESP_LOGE(TAG, "passphrase too long! (size=%zd)", passphrase.size()); ESP_LOGE(TAG, "key too long! (size=%zd)", sta_config.key.size());
return ESP_FAIL; return ESP_FAIL;
} }
} }
wifi_config_t conf = make_sta_config(ssid, passphrase, config.sta.min_rssi, bssid, channel); wifi_config_t conf = make_sta_config(sta_config.ssid, sta_config.key, config.sta.min_rssi, bssid, channel);
wifi_config_t current_conf; wifi_config_t current_conf;
if (const auto result = esp_wifi_get_config(WIFI_IF_STA, &current_conf); result != ESP_OK) if (const auto result = esp_wifi_get_config(WIFI_IF_STA, &current_conf); result != ESP_OK)
@@ -1384,21 +1387,21 @@ esp_err_t goe_wifi_sta_begin(const config &config, const std::string &ssid, cons
} }
} }
if (const auto result = goe_wifi_set_esp_interface_ip(ESP_IF_WIFI_STA, config.sta.static_ip); result != ESP_OK) if (const auto result = goe_wifi_set_esp_interface_ip(ESP_IF_WIFI_STA, sta_config.static_ip); result != ESP_OK)
{ {
ESP_LOGE(TAG, "goe_wifi_set_esp_interface_ip() for STA failed with %s", esp_err_to_name(result)); ESP_LOGE(TAG, "goe_wifi_set_esp_interface_ip() for STA failed with %s", esp_err_to_name(result));
return result; return result;
} }
last_sta_static_ip = config.sta.static_ip; last_sta_static_ip = sta_config.static_ip;
if (const auto result = goe_wifi_set_esp_interface_dns(ESP_IF_WIFI_STA, config.sta.static_dns); result != ESP_OK) if (const auto result = goe_wifi_set_esp_interface_dns(ESP_IF_WIFI_STA, sta_config.static_dns); result != ESP_OK)
{ {
ESP_LOGE(TAG, "goe_wifi_set_esp_interface_dns() for STA failed with %s", esp_err_to_name(result)); ESP_LOGE(TAG, "goe_wifi_set_esp_interface_dns() for STA failed with %s", esp_err_to_name(result));
return result; return result;
} }
last_sta_static_dns = config.sta.static_dns; last_sta_static_dns = sta_config.static_dns;
if (connect) if (connect)
{ {
@@ -1416,7 +1419,7 @@ esp_err_t goe_wifi_sta_begin(const config &config, const std::string &ssid, cons
return ESP_OK; return ESP_OK;
} }
esp_err_t goe_wifi_sta_begin(const config &config) esp_err_t goe_wifi_sta_restart(const config &config)
{ {
if (const auto result = goe_wifi_enable_sta(true, config); result != ESP_OK) if (const auto result = goe_wifi_enable_sta(true, config); result != ESP_OK)
{ {
@@ -1437,21 +1440,23 @@ esp_err_t goe_wifi_sta_begin(const config &config)
return result; return result;
} }
if (const auto result = goe_wifi_set_esp_interface_ip(ESP_IF_WIFI_STA, config.sta.static_ip); result != ESP_OK) // TODO
if (const auto result = goe_wifi_set_esp_interface_ip(ESP_IF_WIFI_STA, /*config.sta.static_ip*/last_sta_static_ip); result != ESP_OK)
{ {
ESP_LOGE(TAG, "goe_wifi_set_esp_interface_ip() for STA failed with %s", esp_err_to_name(result)); ESP_LOGE(TAG, "goe_wifi_set_esp_interface_ip() for STA failed with %s", esp_err_to_name(result));
return result; return result;
} }
last_sta_static_ip = config.sta.static_ip; //last_sta_static_ip = config.sta.static_ip;
if (const auto result = goe_wifi_set_esp_interface_dns(ESP_IF_WIFI_STA, config.sta.static_dns); result != ESP_OK) if (const auto result = goe_wifi_set_esp_interface_dns(ESP_IF_WIFI_STA, /*config.sta.static_dns*/last_sta_static_dns); result != ESP_OK)
{ {
ESP_LOGE(TAG, "goe_wifi_set_esp_interface_dns() for STA failed with %s", esp_err_to_name(result)); ESP_LOGE(TAG, "goe_wifi_set_esp_interface_dns() for STA failed with %s", esp_err_to_name(result));
return result; return result;
} }
last_sta_static_dns = config.sta.static_dns; //last_sta_static_dns = config.sta.static_dns;
if (get_sta_status() != WiFiStaStatus::WL_CONNECTED) if (get_sta_status() != WiFiStaStatus::WL_CONNECTED)
{ {
@@ -1606,7 +1611,8 @@ bool buildConnectPlan(const config &config, const scan_result &scanResult)
std::string_view scanSSID{(const char *)entry.ssid}; std::string_view scanSSID{(const char *)entry.ssid};
// avoid duplicates // avoid duplicates
if (std::any_of(std::begin(connectPlan), std::end(connectPlan), [&scanSSID](const auto &entry){ return cpputils::stringEqualsIgnoreCase(entry.ssid, scanSSID); })) if (std::any_of(std::begin(connectPlan), std::end(connectPlan), [&scanSSID](const auto &entry){
return cpputils::stringEqualsIgnoreCase(entry.config.ssid, scanSSID); }))
continue; continue;
const auto iter = std::find_if(std::begin(config.sta.wifis), std::end(config.sta.wifis), const auto iter = std::find_if(std::begin(config.sta.wifis), std::end(config.sta.wifis),
@@ -1614,8 +1620,7 @@ bool buildConnectPlan(const config &config, const scan_result &scanResult)
if (iter != std::end(config.sta.wifis)) if (iter != std::end(config.sta.wifis))
{ {
connectPlan.emplace_back(ConnectPlanItem{ connectPlan.emplace_back(ConnectPlanItem{
.ssid = std::string{scanSSID}, .config = *iter,
.key = std::string{iter->key},
.channel = entry.primary, .channel = entry.primary,
.authmode = entry.authmode, .authmode = entry.authmode,
.rssi = entry.rssi, .rssi = entry.rssi,
@@ -1635,33 +1640,17 @@ bool buildConnectPlan(const config &config, const scan_result &scanResult)
const auto entry = connectPlan.front(); const auto entry = connectPlan.front();
connectPlan.erase(std::begin(connectPlan)); connectPlan.erase(std::begin(connectPlan));
ESP_LOGI(TAG, "connecting to %s (auth=%s, key=%s, channel=%i, rssi=%i, bssid=%s)", ESP_LOGI(TAG, "connecting to %s (auth=%s, key=%s, channel=%i, rssi=%i, bssid=%s)",
entry.ssid.c_str(), entry.config.ssid.c_str(),
toString(entry.authmode).c_str(), toString(entry.authmode).c_str(),
entry.key.c_str(), entry.config.key.c_str(),
entry.channel, entry.channel,
entry.rssi, entry.rssi,
toString(entry.bssid).c_str() toString(entry.bssid).c_str()
); );
_lastConnect = espchrono::millis_clock::now(); _lastConnect = espchrono::millis_clock::now();
// if (const auto result = goe_wifi_set_esp_interface_ip(ESP_IF_WIFI_STA, config.sta.static_ip); result != ESP_OK)
// {
// ESP_LOGE(TAG, "goe_wifi_set_esp_interface_ip() for STA failed with %s", esp_err_to_name(result));
// return result;
// }
// last_sta_static_ip = config.sta.static_ip;
// if (const auto result = goe_wifi_set_esp_interface_dns(ESP_IF_WIFI_STA, config.sta.static_dns); result != ESP_OK)
// {
// ESP_LOGE(TAG, "goe_wifi_set_esp_interface_dns() for STA failed with %s", esp_err_to_name(result));
// return result;
// }
// last_sta_static_dns = config.sta.static_dns;
_wifiConnectFailCounter = 0; _wifiConnectFailCounter = 0;
if (const auto result = goe_wifi_sta_begin(config, entry.ssid, entry.key, entry.channel, entry.bssid); result != ESP_OK) if (const auto result = goe_wifi_sta_begin(config, entry.config, entry.channel, entry.bssid); result != ESP_OK)
ESP_LOGE(TAG, "goe_wifi_sta_begin() failed with %s", esp_err_to_name(result)); ESP_LOGE(TAG, "goe_wifi_sta_begin() failed with %s", esp_err_to_name(result));
setWifiState(WiFiState::Connecting); setWifiState(WiFiState::Connecting);
@@ -1916,8 +1905,8 @@ void update(const config &config)
if (const auto result = goe_wifi_sta_disconnect(config); result != ESP_OK) if (const auto result = goe_wifi_sta_disconnect(config); result != ESP_OK)
ESP_LOGE(TAG, "goe_wifi_sta_disconnect() failed with %s", esp_err_to_name(result)); ESP_LOGE(TAG, "goe_wifi_sta_disconnect() failed with %s", esp_err_to_name(result));
if (const auto result = goe_wifi_sta_begin(config); result != ESP_OK) if (const auto result = goe_wifi_sta_restart(config); result != ESP_OK)
ESP_LOGE(TAG, "goe_wifi_sta_begin() failed with %s", esp_err_to_name(result)); ESP_LOGE(TAG, "goe_wifi_sta_restart() failed with %s", esp_err_to_name(result));
} }
} }
else else
@@ -1955,12 +1944,12 @@ void update(const config &config)
else if (const auto sta_info = get_sta_ap_info()) else if (const auto sta_info = get_sta_ap_info())
{ {
const std::string_view connectedSSID{reinterpret_cast<const char *>(sta_info->ssid)}; const std::string_view connectedSSID{reinterpret_cast<const char *>(sta_info->ssid)};
const auto configStillFound = std::any_of(std::begin(config.sta.wifis), std::end(config.sta.wifis), const auto iter = std::find_if(std::cbegin(config.sta.wifis), std::cend(config.sta.wifis),
[&connectedSSID](const auto &entry){ [&connectedSSID](const wifi_entry &entry){
return cpputils::stringEqualsIgnoreCase(entry.ssid, connectedSSID); return cpputils::stringEqualsIgnoreCase(entry.ssid, connectedSSID);
}); });
if (!configStillFound) if (iter == std::cend(config.sta.wifis))
{ {
ESP_LOGI(TAG, "disconnecting, because cannot find ssid in config anymore"); ESP_LOGI(TAG, "disconnecting, because cannot find ssid in config anymore");
lastWifisChecksum.clear(); lastWifisChecksum.clear();
@@ -1972,30 +1961,28 @@ void update(const config &config)
} }
else else
{ {
if (last_sta_static_ip != config.sta.static_ip) if (last_sta_static_ip != iter->static_ip ||
last_sta_static_dns != iter->static_dns)
{ {
ESP_LOGI(TAG, "wifi static ip config changed, applying new config"); ESP_LOGI(TAG, "wifi static ip/dns config changed, applying new config");
if (const auto result = goe_wifi_set_esp_interface_ip(ESP_IF_WIFI_STA, config.sta.static_ip); result != ESP_OK) if (const auto result = goe_wifi_set_esp_interface_ip(ESP_IF_WIFI_STA, iter->static_ip); result != ESP_OK)
{ {
ESP_LOGE(TAG, "goe_wifi_set_esp_interface_ip() for STA failed with %s", esp_err_to_name(result)); ESP_LOGE(TAG, "goe_wifi_set_esp_interface_ip() for STA failed with %s", esp_err_to_name(result));
//return result; //return result;
} }
else else
last_sta_static_ip = config.sta.static_ip;
}
if (last_sta_static_dns != config.sta.static_dns)
{ {
ESP_LOGI(TAG, "wifi static dns config changed, applying new config"); last_sta_static_ip = iter->static_ip;
if (const auto result = goe_wifi_set_esp_interface_dns(ESP_IF_WIFI_STA, config.sta.static_dns); result != ESP_OK) if (const auto result = goe_wifi_set_esp_interface_dns(ESP_IF_WIFI_STA, iter->static_dns); result != ESP_OK)
{ {
ESP_LOGE(TAG, "goe_wifi_set_esp_interface_dns() for STA failed with %s", esp_err_to_name(result)); ESP_LOGE(TAG, "goe_wifi_set_esp_interface_dns() for STA failed with %s", esp_err_to_name(result));
//return result; //return result;
} }
else else
last_sta_static_dns = config.sta.static_dns; last_sta_static_dns = iter->static_dns;
}
} }
} }
} }
@@ -2085,7 +2072,7 @@ tl::expected<wifi_ap_record_t, std::string> get_sta_ap_info()
else else
{ {
ESP_LOGW(TAG, "esp_wifi_sta_get_ap_info() failed with %s", esp_err_to_name(result)); ESP_LOGW(TAG, "esp_wifi_sta_get_ap_info() failed with %s", esp_err_to_name(result));
return tl::make_unexpected(std::string{"esp_wifi_sta_get_ap_info() failed with "} + esp_err_to_name(result)); return tl::make_unexpected(fmt::format("esp_wifi_sta_get_ap_info() failed with {}", esp_err_to_name(result)));
} }
} }
@@ -2097,7 +2084,7 @@ tl::expected<wifi_stack::mac_t, std::string> get_default_mac_addr()
else else
{ {
ESP_LOGE(TAG, "esp_efuse_mac_get_default() failed with %s", esp_err_to_name(result)); ESP_LOGE(TAG, "esp_efuse_mac_get_default() failed with %s", esp_err_to_name(result));
return tl::make_unexpected(std::string{"esp_efuse_mac_get_default() failed with "} + esp_err_to_name(result)); return tl::make_unexpected(fmt::format("esp_efuse_mac_get_default() failed with {}", esp_err_to_name(result)));
} }
} }
@@ -2109,7 +2096,7 @@ tl::expected<wifi_stack::mac_t, std::string> get_base_mac_addr()
else else
{ {
ESP_LOGE(TAG, "esp_base_mac_addr_get() failed with %s", esp_err_to_name(result)); ESP_LOGE(TAG, "esp_base_mac_addr_get() failed with %s", esp_err_to_name(result));
return tl::make_unexpected(std::string{"esp_base_mac_addr_get() failed with "} + esp_err_to_name(result)); return tl::make_unexpected(fmt::format("esp_base_mac_addr_get() failed with {}", esp_err_to_name(result)));
} }
} }
@@ -2120,7 +2107,7 @@ tl::expected<void, std::string> set_base_mac_addr(wifi_stack::mac_t mac_addr)
else else
{ {
ESP_LOGE(TAG, "esp_base_mac_addr_set() failed with %s", esp_err_to_name(result)); ESP_LOGE(TAG, "esp_base_mac_addr_set() failed with %s", esp_err_to_name(result));
return tl::make_unexpected(std::string{"esp_base_mac_addr_set() failed with "} + esp_err_to_name(result)); return tl::make_unexpected(fmt::format("esp_base_mac_addr_set() failed with {}", esp_err_to_name(result)));
} }
} }
@@ -2132,7 +2119,7 @@ tl::expected<tcpip_adapter_ip_info_t, std::string> get_ip_info(tcpip_adapter_if_
else else
{ {
ESP_LOGE(TAG, "tcpip_adapter_get_ip_info() failed with %s", esp_err_to_name(result)); ESP_LOGE(TAG, "tcpip_adapter_get_ip_info() failed with %s", esp_err_to_name(result));
return tl::make_unexpected(std::string{"tcpip_adapter_get_ip_info() failed with "} + esp_err_to_name(result)); return tl::make_unexpected(fmt::format("tcpip_adapter_get_ip_info() failed with {}", esp_err_to_name(result)));
} }
} }

View File

@@ -13,23 +13,6 @@
#include "espwifiutils.h" #include "espwifiutils.h"
namespace wifi_stack { 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 static_ip_config struct static_ip_config
{ {
ip_address_t ip; ip_address_t ip;
@@ -68,18 +51,35 @@ struct static_dns_config
} }
}; };
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_config struct sta_config
{ {
std::array<wifi_entry, 10> wifis; std::array<wifi_entry, 10> wifis;
std::optional<static_ip_config> static_ip;
static_dns_config static_dns;
int8_t min_rssi; int8_t min_rssi;
friend bool operator==(const sta_config &left, const sta_config &right) friend bool operator==(const sta_config &left, const sta_config &right)
{ {
return left.wifis == right.wifis && return left.wifis == right.wifis &&
left.static_ip == right.static_ip &&
left.static_dns == right.static_dns &&
left.min_rssi == right.min_rssi; left.min_rssi == right.min_rssi;
} }

View File

@@ -3,6 +3,9 @@
// esp-idf includes // esp-idf includes
#include <esp_log.h> #include <esp_log.h>
// 3rdparty lib includes
#include <fmt/core.h>
// local includes // local includes
#include "futurecpp.h" #include "futurecpp.h"
@@ -52,51 +55,80 @@ std::string toString(wifi_auth_mode_t authMode)
{ {
switch (authMode) switch (authMode)
{ {
case WIFI_AUTH_OPEN: return "WIFI_AUTH_OPEN"; case WIFI_AUTH_OPEN: return "OPEN";
case WIFI_AUTH_WEP: return "WIFI_AUTH_WEP"; case WIFI_AUTH_WEP: return "WEP";
case WIFI_AUTH_WPA_PSK: return "WIFI_AUTH_WPA_PSK"; case WIFI_AUTH_WPA_PSK: return "WPA_PSK";
case WIFI_AUTH_WPA2_PSK: return "WIFI_AUTH_WPA2_PSK"; case WIFI_AUTH_WPA2_PSK: return "WPA2_PSK";
case WIFI_AUTH_WPA_WPA2_PSK: return "WIFI_AUTH_WPA_WPA2_PSK"; case WIFI_AUTH_WPA_WPA2_PSK: return "WPA_WPA2_PSK";
case WIFI_AUTH_WPA2_ENTERPRISE: return "WIFI_AUTH_WPA2_ENTERPRISE"; case WIFI_AUTH_WPA2_ENTERPRISE: return "WPA2_ENTERPRISE";
case WIFI_AUTH_WPA3_PSK: return "WIFI_AUTH_WPA3_PSK"; case WIFI_AUTH_WPA3_PSK: return "WPA3_PSK";
case WIFI_AUTH_WPA2_WPA3_PSK: return "WIFI_AUTH_WPA2_WPA3_PSK"; case WIFI_AUTH_WPA2_WPA3_PSK: return "WPA2_WPA3_PSK";
case WIFI_AUTH_WAPI_PSK: return "WIFI_AUTH_WAPI_PSK"; case WIFI_AUTH_WAPI_PSK: return "WAPI_PSK";
case WIFI_AUTH_MAX: return "WIFI_AUTH_MAX"; case WIFI_AUTH_MAX: return "MAX";
default:
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));
} }
return std::string{"Unknown wifi_auth_mode_t("} + std::to_string(int(authMode)) + ')';
} }
std::string toString(wifi_cipher_type_t cipherType) std::string toString(wifi_cipher_type_t cipherType)
{ {
switch (cipherType) { switch (cipherType)
case WIFI_CIPHER_TYPE_NONE: return "WIFI_CIPHER_TYPE_NONE"; {
case WIFI_CIPHER_TYPE_WEP40: return "WIFI_CIPHER_TYPE_WEP40"; case WIFI_CIPHER_TYPE_NONE: return "NONE";
case WIFI_CIPHER_TYPE_WEP104: return "WIFI_CIPHER_TYPE_WEP104"; case WIFI_CIPHER_TYPE_WEP40: return "WEP40";
case WIFI_CIPHER_TYPE_TKIP: return "WIFI_CIPHER_TYPE_TKIP"; case WIFI_CIPHER_TYPE_WEP104: return "WEP104";
case WIFI_CIPHER_TYPE_CCMP: return "WIFI_CIPHER_TYPE_CCMP"; case WIFI_CIPHER_TYPE_TKIP: return "TKIP";
case WIFI_CIPHER_TYPE_TKIP_CCMP: return "WIFI_CIPHER_TYPE_TKIP_CCMP"; case WIFI_CIPHER_TYPE_CCMP: return "CCMP";
case WIFI_CIPHER_TYPE_AES_CMAC128: return "WIFI_CIPHER_TYPE_AES_CMAC128"; case WIFI_CIPHER_TYPE_TKIP_CCMP: return "TKIP_CCMP";
case WIFI_CIPHER_TYPE_SMS4: return "WIFI_CIPHER_TYPE_SMS4"; case WIFI_CIPHER_TYPE_AES_CMAC128: return "AES_CMAC128";
case WIFI_CIPHER_TYPE_UNKNOWN: return "WIFI_CIPHER_TYPE_UNKNOWN"; case WIFI_CIPHER_TYPE_SMS4: return "SMS4";
case WIFI_CIPHER_TYPE_UNKNOWN: return "UNKNOWN";
default:
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));
}
} }
return std::string{"Unknown wifi_cipher_type_t("} + std::to_string(int(cipherType)) + ')'; 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_ETH: return "ETH";
default:
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";
default:
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));
}
} }
std::string toString(const mac_t &mac) std::string toString(const mac_t &mac)
{ {
char macStr[18]{0}; return fmt::format("{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}",
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)); 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) /*static*/ tl::expected<ip_address_t, std::string> ip_address_t::parseFromString(std::string_view address)
{ {
// TODO: add support for "a", "a.b", "a.b.c" formats // TODO: add support for "a", "a.b", "a.b.c" formats
// TODO: replace with scanf for better performance // TODO: replace with scanf for better performance
ip_address_t result;
uint16_t acc = 0; // Accumulator uint16_t acc = 0; // Accumulator
uint8_t dots = 0; uint8_t dots = 0;
@@ -105,40 +137,32 @@ bool ip_address_t::fromString(std::string_view address)
if (c >= '0' && c <= '9') if (c >= '0' && c <= '9')
{ {
acc = acc * 10 + (c - '0'); acc = acc * 10 + (c - '0');
if (acc > 255) { if (acc > 255)
// Value out of [0..255] range return tl::make_unexpected("Value out of [0..255] range");
return false;
}
} }
else if (c == '.') else if (c == '.')
{ {
if (dots == 3) { if (dots == 3)
// Too much dots (there must be 3 dots) return tl::make_unexpected("Too many dots (there must be 3 dots)");
return false;
} result._bytes[dots++] = acc;
_bytes[dots++] = acc;
acc = 0; acc = 0;
} }
else else
{ return tl::make_unexpected("Invalid char");
// Invalid char
return false;
}
} }
if (dots != 3) { if (dots != 3)
// Too few dots (there must be 3 dots) return tl::make_unexpected("Too few dots (there must be 3 dots)");
return false;
} result._bytes[3] = acc;
_bytes[3] = acc;
return true; return result;
} }
std::string toString(const ip_address_t &address) std::string toString(const ip_address_t &address)
{ {
char szRet[16]; return fmt::format("{}.{}.{}.{}", address[0], address[1], address[2], address[3]);
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 goe_wifi_calculate_network_id(ip_address_t ip, ip_address_t subnet)
@@ -206,21 +230,8 @@ std::string toString(ip_addr_t val)
case IPADDR_TYPE_V4: return toString(val.u_addr.ip4); case IPADDR_TYPE_V4: return toString(val.u_addr.ip4);
case IPADDR_TYPE_V6: return toString(val.u_addr.ip6); case IPADDR_TYPE_V6: return toString(val.u_addr.ip6);
default: default:
ESP_LOGW(TAG, "unknown ipv%i", val.type); ESP_LOGW(TAG, "Unknown ipv%hhu", val.type);
return "unknown ipv" + std::to_string(val.type); return fmt::format("Unknown ipv{}", val.type);
}
}
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_ETH: return "ETH";
default:
ESP_LOGW(TAG, "unknown esp_interface_t(%i)", std::to_underlying(interface));
return "unknown esp_interface_t(" + std::to_string(std::to_underlying(interface)) + ")";
} }
} }

View File

@@ -9,14 +9,20 @@
// esp-idf includes // esp-idf includes
#include <esp_wifi_types.h> #include <esp_wifi_types.h>
#include <esp_netif_ip_addr.h> #include <esp_netif_ip_addr.h>
#include <esp_netif_types.h>
#include <lwip/ip_addr.h> #include <lwip/ip_addr.h>
// 3rdparty lib includes
#include <tl/expected.hpp>
namespace wifi_stack { namespace wifi_stack {
bool goe_wifi_ap_config_equal(const wifi_ap_config_t& lhs, const wifi_ap_config_t& rhs); 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); 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 authMode); std::string toString(wifi_auth_mode_t authMode);
std::string toString(wifi_cipher_type_t cipherType); std::string toString(wifi_cipher_type_t cipherType);
std::string toString(esp_interface_t interface);
std::string toString(esp_netif_dhcp_status_t status);
// A class to make it easier to handle and pass around mac addresses / bssids // A class to make it easier to handle and pass around mac addresses / bssids
@@ -62,7 +68,7 @@ public:
constexpr explicit ip_address_t(esp_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} {} constexpr ip_address_t(std::array<uint8_t, 4> bytes) noexcept : _bytes{bytes} {}
bool fromString(std::string_view address); static tl::expected<ip_address_t, std::string> parseFromString(std::string_view address);
// Access the raw byte array containing the address. Because this returns a pointer // 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 // to the internal structure rather than a copy of the address this function should only
@@ -101,6 +107,4 @@ inline std::string toString(const esp_ip4_addr_t &val)
inline std::string toString(const esp_ip6_addr_t &val) inline std::string toString(const esp_ip6_addr_t &val)
{ return toString(*reinterpret_cast<const ip6_addr_t *>(&val)); } { return toString(*reinterpret_cast<const ip6_addr_t *>(&val)); }
std::string toString(esp_interface_t interface);
} // namespace wifi_stack } // namespace wifi_stack