diff --git a/CMakeLists.txt b/CMakeLists.txt index 5343d11..bcee04e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,7 @@ set(dependencies espchrono espcpputils expected + fmt ) idf_component_register( diff --git a/src/espwifistack.cpp b/src/espwifistack.cpp index 1ce5c71..94393cb 100644 --- a/src/espwifistack.cpp +++ b/src/espwifistack.cpp @@ -20,6 +20,9 @@ #include #endif +// 3rdparty lib includes +#include + // local includes #include "strutils.h" #include "delayedconstruction.h" @@ -95,8 +98,7 @@ bool scanResultChangedFlag{}; struct ConnectPlanItem { - std::string ssid; - std::string key; + wifi_entry config; uint8_t channel; wifi_auth_mode_t authmode; 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; } - 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) { ESP_LOGE(TAG, "esp_netif_dhcpc_get_status() failed with %s", esp_err_to_name(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)) @@ -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_begin(const config &config, const std::string &ssid, const std::string &passphrase = {}, int32_t channel = 0, - std::optional bssid = {}, bool connect = true); -esp_err_t goe_wifi_sta_begin(const config &config); +esp_err_t goe_wifi_sta_begin(const config &config, const wifi_entry &sta_config, + int32_t channel = 0, std::optional bssid = {}, bool connect = true); +esp_err_t goe_wifi_sta_restart(const config &config); 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) 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) - ESP_LOGE(TAG, "goe_wifi_sta_begin() failed with %s", esp_err_to_name(result)); + if (const auto result = goe_wifi_sta_restart(config); result != ESP_OK) + ESP_LOGE(TAG, "goe_wifi_sta_restart() failed with %s", esp_err_to_name(result)); } break; @@ -1202,15 +1205,20 @@ 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) { + 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_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; - 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)); - return result; + esp_netif_dhcp_status_t status; + 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)); + return result; + } + ESP_LOGI(TAG, "esp_netif_dhcps_get_status() resulted in %s", toString(status).c_str()); } 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.end_ip.addr = ip.ip.value() + (11 << 24); - if (const auto result = tcpip_adapter_dhcps_option( - (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) + 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) { ESP_LOGE(TAG, "tcpip_adapter_dhcps_option() failed with %s", esp_err_to_name(result)); return result; @@ -1311,8 +1314,8 @@ wifi_config_t make_sta_config(std::string_view ssid, std::string_view password, return wifi_config; } -esp_err_t goe_wifi_sta_begin(const config &config, const std::string &ssid, const std::string &passphrase, int32_t channel, - std::optional bssid, bool connect) +esp_err_t goe_wifi_sta_begin(const config &config, const wifi_entry &sta_config, + int32_t channel, std::optional bssid, bool connect) { 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; } - if (ssid.empty()) + if (sta_config.ssid.empty()) { ESP_LOGE(TAG, "SSID missing!"); 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; } - 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; } - 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; } } - 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; if (const auto result = esp_wifi_get_config(WIFI_IF_STA, ¤t_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)); 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)); return result; } - last_sta_static_dns = config.sta.static_dns; + last_sta_static_dns = sta_config.static_dns; if (connect) { @@ -1416,7 +1419,7 @@ esp_err_t goe_wifi_sta_begin(const config &config, const std::string &ssid, cons 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) { @@ -1437,21 +1440,23 @@ esp_err_t goe_wifi_sta_begin(const config &config) 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)); 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)); 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) { @@ -1606,7 +1611,8 @@ bool buildConnectPlan(const config &config, const scan_result &scanResult) std::string_view scanSSID{(const char *)entry.ssid}; // 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; 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)) { connectPlan.emplace_back(ConnectPlanItem{ - .ssid = std::string{scanSSID}, - .key = std::string{iter->key}, + .config = *iter, .channel = entry.primary, .authmode = entry.authmode, .rssi = entry.rssi, @@ -1635,33 +1640,17 @@ bool buildConnectPlan(const config &config, const scan_result &scanResult) const auto entry = connectPlan.front(); connectPlan.erase(std::begin(connectPlan)); 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(), - entry.key.c_str(), + entry.config.key.c_str(), entry.channel, entry.rssi, toString(entry.bssid).c_str() ); _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; - 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)); setWifiState(WiFiState::Connecting); @@ -1916,8 +1905,8 @@ void update(const config &config) 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)); - if (const auto result = goe_wifi_sta_begin(config); result != ESP_OK) - ESP_LOGE(TAG, "goe_wifi_sta_begin() failed with %s", esp_err_to_name(result)); + if (const auto result = goe_wifi_sta_restart(config); result != ESP_OK) + ESP_LOGE(TAG, "goe_wifi_sta_restart() failed with %s", esp_err_to_name(result)); } } else @@ -1955,12 +1944,12 @@ void update(const config &config) else if (const auto sta_info = get_sta_ap_info()) { const std::string_view connectedSSID{reinterpret_cast(sta_info->ssid)}; - const auto configStillFound = std::any_of(std::begin(config.sta.wifis), std::end(config.sta.wifis), - [&connectedSSID](const auto &entry){ - return cpputils::stringEqualsIgnoreCase(entry.ssid, connectedSSID); - }); + const auto iter = std::find_if(std::cbegin(config.sta.wifis), std::cend(config.sta.wifis), + [&connectedSSID](const wifi_entry &entry){ + 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"); lastWifisChecksum.clear(); @@ -1972,30 +1961,28 @@ void update(const config &config) } 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)); //return result; } 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"); - - 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_ip = iter->static_ip; + + 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)); + //return result; + } + else + last_sta_static_dns = iter->static_dns; } - else - last_sta_static_dns = config.sta.static_dns; } } } @@ -2085,7 +2072,7 @@ tl::expected get_sta_ap_info() else { 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 get_default_mac_addr() else { 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 get_base_mac_addr() else { 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 set_base_mac_addr(wifi_stack::mac_t mac_addr) else { 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 get_ip_info(tcpip_adapter_if_ else { 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))); } } diff --git a/src/espwifistackconfig.h b/src/espwifistackconfig.h index b4d0549..3ae8e23 100644 --- a/src/espwifistackconfig.h +++ b/src/espwifistackconfig.h @@ -13,23 +13,6 @@ #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 static_ip_config { 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; + 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 { std::array wifis; - std::optional static_ip; - static_dns_config static_dns; int8_t min_rssi; friend bool operator==(const sta_config &left, const sta_config &right) { return left.wifis == right.wifis && - left.static_ip == right.static_ip && - left.static_dns == right.static_dns && left.min_rssi == right.min_rssi; } diff --git a/src/espwifiutils.cpp b/src/espwifiutils.cpp index 9747865..bb3d9f8 100644 --- a/src/espwifiutils.cpp +++ b/src/espwifiutils.cpp @@ -3,6 +3,9 @@ // esp-idf includes #include +// 3rdparty lib includes +#include + // local includes #include "futurecpp.h" @@ -52,51 +55,80 @@ std::string toString(wifi_auth_mode_t authMode) { switch (authMode) { - 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"; + 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_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) { - 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_WEP104: return "WIFI_CIPHER_TYPE_WEP104"; - case WIFI_CIPHER_TYPE_TKIP: return "WIFI_CIPHER_TYPE_TKIP"; - case WIFI_CIPHER_TYPE_CCMP: return "WIFI_CIPHER_TYPE_CCMP"; - case WIFI_CIPHER_TYPE_TKIP_CCMP: return "WIFI_CIPHER_TYPE_TKIP_CCMP"; - case WIFI_CIPHER_TYPE_AES_CMAC128: return "WIFI_CIPHER_TYPE_AES_CMAC128"; - case WIFI_CIPHER_TYPE_SMS4: return "WIFI_CIPHER_TYPE_SMS4"; - case WIFI_CIPHER_TYPE_UNKNOWN: return "WIFI_CIPHER_TYPE_UNKNOWN"; + 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_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) { - 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}; + return fmt::format("{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}", + mac.at(0), mac.at(1), mac.at(2), mac.at(3), mac.at(4), mac.at(5)); } -bool ip_address_t::fromString(std::string_view address) +/*static*/ tl::expected ip_address_t::parseFromString(std::string_view address) { // 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; @@ -105,40 +137,32 @@ bool ip_address_t::fromString(std::string_view address) if (c >= '0' && c <= '9') { acc = acc * 10 + (c - '0'); - if (acc > 255) { - // Value out of [0..255] range - return false; - } + if (acc > 255) + return tl::make_unexpected("Value out of [0..255] range"); } else if (c == '.') { - if (dots == 3) { - // Too much dots (there must be 3 dots) - return false; - } - _bytes[dots++] = acc; + if (dots == 3) + return tl::make_unexpected("Too many dots (there must be 3 dots)"); + + result._bytes[dots++] = acc; acc = 0; } else - { - // Invalid char - return false; - } + return tl::make_unexpected("Invalid char"); } - if (dots != 3) { - // Too few dots (there must be 3 dots) - return false; - } - _bytes[3] = acc; - return true; + if (dots != 3) + return tl::make_unexpected("Too few dots (there must be 3 dots)"); + + result._bytes[3] = acc; + + return result; } 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}; + return fmt::format("{}.{}.{}.{}", address[0], address[1], address[2], address[3]); } 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_V6: return toString(val.u_addr.ip6); default: - ESP_LOGW(TAG, "unknown ipv%i", val.type); - return "unknown ipv" + std::to_string(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)) + ")"; + ESP_LOGW(TAG, "Unknown ipv%hhu", val.type); + return fmt::format("Unknown ipv{}", val.type); } } diff --git a/src/espwifiutils.h b/src/espwifiutils.h index 22eedf0..d285d51 100644 --- a/src/espwifiutils.h +++ b/src/espwifiutils.h @@ -9,14 +9,20 @@ // esp-idf includes #include #include +#include #include +// 3rdparty lib includes +#include + 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 authMode); 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 @@ -62,7 +68,7 @@ public: constexpr explicit ip_address_t(esp_ip4_addr_t address) noexcept : _value{address.addr} {} constexpr ip_address_t(std::array bytes) noexcept : _bytes{bytes} {} - bool fromString(std::string_view address); + static tl::expected parseFromString(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 @@ -101,6 +107,4 @@ inline std::string toString(const esp_ip4_addr_t &val) inline std::string toString(const esp_ip6_addr_t &val) { return toString(*reinterpret_cast(&val)); } -std::string toString(esp_interface_t interface); - } // namespace wifi_stack