Add FTM support and examples (#5272)

Rework of #5266 by @pedrominatel
This commit is contained in:
Me No Dev 2021-06-16 21:24:48 +03:00 committed by GitHub
parent b1bcec08f8
commit cf43d174b7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 366 additions and 6 deletions

View File

@ -0,0 +1,90 @@
/* Wi-Fi FTM Initiator Arduino Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include "WiFi.h"
/*
THIS FEATURE IS SUPPORTED ONLY BY ESP32-S2 AND ESP32-C3
*/
// Change the SSID and PASSWORD here if needed
const char * WIFI_FTM_SSID = "WiFi_FTM_Responder"; // SSID of AP that has FTM Enabled
const char * WIFI_FTM_PASS = "ftm_responder"; // STA Password
// FTM settings
// Number of FTM frames requested in terms of 4 or 8 bursts (allowed values - 0 (No pref), 16, 24, 32, 64)
const uint8_t FTM_FRAME_COUNT = 16;
// Requested time period between consecutive FTM bursts in 100s of milliseconds (allowed values - 0 (No pref) or 2-255)
const uint16_t FTM_BURST_PERIOD = 2;
// Semaphore to signal when FTM Report has been received
xSemaphoreHandle ftmSemaphore;
// Status of the received FTM Report
bool ftmSuccess = true;
// FTM report handler with the calculated data from the round trip
void onFtmReport(arduino_event_t *event) {
const char * status_str[5] = {"SUCCESS", "UNSUPPORTED", "CONF_REJECTED", "NO_RESPONSE", "FAIL"};
wifi_event_ftm_report_t * report = &event->event_info.wifi_ftm_report;
// Set the global report status
ftmSuccess = report->status == FTM_STATUS_SUCCESS;
if (ftmSuccess) {
// The estimated distance in meters may vary depending on some factors (see README file)
Serial.printf("FTM Estimate: Distance: %.2f m, Return Time: %u ns\n", (float)report->dist_est / 100.0, report->rtt_est);
// Pointer to FTM Report with multiple entries, should be freed after use
free(report->ftm_report_data);
} else {
Serial.print("FTM Error: ");
Serial.println(status_str[report->status]);
}
// Signal that report is received
xSemaphoreGive(ftmSemaphore);
}
// Initiate FTM Session and wait for FTM Report
bool getFtmReport(){
if(!WiFi.initiateFTM(FTM_FRAME_COUNT, FTM_BURST_PERIOD)){
Serial.println("FTM Error: Initiate Session Failed");
return false;
}
// Wait for signal that report is received and return true if status was success
return xSemaphoreTake(ftmSemaphore, portMAX_DELAY) == pdPASS && ftmSuccess;
}
void setup() {
Serial.begin(115200);
// Create binary semaphore (initialized taken and can be taken/given from any thread/ISR)
ftmSemaphore = xSemaphoreCreateBinary();
// Listen for FTM Report events
WiFi.onEvent(onFtmReport, ARDUINO_EVENT_WIFI_FTM_REPORT);
// Connect to AP that has FTM Enabled
Serial.println("Connecting to FTM Responder");
WiFi.begin(WIFI_FTM_SSID, WIFI_FTM_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi Connected");
Serial.print("Initiating FTM session with Frame Count ");
Serial.print(FTM_FRAME_COUNT);
Serial.print(" and Burst Period ");
Serial.print(FTM_BURST_PERIOD * 100);
Serial.println(" ms");
// Request FTM reports until one fails
while(getFtmReport());
}
void loop() {
delay(1000);
}

View File

@ -0,0 +1,110 @@
# Wi-Fi FTM Initiator Arduino Example
This example demonstrates how to use the Fine Timing Measurement (FTM) to calculate the distace from the Access Point and the device. This is calculated by the Wi-Fi Round Trip Time (Wi-Fi RTT) introduced on the [IEEE Std 802.11-2016](https://en.wikipedia.org/wiki/IEEE_802.11mc) standard.
This example was based on the [ESP-IDF FTM](https://github.com/espressif/esp-idf/tree/master/examples/wifi/ftm). See the README file for more details about on how to use this feature.
Some usages for this feature includes:
* Indoor positioning systems.
* Navigation.
* Device Location.
* Smart Devices.
* Alarms.
# Supported Targets
Currently, this example supports the following targets:
| Supported Targets | ESP32-S2 | ESP32-C3 |
| ----------------- | -------- | -------- |
## How to Use Example
In order to use the FTM, you will need a Responder or Wi-Fi router with FTM capabilities. If you don't own one, you can use a second ESP32-S2 or ESP32-C3 to simulate one.
See the **Responder** example to prepare the environment.
* How to install the Arduino IDE: [Install Arduino IDE](https://github.com/espressif/arduino-esp32/tree/master/docs/arduino-ide).
### Configure the Project
To configure this project, you can change the following configuration related to FTM feature:
```c
// Change the SSID and PASSWORD here if needed
const char * WIFI_FTM_SSID = "WiFi_FTM_Responder"; // SSID of AP that has FTM Enabled
const char * WIFI_FTM_PASS = "ftm_responder"; // STA Password
// FTM settings
// Number of FTM frames requested in terms of 4 or 8 bursts (allowed values - 0 (No pref), 16, 24, 32, 64)
const uint8_t FTM_FRAME_COUNT = 16;
// Requested time period between consecutive FTM bursts in 100s of milliseconds (allowed values - 0 (No pref) or 2-255)
const uint16_t FTM_BURST_PERIOD = 2;
```
* Change the Wi-Fi `SSID` and `PASSWORD` as the same as the Responder/Router.
* Change `FTM_FRAME_COUNT` with the number of frames requested to the Responder.
* Change `FTM_BURST_PERIOD` with the time between each FTM burst.
To see more details about FTM, please see the [ESP-IDF docs](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/api-reference/network/esp_wifi.html).
#### Using Arduino IDE
To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits).
* Before Compile/Verify, select the correct board: `Tools -> Board`.
* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port.
#### Using Platform IO
* Select the COM port: `Devices` or setting the `upload_port` option on the `platformio.ini` file.
## Log Output
Expected log output:
```
ESP-ROM:esp32s2-rc4-20191025
Build:Oct 25 2019
rst:0x1 (POWERON),boot:0x8 (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3ffe6100,len:0x4b0
load:0x4004c000,len:0xa6c
load:0x40050000,len:0x25c4
entry 0x4004c198
Connecting to FTM Responder
.....
WiFi Connected
Initiating FTM session with Frame Count 16 and Burst Period 200 ms
FTM Estimate: Distance: 0.13 m, Return Time: 0 ns
FTM Estimate: Distance: 0.13 m, Return Time: 0 ns
FTM Estimate: Distance: 0.13 m, Return Time: 0 ns
FTM Estimate: Distance: 0.00 m, Return Time: 0 ns
...
```
## Troubleshooting
***Important: Make sure you are using a good quality USB cable and that you have a reliable power source.***
* **Programming Fail:** If the programming/flash procedure fails, try reducing the serial connection speed.
* **COM port not detected:** Check the USB cable and the USB to Serial driver installation.
If the error persist, you can ask for help at the official [ESP32 forum](https://esp32.com) or see [Contribute](#contribute).
## Contribute
To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst)
If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome!
Before creating a new issue, be sure to try the Troubleshooting and to check if the same issue was already created by someone else.
## Resources
* Official ESP32 Forum: [Link](https://esp32.com)
* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32)
* ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf)
* ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf)
* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com)

View File

@ -0,0 +1,23 @@
/* Wi-Fi FTM Responder Arduino Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include "WiFi.h"
// Change the SSID and PASSWORD here if needed
const char * WIFI_FTM_SSID = "WiFi_FTM_Responder";
const char * WIFI_FTM_PASS = "ftm_responder";
void setup() {
Serial.begin(115200);
Serial.println("Starting SoftAP with FTM Responder support");
// Enable AP with FTM support (last argument is 'true')
WiFi.softAP(WIFI_FTM_SSID, WIFI_FTM_PASS, 1, 0, 4, true);
}
void loop() {
delay(1000);
}

View File

@ -0,0 +1,94 @@
# Wi-Fi FTM Responder Arduino Example
This example demonstrates how to use the Fine Timing Measurement (FTM) to calculate the distace from the Access Point and the device. This is calculated by the Wi-Fi Round Trip Time (Wi-Fi RTT) introduced on the [IEEE Std 802.11-2016](https://en.wikipedia.org/wiki/IEEE_802.11mc) standard.
This example will simulate the Router with FTM capability.
This example was based on the [ESP-IDF FTM](https://github.com/espressif/esp-idf/tree/master/examples/wifi/ftm). See the README file for more details about on how to use this feature.
Some usages for this feature includes:
* Indoor positioning systems.
* Navigation.
* Device Location.
* Smart Devices.
* Alarms.
# Supported Targets
Currently, this example supports the following targets:
| Supported Targets | ESP32-S2 | ESP32-C3 |
| ----------------- | -------- | -------- |
## How to Use Example
See the **Initiator** example to prepare the environment.
* How to install the Arduino IDE: [Install Arduino IDE](https://github.com/espressif/arduino-esp32/tree/master/docs/arduino-ide).
### Configure the Project
To configure this project, you can change the following configuration related to STA:
```c
// Change the SSID and PASSWORD here if needed
const char * WIFI_FTM_SSID = "WiFi_FTM_Responder";
const char * WIFI_FTM_PASS = "ftm_responder";
```
* Change the Wi-Fi `SSID` and `PASSWORD` as the same as the Initiator.
To see more details about FTM, please see the [ESP-IDF docs](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/api-reference/network/esp_wifi.html).
#### Using Arduino IDE
To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits).
* Before Compile/Verify, select the correct board: `Tools -> Board`.
* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port.
#### Using Platform IO
* Select the COM port: `Devices` or setting the `upload_port` option on the `platformio.ini` file.
## Log Output
Expected log output:
```
Build:Oct 25 2019
rst:0x1 (POWERON),boot:0x8 (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3ffe6100,len:0x4b0
load:0x4004c000,len:0xa6c
load:0x40050000,len:0x25c4
entry 0x4004c198
Starting SoftAP with FTM Responder support
```
## Troubleshooting
***Important: Make sure you are using a good quality USB cable and that you have a reliable power source.***
* **Programming Fail:** If the programming/flash procedure fails, try reducing the serial connection speed.
* **COM port not detected:** Check the USB cable and the USB to Serial driver installation.
If the error persist, you can ask for help at the official [ESP32 forum](https://esp32.com) or see [Contribute](#contribute).
## Contribute
To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst)
If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome!
Before creating a new issue, be sure to try the Troubleshooting and to check if the same issue was already created by someone else.
## Resources
* Official ESP32 Forum: [Link](https://esp32.com)
* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32)
* ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf)
* ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf)
* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com)

View File

@ -81,11 +81,14 @@ static bool softap_config_equal(const wifi_config_t& lhs, const wifi_config_t& r
if(lhs.ap.pairwise_cipher != rhs.ap.pairwise_cipher) { if(lhs.ap.pairwise_cipher != rhs.ap.pairwise_cipher) {
return false; return false;
} }
if(lhs.ap.ftm_responder != rhs.ap.ftm_responder) {
return false;
}
return true; return true;
} }
void wifi_softap_config(wifi_config_t *wifi_config, const char * ssid=NULL, const char * password=NULL, uint8_t channel=6, wifi_auth_mode_t authmode=WIFI_AUTH_WPA2_PSK, uint8_t ssid_hidden=0, uint8_t max_connections=4, uint16_t beacon_interval=100){ void wifi_softap_config(wifi_config_t *wifi_config, const char * ssid=NULL, const char * password=NULL, uint8_t channel=6, wifi_auth_mode_t authmode=WIFI_AUTH_WPA2_PSK, uint8_t ssid_hidden=0, uint8_t max_connections=4, bool ftm_responder=false, uint16_t beacon_interval=100){
wifi_config->ap.channel = channel; wifi_config->ap.channel = channel;
wifi_config->ap.max_connection = max_connections; wifi_config->ap.max_connection = max_connections;
wifi_config->ap.beacon_interval = beacon_interval; wifi_config->ap.beacon_interval = beacon_interval;
wifi_config->ap.ssid_hidden = ssid_hidden; wifi_config->ap.ssid_hidden = ssid_hidden;
@ -93,6 +96,7 @@ void wifi_softap_config(wifi_config_t *wifi_config, const char * ssid=NULL, cons
wifi_config->ap.ssid_len = 0; wifi_config->ap.ssid_len = 0;
wifi_config->ap.ssid[0] = 0; wifi_config->ap.ssid[0] = 0;
wifi_config->ap.password[0] = 0; wifi_config->ap.password[0] = 0;
wifi_config->ap.ftm_responder = ftm_responder;
if(ssid != NULL && ssid[0] != 0){ if(ssid != NULL && ssid[0] != 0){
snprintf((char*)wifi_config->ap.ssid, 32, ssid); snprintf((char*)wifi_config->ap.ssid, 32, ssid);
wifi_config->ap.ssid_len = strlen(ssid); wifi_config->ap.ssid_len = strlen(ssid);
@ -117,7 +121,7 @@ void wifi_softap_config(wifi_config_t *wifi_config, const char * ssid=NULL, cons
* @param ssid_hidden Network cloaking (0 = broadcast SSID, 1 = hide SSID) * @param ssid_hidden Network cloaking (0 = broadcast SSID, 1 = hide SSID)
* @param max_connection Max simultaneous connected clients, 1 - 4. * @param max_connection Max simultaneous connected clients, 1 - 4.
*/ */
bool WiFiAPClass::softAP(const char* ssid, const char* passphrase, int channel, int ssid_hidden, int max_connection) bool WiFiAPClass::softAP(const char* ssid, const char* passphrase, int channel, int ssid_hidden, int max_connection, bool ftm_responder)
{ {
if(!WiFi.enableAP(true)) { if(!WiFi.enableAP(true)) {
@ -140,7 +144,7 @@ bool WiFiAPClass::softAP(const char* ssid, const char* passphrase, int channel,
wifi_config_t conf; wifi_config_t conf;
wifi_config_t conf_current; wifi_config_t conf_current;
wifi_softap_config(&conf, ssid, passphrase, channel, WIFI_AUTH_WPA2_PSK, ssid_hidden, max_connection); wifi_softap_config(&conf, ssid, passphrase, channel, WIFI_AUTH_WPA2_PSK, ssid_hidden, max_connection, ftm_responder);
esp_err_t err = esp_wifi_get_config((wifi_interface_t)WIFI_IF_AP, &conf_current); esp_err_t err = esp_wifi_get_config((wifi_interface_t)WIFI_IF_AP, &conf_current);
if(err){ if(err){
log_e("get AP config failed"); log_e("get AP config failed");

View File

@ -37,7 +37,7 @@ class WiFiAPClass
public: public:
bool softAP(const char* ssid, const char* passphrase = NULL, int channel = 1, int ssid_hidden = 0, int max_connection = 4); bool softAP(const char* ssid, const char* passphrase = NULL, int channel = 1, int ssid_hidden = 0, int max_connection = 4, bool ftm_responder = false);
bool softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet); bool softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet);
bool softAPdisconnect(bool wifioff = false); bool softAPdisconnect(bool wifioff = false);

View File

@ -395,6 +395,14 @@ static void _arduino_event_cb(void* arg, esp_event_base_t event_base, int32_t ev
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_WPS_ER_PBC_OVERLAP) { } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_WPS_ER_PBC_OVERLAP) {
arduino_event.event_id = ARDUINO_EVENT_WPS_ER_PBC_OVERLAP; arduino_event.event_id = ARDUINO_EVENT_WPS_ER_PBC_OVERLAP;
/*
* FTM
* */
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_FTM_REPORT) {
wifi_event_ftm_report_t * event = (wifi_event_ftm_report_t*)event_data;
arduino_event.event_id = ARDUINO_EVENT_WIFI_FTM_REPORT;
memcpy(&arduino_event.event_info.wifi_ftm_report, event_data, sizeof(wifi_event_ftm_report_t));
/* /*
* SMART CONFIG * SMART CONFIG
@ -778,7 +786,8 @@ const char * arduino_event_names[] = {
"WIFI_READY", "WIFI_READY",
"SCAN_DONE", "SCAN_DONE",
"STA_START", "STA_STOP", "STA_CONNECTED", "STA_DISCONNECTED", "STA_AUTHMODE_CHANGE", "STA_GOT_IP", "STA_GOT_IP6", "STA_LOST_IP", "STA_START", "STA_STOP", "STA_CONNECTED", "STA_DISCONNECTED", "STA_AUTHMODE_CHANGE", "STA_GOT_IP", "STA_GOT_IP6", "STA_LOST_IP",
"AP_START", "AP_STOP", "AP_STACONNECTED", "AP_STADISCONNECTED", "AP_STAIPASSIGNED", "AP_PROBEREQRECVED", "AP_GOT_IP6", "AP_START", "AP_STOP", "AP_STACONNECTED", "AP_STADISCONNECTED", "AP_STAIPASSIGNED", "AP_PROBEREQRECVED", "AP_GOT_IP6",
"FTM_REPORT",
"ETH_START", "ETH_STOP", "ETH_CONNECTED", "ETH_DISCONNECTED", "ETH_GOT_IP", "ETH_GOT_IP6", "ETH_START", "ETH_STOP", "ETH_CONNECTED", "ETH_DISCONNECTED", "ETH_GOT_IP", "ETH_GOT_IP6",
"WPS_ER_SUCCESS", "WPS_ER_FAILED", "WPS_ER_TIMEOUT", "WPS_ER_PIN", "WPS_ER_PBC_OVERLAP", "WPS_ER_SUCCESS", "WPS_ER_FAILED", "WPS_ER_TIMEOUT", "WPS_ER_PIN", "WPS_ER_PBC_OVERLAP",
"SC_SCAN_DONE", "SC_FOUND_CHANNEL", "SC_GOT_SSID_PSWD", "SC_SEND_ACK_DONE", "SC_SCAN_DONE", "SC_FOUND_CHANNEL", "SC_GOT_SSID_PSWD", "SC_SEND_ACK_DONE",
@ -1125,6 +1134,32 @@ wifi_power_t WiFiGenericClass::getTxPower(){
return (wifi_power_t)power; return (wifi_power_t)power;
} }
/**
* Initiate FTM Session.
* @param frm_count Number of FTM frames requested in terms of 4 or 8 bursts (allowed values - 0(No pref), 16, 24, 32, 64)
* @param burst_period Requested time period between consecutive FTM bursts in 100's of milliseconds (allowed values - 0(No pref), 2 - 255)
* @param channel Primary channel of the FTM Responder
* @param mac MAC address of the FTM Responder
* @return true on success
*/
bool WiFiGenericClass::initiateFTM(uint8_t frm_count, uint16_t burst_period, uint8_t channel, const uint8_t * mac) {
wifi_ftm_initiator_cfg_t ftmi_cfg = {
.resp_mac = {0,0,0,0,0,0},
.channel = channel,
.frm_count = frm_count,
.burst_period = burst_period,
};
if(mac != NULL){
memcpy(ftmi_cfg.resp_mac, mac, 6);
}
// Request FTM session with the Responder
if (ESP_OK != esp_wifi_ftm_initiate_session(&ftmi_cfg)) {
log_e("Failed to initiate FTM session");
return false;
}
return true;
}
// ----------------------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------------------
// ------------------------------------------------ Generic Network function --------------------------------------------- // ------------------------------------------------ Generic Network function ---------------------------------------------
// ----------------------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------------------

View File

@ -51,6 +51,7 @@ typedef enum {
ARDUINO_EVENT_WIFI_AP_STAIPASSIGNED, ARDUINO_EVENT_WIFI_AP_STAIPASSIGNED,
ARDUINO_EVENT_WIFI_AP_PROBEREQRECVED, ARDUINO_EVENT_WIFI_AP_PROBEREQRECVED,
ARDUINO_EVENT_WIFI_AP_GOT_IP6, ARDUINO_EVENT_WIFI_AP_GOT_IP6,
ARDUINO_EVENT_WIFI_FTM_REPORT,
ARDUINO_EVENT_ETH_START, ARDUINO_EVENT_ETH_START,
ARDUINO_EVENT_ETH_STOP, ARDUINO_EVENT_ETH_STOP,
ARDUINO_EVENT_ETH_CONNECTED, ARDUINO_EVENT_ETH_CONNECTED,
@ -86,6 +87,7 @@ typedef union {
wifi_event_ap_probe_req_rx_t wifi_ap_probereqrecved; wifi_event_ap_probe_req_rx_t wifi_ap_probereqrecved;
wifi_event_ap_staconnected_t wifi_ap_staconnected; wifi_event_ap_staconnected_t wifi_ap_staconnected;
wifi_event_ap_stadisconnected_t wifi_ap_stadisconnected; wifi_event_ap_stadisconnected_t wifi_ap_stadisconnected;
wifi_event_ftm_report_t wifi_ftm_report;
ip_event_ap_staipassigned_t wifi_ap_staipassigned; ip_event_ap_staipassigned_t wifi_ap_staipassigned;
ip_event_got_ip_t got_ip; ip_event_got_ip_t got_ip;
ip_event_got_ip6_t got_ip6; ip_event_got_ip6_t got_ip6;
@ -170,6 +172,8 @@ class WiFiGenericClass
bool setTxPower(wifi_power_t power); bool setTxPower(wifi_power_t power);
wifi_power_t getTxPower(); wifi_power_t getTxPower();
bool initiateFTM(uint8_t frm_count=16, uint16_t burst_period=2, uint8_t channel=0, const uint8_t * mac=NULL);
static const char * getHostname(); static const char * getHostname();
static bool setHostname(const char * hostname); static bool setHostname(const char * hostname);
static bool hostname(const String& aHostname) { return setHostname(aHostname.c_str()); } static bool hostname(const String& aHostname) { return setHostname(aHostname.c_str()); }