From 5198b794d68a67dedc81bc04471a33805f0d7360 Mon Sep 17 00:00:00 2001 From: David Gauchard Date: Wed, 23 Jan 2019 12:26:25 +0100 Subject: [PATCH 1/3] dynamic WiFi.hostname("newname") --- libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp | 100 ++++++++++++++----- libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h | 6 +- tools/sdk/include/user_interface.h | 4 +- 3 files changed, 81 insertions(+), 29 deletions(-) diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp index 105d70d692..07994afdda 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp @@ -37,6 +37,7 @@ extern "C" { #include "lwip/err.h" #include "lwip/dns.h" +#include "lwip/dhcp.h" #include "lwip/init.h" // LWIP_VERSION_ #if LWIP_IPV6 #include "lwip/netif.h" // struct netif @@ -466,39 +467,92 @@ IPAddress ESP8266WiFiSTAClass::dnsIP(uint8_t dns_no) { * Get ESP8266 station DHCP hostname * @return hostname */ -String ESP8266WiFiSTAClass::hostname(void) { - return String(wifi_station_get_hostname()); +const char* ESP8266WiFiSTAClass::hostname(void) { + return wifi_station_get_hostname(); } - /** * Set ESP8266 station DHCP hostname - * @param aHostname max length:32 + * @param aHostname max length:24 * @return ok */ -bool ESP8266WiFiSTAClass::hostname(char* aHostname) { - if(strlen(aHostname) > 32) { +bool ESP8266WiFiSTAClass::hostname(String aHostname) { + /* + vvvv RFC952 vvvv + 1. A "name" (Net, Host, Gateway, or Domain name) is a text string up + to 24 characters drawn from the alphabet (A-Z), digits (0-9), minus + sign (-), and period (.). Note that periods are only allowed when + they serve to delimit components of "domain style names". (See + RFC-921, "Domain Name System Implementation Schedule", for + background). No blank or space characters are permitted as part of a + name. No distinction is made between upper and lower case. The first + character must be an alpha character. The last character must not be + a minus sign or period. A host which serves as a GATEWAY should have + "-GATEWAY" or "-GW" as part of its name. Hosts which do not serve as + Internet gateways should not use "-GATEWAY" and "-GW" as part of + their names. A host which is a TAC should have "-TAC" as the last + part of its host name, if it is a DoD host. Single character names + or nicknames are not allowed. + ^^^^ RFC952 ^^^^ + + - 24 chars max + - only a..z A..Z 0..9 -] + - no '-' as last char + */ + + if (aHostname.length() == 0) { + DEBUGV("WiFi.(set)hostname(): empty name\n"); return false; } - return wifi_station_set_hostname(aHostname); -} -/** - * Set ESP8266 station DHCP hostname - * @param aHostname max length:32 - * @return ok - */ -bool ESP8266WiFiSTAClass::hostname(const char* aHostname) { - return hostname((char*) aHostname); -} + // rework hostname to be RFC compliant -/** - * Set ESP8266 station DHCP hostname - * @param aHostname max length:32 - * @return ok - */ -bool ESP8266WiFiSTAClass::hostname(const String& aHostname) { - return hostname((char*) aHostname.c_str()); + if (aHostname.length() > 24) { + // nonos-sdk allows 32, but + // dhcp server may require RFC compliance + aHostname.remove(24); + } + for (size_t i = 0; i < aHostname.length(); i++) + // replace unallowed chars by dashes + if (!isalnum(aHostname[i]) && aHostname[i] != '-') + aHostname[i] = '-'; + if (aHostname[aHostname.length() - 1] == '-') { + // check for ending dash + aHostname[aHostname.length() - 1] = 'x'; + } + + bool ret = wifi_station_set_hostname(aHostname.c_str()); + + if (!ret) { +#ifdef DEBUG_ESP_CORE + static const char fmt[] PROGMEM = "WiFi.hostname(%s): wifi_station_set_hostname() failed\n"; + DEBUGV(fmt, aHostname.c_str()); +#endif + return false; + } + + // now we should inform dhcp server for this change, using lwip_renew() + // looping through all existing interface + // harmless for AP, also compatible with ethernet adapters (to come) + for (netif* intf = netif_list; intf; intf = intf->next) { + + // unconditionally update all known interfaces + intf->hostname = wifi_station_get_hostname(); + + if (netif_dhcp_data(intf) != nullptr) { + // renew already started DHCP leases + err_t lwipret = dhcp_renew(intf); + if (lwipret != ERR_OK) { +#ifdef DEBUG_ESP_CORE + static const char fmt[] PROGMEM = "WiFi.hostname(%s): lwIP error %d on interface %c%c (index %d)\n"; + DEBUGV(fmt, intf->hostname, (int)lwipret, intf->name[0], intf->name[1], intf->num); +#endif + ret = false; + } + } + } + + return ret; } /** diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h index 7988005313..5a81ad42a7 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h @@ -69,10 +69,8 @@ class ESP8266WiFiSTAClass { IPAddress gatewayIP(); IPAddress dnsIP(uint8_t dns_no = 0); - String hostname(); - bool hostname(char* aHostname); - bool hostname(const char* aHostname); - bool hostname(const String& aHostname); + const char* hostname(); + bool hostname(String aHostname); // STA WiFi info wl_status_t status(); diff --git a/tools/sdk/include/user_interface.h b/tools/sdk/include/user_interface.h index 71159bf202..d1b0309066 100644 --- a/tools/sdk/include/user_interface.h +++ b/tools/sdk/include/user_interface.h @@ -328,8 +328,8 @@ bool wifi_station_dhcpc_stop(void); enum dhcp_status wifi_station_dhcpc_status(void); bool wifi_station_dhcpc_set_maxtry(uint8 num); -char* wifi_station_get_hostname(void); -bool wifi_station_set_hostname(char *name); +const char* wifi_station_get_hostname(void); +bool wifi_station_set_hostname(const char *name); int wifi_station_set_cert_key(uint8 *client_cert, int client_cert_len, uint8 *private_key, int private_key_len, From 51bbae15fd273a67b99a88d6f66dcc8e0b794b67 Mon Sep 17 00:00:00 2001 From: David Gauchard Date: Wed, 23 Jan 2019 13:18:46 +0100 Subject: [PATCH 2/3] WiFi.hostname() back to String return type --- libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp | 2 +- libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp index 07994afdda..0cfbd51556 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp @@ -467,7 +467,7 @@ IPAddress ESP8266WiFiSTAClass::dnsIP(uint8_t dns_no) { * Get ESP8266 station DHCP hostname * @return hostname */ -const char* ESP8266WiFiSTAClass::hostname(void) { +String ESP8266WiFiSTAClass::hostname(void) { return wifi_station_get_hostname(); } diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h index 5a81ad42a7..adc5c44a4c 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h @@ -69,7 +69,7 @@ class ESP8266WiFiSTAClass { IPAddress gatewayIP(); IPAddress dnsIP(uint8_t dns_no = 0); - const char* hostname(); + String hostname(); bool hostname(String aHostname); // STA WiFi info From 19bfa7fcd344e7a2f0414aca6f17ed51147e83be Mon Sep 17 00:00:00 2001 From: David Gauchard Date: Thu, 24 Jan 2019 11:32:25 +0100 Subject: [PATCH 3/3] no silent hostname fix but proceed with debug message and returning false --- libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp | 51 +++++++++----------- libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h | 3 +- 2 files changed, 25 insertions(+), 29 deletions(-) diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp index 0cfbd51556..ac03a3754d 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp @@ -476,9 +476,10 @@ String ESP8266WiFiSTAClass::hostname(void) { * @param aHostname max length:24 * @return ok */ -bool ESP8266WiFiSTAClass::hostname(String aHostname) { +bool ESP8266WiFiSTAClass::hostname(const char* aHostname) { /* vvvv RFC952 vvvv + ASSUMPTIONS 1. A "name" (Net, Host, Gateway, or Domain name) is a text string up to 24 characters drawn from the alphabet (A-Z), digits (0-9), minus sign (-), and period (.). Note that periods are only allowed when @@ -496,38 +497,34 @@ bool ESP8266WiFiSTAClass::hostname(String aHostname) { ^^^^ RFC952 ^^^^ - 24 chars max - - only a..z A..Z 0..9 -] + - only a..z A..Z 0..9 '-' - no '-' as last char */ - if (aHostname.length() == 0) { - DEBUGV("WiFi.(set)hostname(): empty name\n"); + size_t len = strlen(aHostname); + + if (len == 0 || len > 32) { + // nonos-sdk limit is 32 + // (dhcp hostname option minimum size is ~60) + DEBUG_WIFI_GENERIC("WiFi.(set)hostname(): empty or large(>32) name\n"); return false; } - // rework hostname to be RFC compliant - - if (aHostname.length() > 24) { - // nonos-sdk allows 32, but - // dhcp server may require RFC compliance - aHostname.remove(24); - } - for (size_t i = 0; i < aHostname.length(); i++) - // replace unallowed chars by dashes + // check RFC compliance + bool compliant = (len <= 24); + for (size_t i = 0; compliant && i < len; i++) if (!isalnum(aHostname[i]) && aHostname[i] != '-') - aHostname[i] = '-'; - if (aHostname[aHostname.length() - 1] == '-') { - // check for ending dash - aHostname[aHostname.length() - 1] = 'x'; - } + compliant = false; + if (aHostname[len - 1] == '-') + compliant = false; - bool ret = wifi_station_set_hostname(aHostname.c_str()); + if (!compliant) { + DEBUG_WIFI_GENERIC("hostname '%s' is not compliant with RFC952\n", aHostname); + } + bool ret = wifi_station_set_hostname(aHostname); if (!ret) { -#ifdef DEBUG_ESP_CORE - static const char fmt[] PROGMEM = "WiFi.hostname(%s): wifi_station_set_hostname() failed\n"; - DEBUGV(fmt, aHostname.c_str()); -#endif + DEBUG_WIFI_GENERIC("WiFi.hostname(%s): wifi_station_set_hostname() failed\n", aHostname); return false; } @@ -543,16 +540,14 @@ bool ESP8266WiFiSTAClass::hostname(String aHostname) { // renew already started DHCP leases err_t lwipret = dhcp_renew(intf); if (lwipret != ERR_OK) { -#ifdef DEBUG_ESP_CORE - static const char fmt[] PROGMEM = "WiFi.hostname(%s): lwIP error %d on interface %c%c (index %d)\n"; - DEBUGV(fmt, intf->hostname, (int)lwipret, intf->name[0], intf->name[1], intf->num); -#endif + DEBUG_WIFI_GENERIC("WiFi.hostname(%s): lwIP error %d on interface %c%c (index %d)\n", + intf->hostname, (int)lwipret, intf->name[0], intf->name[1], intf->num); ret = false; } } } - return ret; + return ret && compliant; } /** diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h index adc5c44a4c..f8c352cca7 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h @@ -70,7 +70,8 @@ class ESP8266WiFiSTAClass { IPAddress dnsIP(uint8_t dns_no = 0); String hostname(); - bool hostname(String aHostname); + bool hostname(const String& aHostname) { return hostname(aHostname.c_str()); } + bool hostname(const char* aHostname); // STA WiFi info wl_status_t status();