Skip to content

Commit 5198b79

Browse files
committed
dynamic WiFi.hostname("newname")
1 parent bff3a6d commit 5198b79

File tree

3 files changed

+81
-29
lines changed

3 files changed

+81
-29
lines changed

libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp

+77-23
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
extern "C" {
3838
#include "lwip/err.h"
3939
#include "lwip/dns.h"
40+
#include "lwip/dhcp.h"
4041
#include "lwip/init.h" // LWIP_VERSION_
4142
#if LWIP_IPV6
4243
#include "lwip/netif.h" // struct netif
@@ -466,39 +467,92 @@ IPAddress ESP8266WiFiSTAClass::dnsIP(uint8_t dns_no) {
466467
* Get ESP8266 station DHCP hostname
467468
* @return hostname
468469
*/
469-
String ESP8266WiFiSTAClass::hostname(void) {
470-
return String(wifi_station_get_hostname());
470+
const char* ESP8266WiFiSTAClass::hostname(void) {
471+
return wifi_station_get_hostname();
471472
}
472473

473-
474474
/**
475475
* Set ESP8266 station DHCP hostname
476-
* @param aHostname max length:32
476+
* @param aHostname max length:24
477477
* @return ok
478478
*/
479-
bool ESP8266WiFiSTAClass::hostname(char* aHostname) {
480-
if(strlen(aHostname) > 32) {
479+
bool ESP8266WiFiSTAClass::hostname(String aHostname) {
480+
/*
481+
vvvv RFC952 vvvv
482+
1. A "name" (Net, Host, Gateway, or Domain name) is a text string up
483+
to 24 characters drawn from the alphabet (A-Z), digits (0-9), minus
484+
sign (-), and period (.). Note that periods are only allowed when
485+
they serve to delimit components of "domain style names". (See
486+
RFC-921, "Domain Name System Implementation Schedule", for
487+
background). No blank or space characters are permitted as part of a
488+
name. No distinction is made between upper and lower case. The first
489+
character must be an alpha character. The last character must not be
490+
a minus sign or period. A host which serves as a GATEWAY should have
491+
"-GATEWAY" or "-GW" as part of its name. Hosts which do not serve as
492+
Internet gateways should not use "-GATEWAY" and "-GW" as part of
493+
their names. A host which is a TAC should have "-TAC" as the last
494+
part of its host name, if it is a DoD host. Single character names
495+
or nicknames are not allowed.
496+
^^^^ RFC952 ^^^^
497+
498+
- 24 chars max
499+
- only a..z A..Z 0..9 -]
500+
- no '-' as last char
501+
*/
502+
503+
if (aHostname.length() == 0) {
504+
DEBUGV("WiFi.(set)hostname(): empty name\n");
481505
return false;
482506
}
483-
return wifi_station_set_hostname(aHostname);
484-
}
485507

486-
/**
487-
* Set ESP8266 station DHCP hostname
488-
* @param aHostname max length:32
489-
* @return ok
490-
*/
491-
bool ESP8266WiFiSTAClass::hostname(const char* aHostname) {
492-
return hostname((char*) aHostname);
493-
}
508+
// rework hostname to be RFC compliant
494509

495-
/**
496-
* Set ESP8266 station DHCP hostname
497-
* @param aHostname max length:32
498-
* @return ok
499-
*/
500-
bool ESP8266WiFiSTAClass::hostname(const String& aHostname) {
501-
return hostname((char*) aHostname.c_str());
510+
if (aHostname.length() > 24) {
511+
// nonos-sdk allows 32, but
512+
// dhcp server may require RFC compliance
513+
aHostname.remove(24);
514+
}
515+
for (size_t i = 0; i < aHostname.length(); i++)
516+
// replace unallowed chars by dashes
517+
if (!isalnum(aHostname[i]) && aHostname[i] != '-')
518+
aHostname[i] = '-';
519+
if (aHostname[aHostname.length() - 1] == '-') {
520+
// check for ending dash
521+
aHostname[aHostname.length() - 1] = 'x';
522+
}
523+
524+
bool ret = wifi_station_set_hostname(aHostname.c_str());
525+
526+
if (!ret) {
527+
#ifdef DEBUG_ESP_CORE
528+
static const char fmt[] PROGMEM = "WiFi.hostname(%s): wifi_station_set_hostname() failed\n";
529+
DEBUGV(fmt, aHostname.c_str());
530+
#endif
531+
return false;
532+
}
533+
534+
// now we should inform dhcp server for this change, using lwip_renew()
535+
// looping through all existing interface
536+
// harmless for AP, also compatible with ethernet adapters (to come)
537+
for (netif* intf = netif_list; intf; intf = intf->next) {
538+
539+
// unconditionally update all known interfaces
540+
intf->hostname = wifi_station_get_hostname();
541+
542+
if (netif_dhcp_data(intf) != nullptr) {
543+
// renew already started DHCP leases
544+
err_t lwipret = dhcp_renew(intf);
545+
if (lwipret != ERR_OK) {
546+
#ifdef DEBUG_ESP_CORE
547+
static const char fmt[] PROGMEM = "WiFi.hostname(%s): lwIP error %d on interface %c%c (index %d)\n";
548+
DEBUGV(fmt, intf->hostname, (int)lwipret, intf->name[0], intf->name[1], intf->num);
549+
#endif
550+
ret = false;
551+
}
552+
}
553+
}
554+
555+
return ret;
502556
}
503557

504558
/**

libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h

+2-4
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,8 @@ class ESP8266WiFiSTAClass {
6969
IPAddress gatewayIP();
7070
IPAddress dnsIP(uint8_t dns_no = 0);
7171

72-
String hostname();
73-
bool hostname(char* aHostname);
74-
bool hostname(const char* aHostname);
75-
bool hostname(const String& aHostname);
72+
const char* hostname();
73+
bool hostname(String aHostname);
7674

7775
// STA WiFi info
7876
wl_status_t status();

tools/sdk/include/user_interface.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -328,8 +328,8 @@ bool wifi_station_dhcpc_stop(void);
328328
enum dhcp_status wifi_station_dhcpc_status(void);
329329
bool wifi_station_dhcpc_set_maxtry(uint8 num);
330330

331-
char* wifi_station_get_hostname(void);
332-
bool wifi_station_set_hostname(char *name);
331+
const char* wifi_station_get_hostname(void);
332+
bool wifi_station_set_hostname(const char *name);
333333

334334
int wifi_station_set_cert_key(uint8 *client_cert, int client_cert_len,
335335
uint8 *private_key, int private_key_len,

0 commit comments

Comments
 (0)