Espressif's ESP-32 (specifically the ESP-WROOM-32 in this case) appears on a network with the default hostname "Espressif". I don't want to use this hostname, so I've opted to change it as follows:
// Initialize the TCP/IP adapter (launches handler task)
tcpip_adapter_init();
// Set the hostname for the default TCP/IP station interface
if ((err = tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_STA, g_hostname))
!= ESP_OK) {
return err;
}
Of course, this isn't working. I get back the following error: ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY
.
To solve this, I look to see if the TCP/IP adapter will post some kind of event when it is finished initializing. That way I can register a handler to set the hostname. The Espressif WiFi Driver Guide here indicates a task is launched - so there is probably an event right:
"The main task calls tcpip_adapter_init() to create an LwIP core task and initialize LwIP-related work."
Well I cannot find any such events. Neither the API documentation nor the actual file itself (tcpip_adapter.h
) have it. I checked the header file for events, and none seem to exist solely for the purpose of indicating that the TCP/IP adapter has finished starting:
/** IP event declarations */
typedef enum {
IP_EVENT_STA_GOT_IP, /*!< ESP32 station got IP from connected AP */
IP_EVENT_STA_LOST_IP, /*!< ESP32 station lost IP and the IP is reset to 0 */
IP_EVENT_AP_STAIPASSIGNED, /*!< ESP32 soft-AP assign an IP to a connected station */
IP_EVENT_GOT_IP6, /*!< ESP32 station or ap or ethernet interface v6IP addr is preferred */
IP_EVENT_ETH_GOT_IP, /*!< ESP32 ethernet got IP from connected AP */
} ip_event_t;
I have noticed that in Espressif's WiFi guide they indicate that the event SYSTEM_EVENT_STA_START
(which indicates that a station has started), will:
Upon receiving this event, the event task will initialize the LwIP network interface (netif).
If I place the call after a handler receives this event, I no longer get the error:
// After the event WIFI_EVENT_STA_START
if (base == WIFI_EVENT && id == WIFI_EVENT_STA_START) {
// Set the hostname for the default TCP/IP station interface
if ((err = tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_STA, g_hostname))
!= ESP_OK) {
fprintf(stderr, "Err: %s", esp_err_to_name(err));
}
...
}
However, the hostname still hasn't changed. Therefore I find myself a bit stuck. How can I actually change the hostname? I've found little to no results from searching this problem. However, the esp32 is a popular module and I'm sure many other people will find themselves facing the same problem.
Turns out I was doing it correctly. It was my router that had failed to refresh the hostname adequately. For consistency I will restate what I did to solve this problem:
The Espressif WiFi Guide indicates that the event SYSTEM_EVENT_STA_START
is generated once esp_wifi_start()
returns successfully.
The generation of this event also means that the event task will initialize the LwIP network interface (netif). Since we know that the TCP/IP adapter will surely have been initialized at this point, we can invoke the hostname change function. Here is an example of a handler that does that, taken right from their example:
void wifi_event_handler (void *handler_arg, esp_event_base_t base, int32_t id,
void *event_data) {
esp_err_t err;
// If esp_wifi_start() returned ESP_OK and WiFi mode is in station mode
if (base == WIFI_EVENT && id == WIFI_EVENT_STA_START) {
const char *name;
// Set the hostname for the default TCP/IP station interface
if ((err = tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_STA, g_hostname))
!= ESP_OK) {
fprintf(stderr, "Err: %s", esp_err_to_name(err));
} else {
if ((err = tcpip_adapter_get_hostname(TCPIP_ADAPTER_IF_STA, &name)) != ESP_OK) {
fprintf(stderr, "Err Get Hostname: %s\n", esp_err_to_name(err));
} else {
printf("Hostname: %s\n", (name == NULL ? "<None>" : name));
}
}
...
}
...
}
In this example I get the hostname after setting it, and print it to stdout
. You can validate it if you are running the monitor for the ESP32. The hostname set will be the one visible from the router page.