diff --git a/cpu/esp32/doc.txt b/cpu/esp32/doc.txt
index b6ca540d50..b363bdd10a 100644
--- a/cpu/esp32/doc.txt
+++ b/cpu/esp32/doc.txt
@@ -49,8 +49,9 @@
8. [Network Interfaces](#esp32_network_interfaces)
1. [Ethernet MAC Network Interface](#esp32_ethernet_network_interface)
2. [WiFi Network Interface](#esp32_wifi_network_interface)
- 3. [ESP-NOW Network Interface](#esp32_esp_now_network_interface)
- 4. [Other Network Devices](#esp32_other_network_devices)
+ 3. [WiFi SoftAP Network Interface](#esp32_wifi_ap_network_interface)
+ 4. [ESP-NOW Network Interface](#esp32_esp_now_network_interface)
+ 5. [Other Network Devices](#esp32_other_network_devices)
10. [Application-Specific Configurations](#esp32_application_specific_configurations)
1. [Make Variable ```CONFIGS```](#esp32_config_make_variable)
2. [Application-Specific Board Configuration](#esp32_application_specific_board_configuration)
@@ -124,6 +125,7 @@ Module | Default | Short description
[esp_spi_ram](#esp32_spi_ram) | not used | enable SPI RAM
[esp_spiffs](#esp32_spiffs_device) | not used | enable SPIFFS for on-board flash memory
[esp_wifi](#esp32_wifi_network_interface) | not used | enable the Wifi network device in WPA2 personal mode
+[esp_wifi_ap](#esp32_wifi_ap_network_interface) | not used | enable the WiFi SoftAP network device
[esp_wifi_enterprise](#esp32_wifi_network_interface) | not used | enable the Wifi network device in WPA2 enterprise mode
@@ -425,6 +427,7 @@ esp_rtc_timer_32k | Enable RTC hardware timer with external 32.768 kHz crystal.
esp_spiffs | Enable the optional SPIFFS drive in on-board flash memory, see section [SPIFFS Device](#esp32_spiffs_device).
esp_spi_ram | Enable the optional SPI RAM, see section [SPI RAM Modules](#esp32_spi_ram).
esp_wifi | Enable the built-in WiFi module as `netdev` network device in WPA2 personal mode, see section [WiFi Network Interface](#esp32_wifi_network_interface).
+esp_wifi_ap | Enable the built-in WiFi SoftAP module as `netdev` network device, see section [WiFi SoftAP Network Interface](#esp32_wifi_ap_network_interface).
esp_wifi_enterprise | Enable the built-in WiFi module as `netdev` network device in WPA2 enterprise mode, see section [WiFi Network Interface](#esp32_wifi_network_interface).
@@ -1256,6 +1259,53 @@ In this case the ESP-NOW interface must use the same channel as the AP of the
infrastructure WiFi network. All ESP-NOW nodes must therefore be compiled with
the channel of the AP as value for the parameter 'ESP_NOW_CHANNEL'.
+\anchor esp32_wifi_ap_network_interface
+## WiFi SoftAP Network Interface [[TOC](#esp32_toc)]
+
+The RIOT port for the ESP32 supports a `netdev` interface for the ESP32 WiFi
+SoftAP mode. Module `esp_wifi_ap` has to be enabled to use it.
+
+The following parameters can be configured:
+
+
+
+Parameter | Default | Description
+:-------------------------|:--------------------------|:-------------
+#ESP_WIFI_SSID | "RIOT_AP" | Static SSID definition for the SoftAP
+#ESP_WIFI_AP_PREFIX | "RIOT_AP_" | Optional prefix for dynamic SSID, if used, the node will create the SSID based on the prefix + mac address (e.g.: "RIOT_AP_aabbccddeeff"). This is disabled by default and `ESP_WIFI_SSID` is used, define this to enable the usage of the SSID prefix.
+#ESP_WIFI_PASS | none | The password for the WiFi SoftAP network interface. If no password is provided, the interface will be "open", otherwise it uses WPA2-PSK authentication mode.
+#ESP_WIFI_SSID_HIDDEN | 0 | Whether the SoftAP SSID should be hidden.
+#ESP_WIFI_MAX_CONN | 4 | The maximum number of connections for the SoftAP.
+#ESP_WIFI_BEACON_INTERVAL | 100 | The beacon interval time in milliseconds for the SoftAP.
+#ESP_WIFI_STACKSIZE | #THREAD_STACKSIZE_DEFAULT | Stack size used for the WiFi netdev driver thread.
+
+
+
+These configuration parameter definitions, as well as enabling the `esp_wifi_ap`
+module, can be done either in the makefile of the project or at make command
+line, for example:
+
+```
+USEMODULE=esp_wifi_ap \
+CFLAGS='-DESP_WIFI_SSID=\"MySSID\" -DESP_WIFI_PASS=\"MyPassphrase\" -DESP_WIFI_MAX_CONN=1 \
+make -C examples/gnrc_networking BOARD=...
+```
+
+@note
+- The `esp_wifi_ap` module is not used by default when `netdev_default` is used.
+- Supports open and WPA2-PSK authentication modes.
+- The ESP-NOW network interface and the WiFi SoftAP network interface can not
+be used simultaneously.
+
+@warning
+The SoftAP may or may not be at all reliable sometimes, this is a known
+problem with the Wi-Fi network interface, even on the official ESP-IDF.
+The problem is that the AP doesn't cache multicast data for connected
+stations, and if stations connected to the AP are power save enabled,
+they may experience multicast packet loss. This affects RIOT, because
+NDP relies on multicast packets to work correctly.
+Refer to the SDK documentation from Espressif on [AP Sleep](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/wifi.html#ap-sleep) for more information.
+
\anchor esp32_esp_now_network_interface
## ESP-NOW Network Interface [[TOC](#esp32_toc)]
diff --git a/cpu/esp8266/doc.txt b/cpu/esp8266/doc.txt
index 943dccb30b..c621328e63 100644
--- a/cpu/esp8266/doc.txt
+++ b/cpu/esp8266/doc.txt
@@ -29,7 +29,8 @@
8. [Other Peripherals](#esp8266_other_peripherals)
7. [Network Interfaces](#esp8266_network_interfaces)
1. [WiFi Network Interface](#esp8266_wifi_network_interface)
- 2. [ESP-NOW Network Interface](#esp8266_esp_now_network_interface)
+ 2. [WiFi SoftAP Network Interface](#esp8266_wifi_ap_network_interface)
+ 3. [ESP-NOW Network Interface](#esp8266_esp_now_network_interface)
8. [Preconfigured Devices](#esp8266_preconfigured_devices)
1. [Network Devices](#esp8266_network_devices)
2. [SD-Card Device](#esp8266_sd_card_device)
@@ -112,6 +113,7 @@ Module | Default | Short description
[esp_qemu](#esp8266_qemu_mode_and_gdb) | not used | generate image for `QEMU` and `GDB` debugging
[esp_spiffs](#esp8266_spiffs_device) | not used | enable SPIFFS for on-board flash memory
[esp_wifi](#esp8266_wifi_network_interface) | not used | enable the Wifi network device
+[esp_wifi_ap](#esp8266_wifi_ap_network_interface) | not used | enable the Wifi SoftAP network device
@@ -418,6 +420,7 @@ Module | Description
[esp_spiffs](#esp8266_spiffs_device) | Enable the SPIFFS drive in on-board flash memory
[esp_sw_timer](#esp8266_timers) | Enable software timer implementation
[esp_wifi](#esp8266_wifi_network_interface) | Enable the built-in WiFi module in infrastructure mode as `netdev` network device
+[esp_wifi_ap](#esp8266_wifi_ap_network_interface) | Enable the built-in WiFi SoftAP module as `netdev` network device
@@ -714,6 +717,53 @@ In this case the ESP-NOW interface must use the same channel as the AP of the
infrastructure WiFi network. All ESP-NOW nodes must therefore be compiled with
the channel of the AP asvalue for the parameter 'ESP_NOW_CHANNEL'.
+\anchor esp8266_wifi_ap_network_interface
+## WiFi SoftAP Network Interface [[TOC](#esp8266_toc)]
+
+The RIOT port for the ESP8266 supports a `netdev` interface for the ESP32 WiFi
+SoftAP mode. Module `esp_wifi_ap` has to be enabled to use it.
+
+The following parameters can be configured:
+
+
+
+Parameter | Default | Description
+:-------------------------|:--------------------------|:-------------
+#ESP_WIFI_SSID | "RIOT_AP" | Static SSID definition for the SoftAP
+#ESP_WIFI_AP_PREFIX | "RIOT_AP_" | Optional prefix for dynamic SSID, if used, the node will create the SSID based on the prefix + mac address (e.g.: "RIOT_AP_aabbccddeeff"). This is disabled by default and `ESP_WIFI_SSID` is used, define this to enable the usage of the SSID prefix.
+#ESP_WIFI_PASS | none | The password for the WiFi SoftAP network interface. If no password is provided, the interface will be "open", otherwise it uses WPA2-PSK authentication mode.
+#ESP_WIFI_SSID_HIDDEN | 0 | Whether the SoftAP SSID should be hidden.
+#ESP_WIFI_MAX_CONN | 4 | The maximum number of connections for the SoftAP.
+#ESP_WIFI_BEACON_INTERVAL | 100 | The beacon interval time in milliseconds for the SoftAP.
+#ESP_WIFI_STACKSIZE | #THREAD_STACKSIZE_DEFAULT | Stack size used for the WiFi netdev driver thread.
+
+
+
+These configuration parameter definitions, as well as enabling the `esp_wifi_ap`
+module, can be done either in the makefile of the project or at make command
+line, for example:
+
+```
+USEMODULE=esp_wifi_ap \
+CFLAGS='-DESP_WIFI_SSID=\"MySSID\" -DESP_WIFI_PASS=\"MyPassphrase\" -DESP_WIFI_MAX_CONN=1 \
+make -C examples/gnrc_networking BOARD=...
+```
+
+@note
+- The `esp_wifi_ap` module is not used by default when `netdev_default` is used.
+- Supports open and WPA2-PSK authentication modes.
+- The ESP-NOW network interface and the WiFi SoftAP network interface can not
+be used simultaneously.
+
+@warning
+The SoftAP may or may not be at all reliable sometimes, this is a known
+problem with the Wi-Fi network interface, even on the official ESP-IDF.
+The problem is that the AP doesn't cache multicast data for connected
+stations, and if stations connected to the AP are power save enabled,
+they may experience multicast packet loss. This affects RIOT, because
+NDP relies on multicast packets to work correctly.
+Refer to the SDK documentation from Espressif on [AP Sleep](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/wifi.html#ap-sleep) for more information.
+
\anchor esp8266_esp_now_network_interface
## ESP-NOW Network Interface [[TOC](#esp8266_toc)]
diff --git a/cpu/esp_common/Kconfig b/cpu/esp_common/Kconfig
index 5aa7ead0a3..dd7fc1758f 100644
--- a/cpu/esp_common/Kconfig
+++ b/cpu/esp_common/Kconfig
@@ -15,6 +15,7 @@ config CPU_COMMON_ESP
select HAS_ESP_NOW
select HAS_ESP_SPIFFS
select HAS_ESP_WIFI
+ select HAS_ESP_WIFI_AP
select HAS_LIBSTDCPP
select HAS_PERIPH_CPUID
select HAS_PERIPH_HWRNG
@@ -34,6 +35,11 @@ config HAS_ESP_WIFI
help
Indicates that an ESP WiFi radio is present.
+config HAS_ESP_WIFI_AP
+ bool
+ help
+ Indicates that ESP WiFi SoftAP support is present.
+
config HAS_ESP_NOW
bool
help
diff --git a/cpu/esp_common/Makefile.dep b/cpu/esp_common/Makefile.dep
index 84877e933f..500f071308 100644
--- a/cpu/esp_common/Makefile.dep
+++ b/cpu/esp_common/Makefile.dep
@@ -24,6 +24,11 @@ USEMODULE += xtensa
FEATURES_REQUIRED += cpp # Vendor code uses C++
+ifneq (,$(filter esp_wifi_ap,$(USEMODULE)))
+ FEATURES_REQUIRED += esp_wifi_ap
+ USEMODULE += esp_wifi
+endif
+
ifneq (,$(filter esp_wifi_enterprise,$(USEMODULE)))
FEATURES_REQUIRED += esp_wifi_enterprise
USEMODULE += esp_wifi
diff --git a/cpu/esp_common/Makefile.features b/cpu/esp_common/Makefile.features
index 0020b7af35..af36311915 100644
--- a/cpu/esp_common/Makefile.features
+++ b/cpu/esp_common/Makefile.features
@@ -7,6 +7,7 @@ FEATURES_PROVIDED += arch_esp
FEATURES_PROVIDED += cpp
FEATURES_PROVIDED += esp_now
FEATURES_PROVIDED += esp_spiffs
+FEATURES_PROVIDED += esp_wifi_ap
FEATURES_PROVIDED += esp_wifi
FEATURES_PROVIDED += libstdcpp
FEATURES_PROVIDED += periph_cpuid
@@ -14,3 +15,6 @@ FEATURES_PROVIDED += periph_hwrng
FEATURES_PROVIDED += periph_pm
FEATURES_PROVIDED += periph_timer
FEATURES_PROVIDED += ssp
+
+FEATURES_CONFLICT += esp_wifi_ap:esp_now
+FEATURES_CONFLICT_MSG += "ESP_NOW and ESP_WIFI_AP can not be used at the same time."
diff --git a/cpu/esp_common/Makefile.include b/cpu/esp_common/Makefile.include
index 3e00c42f6c..aff5f8babe 100644
--- a/cpu/esp_common/Makefile.include
+++ b/cpu/esp_common/Makefile.include
@@ -14,6 +14,7 @@ PSEUDOMODULES += esp_log_startup
PSEUDOMODULES += esp_qemu
PSEUDOMODULES += esp_spiffs
PSEUDOMODULES += esp_wifi_any
+PSEUDOMODULES += esp_wifi_ap
# Common includes
diff --git a/cpu/esp_common/esp-wifi/esp_wifi_netdev.c b/cpu/esp_common/esp-wifi/esp_wifi_netdev.c
index 9e1b10a95c..292f6c0fc8 100644
--- a/cpu/esp_common/esp-wifi/esp_wifi_netdev.c
+++ b/cpu/esp_common/esp-wifi/esp_wifi_netdev.c
@@ -30,7 +30,9 @@
#include "esp_common.h"
#include "esp_attr.h"
#include "esp_event_loop.h"
+#ifndef MODULE_ESP_WIFI_AP
#include "esp_now.h"
+#endif
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_wifi_internal.h"
@@ -57,6 +59,9 @@
#define ESP_WIFI_LOG_ERROR(f, ...) \
LOG_TAG_ERROR("esp_wifi", f "\n", ## __VA_ARGS__)
+#define ESP_WIFI_LOG_DEBUG(f, ...) \
+ LOG_TAG_DEBUG("esp_wifi", f "\n", ## __VA_ARGS__)
+
#define MAC_STR "%02x:%02x:%02x:%02x:%02x:%02x"
#define MAC_STR_ARG(m) m[0], m[1], m[2], m[3], m[4], m[5]
@@ -195,6 +200,7 @@ static int _esp_wifi_tx_cb(esp_aio_t* aio)
*/
int esp_wifi_internal_tx(wifi_interface_t wifi_if, void *buf, uint16_t len)
{
+ (void)wifi_if;
ESP_WIFI_DEBUG("buf=%p len=%u", buf, len);
struct pbuf *pb = _esp_wifi_pbuf_alloc(len);
@@ -206,7 +212,7 @@ int esp_wifi_internal_tx(wifi_interface_t wifi_if, void *buf, uint16_t len)
}
esp_aio_t aio;
- aio.fd = wifi_if;
+ aio.fd = _esp_wifi_socket;
aio.pbuf = pb->payload;
aio.len = pb->len;
aio.cb = _esp_wifi_tx_cb;
@@ -245,7 +251,7 @@ typedef int (*wifi_rxcb_t)(struct esp_aio *aio);
*/
esp_err_t esp_wifi_internal_reg_rxcb(wifi_interface_t ifx, wifi_rxcb_t fn)
{
- assert(ifx == ESP_IF_WIFI_STA);
+ assert(ifx == ESP_IF_WIFI_STA || ifx == ESP_IF_WIFI_AP);
ESP_WIFI_DEBUG("%d %p", ifx, fn);
@@ -268,13 +274,16 @@ esp_err_t esp_wifi_internal_reg_rxcb(wifi_interface_t ifx, wifi_rxcb_t fn)
/* now, we have to allocate a new socket and register the function */
_esp_wifi_socket = esp_socket(AF_PACKET, SOCK_RAW, ETH_P_ALL);
-
+ const char *ifx_name = "sta0";
+ if (ifx == ESP_IF_WIFI_AP) {
+ ifx_name = "ap0";
+ }
if (_esp_wifi_socket < 0) {
ESP_WIFI_LOG_ERROR("create socket of (AF_PACKET, SOCK_RAW, ETH_P_ALL) error");
return ESP_FAIL;
}
- if (esp_ioctl(_esp_wifi_socket, SIOCGIFINDEX, "sta0") < 0) {
- ESP_WIFI_LOG_ERROR("bind socket %d to netcard %s error", _esp_wifi_socket, "sta0");
+ if (esp_ioctl(_esp_wifi_socket, SIOCGIFINDEX, ifx_name) < 0) {
+ ESP_WIFI_LOG_ERROR("bind socket %d to netcard %s error", _esp_wifi_socket, ifx_name);
esp_close(_esp_wifi_socket);
return ESP_FAIL;
}
@@ -367,6 +376,7 @@ esp_err_t _esp_wifi_rx_cb(void *buffer, uint16_t len, void *eb)
return ESP_OK;
}
+#ifndef MODULE_ESP_WIFI_AP
#define REASON_BEACON_TIMEOUT (200)
#define REASON_HANDSHAKE_TIMEOUT (204)
#define INDEX_BEACON_TIMEOUT (REASON_BEACON_TIMEOUT - 24)
@@ -402,6 +412,7 @@ static const char *_esp_wifi_disc_reasons [] = {
"ASSOC_FAIL", /* 203 */
"HANDSHAKE_TIMEOUT" /* 204 */
};
+#endif /* MODULE_ESP_WIFI_AP */
/* indicator whether the WiFi interface is started */
static unsigned _esp_wifi_started = 0;
@@ -416,12 +427,47 @@ static esp_err_t IRAM_ATTR _esp_system_event_handler(void *ctx, system_event_t *
{
assert(event != NULL);
+#ifndef MODULE_ESP_WIFI_AP
esp_err_t result;
uint8_t reason;
const char* reason_str = "UNKNOWN";
+#endif /* MODULE_ESP_WIFI_AP */
- switch(event->event_id) {
+ switch (event->event_id) {
+#ifdef MODULE_ESP_WIFI_AP
+ case SYSTEM_EVENT_AP_START:
+ _esp_wifi_started = 1;
+ esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_AP, _esp_wifi_rx_cb);
+ ESP_WIFI_DEBUG("WiFi started");
+ break;
+
+ case SYSTEM_EVENT_AP_STOP:
+ _esp_wifi_started = 0;
+ esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_AP, NULL);
+ ESP_WIFI_DEBUG("WiFi stopped");
+ break;
+
+ case SYSTEM_EVENT_AP_STACONNECTED:
+ _esp_wifi_dev.sta_connected += 1;
+ ESP_WIFI_LOG_INFO("Station "MAC_STR" join (AID=%d)",
+ MAC_STR_ARG(event->event_info.sta_connected.mac),
+ event->event_info.sta_connected.aid);
+ break;
+
+ case SYSTEM_EVENT_AP_STADISCONNECTED:
+ _esp_wifi_dev.sta_connected -= 1;
+ ESP_WIFI_LOG_INFO("Station "MAC_STR" leave (AID=%d)",
+ MAC_STR_ARG(event->event_info.sta_disconnected.mac),
+ event->event_info.sta_disconnected.aid);
+ break;
+
+ case SYSTEM_EVENT_AP_PROBEREQRECVED:
+ ESP_WIFI_LOG_DEBUG("Station "MAC_STR" probed (rssi=%d)",
+ MAC_STR_ARG(event->event_info.ap_probereqrecved.mac),
+ event->event_info.ap_probereqrecved.rssi);
+ break;
+#else /* MODULE_ESP_WIFI_AP */
case SYSTEM_EVENT_STA_START:
_esp_wifi_started = 1;
ESP_WIFI_DEBUG("WiFi started");
@@ -495,6 +541,7 @@ static esp_err_t IRAM_ATTR _esp_system_event_handler(void *ctx, system_event_t *
}
break;
+#endif /* MODULE_ESP_WIFI_AP */
default:
ESP_WIFI_DEBUG("event %d", event->event_id);
@@ -517,11 +564,19 @@ static int _esp_wifi_send(netdev_t *netdev, const iolist_t *iolist)
esp_wifi_netdev_t* dev = (esp_wifi_netdev_t*)netdev;
+#ifdef MODULE_ESP_WIFI_AP
+ if (_esp_wifi_dev.sta_connected == 0) {
+ ESP_WIFI_DEBUG("No STAs are connected to SoftAP, cannot send");
+ _esp_wifi_send_is_in = false;
+ return -ENODEV;
+ }
+#else /* MODULE_ESP_WIFI_AP */
if (!_esp_wifi_dev.connected) {
ESP_WIFI_DEBUG("WiFi is still not connected to AP, cannot send");
_esp_wifi_send_is_in = false;
return -ENODEV;
}
+#endif /* MODULE_ESP_WIFI_AP */
critical_enter();
dev->tx_len = 0;
@@ -547,8 +602,12 @@ static int _esp_wifi_send(netdev_t *netdev, const iolist_t *iolist)
#endif
critical_exit();
+#ifdef MODULE_ESP_WIFI_AP
+ if (esp_wifi_internal_tx(ESP_IF_WIFI_AP, dev->tx_buf, dev->tx_len) == ESP_OK) {
+#else /* MODULE_ESP_WIFI_AP */
/* send the the packet to the peer(s) mac address */
if (esp_wifi_internal_tx(ESP_IF_WIFI_STA, dev->tx_buf, dev->tx_len) == ESP_OK) {
+#endif
#ifdef MCU_ESP32
/* for ESP8266 it is done in _esp_wifi_tx_cb */
_esp_wifi_send_is_in = false;
@@ -627,7 +686,9 @@ static int _esp_wifi_get(netdev_t *netdev, netopt_t opt, void *val, size_t max_l
assert(netdev != NULL);
assert(val != NULL);
+#ifndef MODULE_ESP_WIFI_AP
esp_wifi_netdev_t* dev = (esp_wifi_netdev_t*)netdev;
+#endif /* MODULE_ESP_WIFI_AP */
switch (opt) {
case NETOPT_IS_WIRED:
@@ -638,12 +699,21 @@ static int _esp_wifi_get(netdev_t *netdev, netopt_t opt, void *val, size_t max_l
return sizeof(uint16_t);
case NETOPT_ADDRESS:
assert(max_len >= ETHERNET_ADDR_LEN);
- esp_wifi_get_mac(ESP_MAC_WIFI_STA,(uint8_t *)val);
+#ifdef MODULE_ESP_WIFI_AP
+ esp_wifi_get_mac(ESP_MAC_WIFI_SOFTAP, (uint8_t *)val);
+#else /* MODULE_ESP_WIFI_AP */
+ esp_wifi_get_mac(ESP_MAC_WIFI_STA, (uint8_t *)val);
+#endif /* MODULE_ESP_WIFI_AP */
return ETHERNET_ADDR_LEN;
case NETOPT_LINK:
assert(max_len == sizeof(netopt_enable_t));
+#ifdef MODULE_ESP_WIFI_AP
+ *((netopt_enable_t *)val) = (_esp_wifi_started) ? NETOPT_ENABLE
+ : NETOPT_DISABLE;
+#else /* MOUDLE_ESP_WIFI_AP */
*((netopt_enable_t *)val) = (dev->connected) ? NETOPT_ENABLE
: NETOPT_DISABLE;
+#endif /* MODULE_ESP_WIFI_AP */
return sizeof(netopt_enable_t);
default:
return netdev_eth_get(netdev, opt, val, max_len);
@@ -660,7 +730,11 @@ static int _esp_wifi_set(netdev_t *netdev, netopt_t opt, const void *val, size_t
switch (opt) {
case NETOPT_ADDRESS:
assert(max_len == ETHERNET_ADDR_LEN);
+#ifdef MODULE_ESP_WIFI_AP
+ esp_wifi_set_mac(ESP_MAC_WIFI_SOFTAP, (uint8_t *)val);
+#else /* MODULE_ESP_WIFI_AP */
esp_wifi_set_mac(ESP_MAC_WIFI_STA, (uint8_t *)val);
+#endif /* MODULE_ESP_WIFI_AP */
return ETHERNET_ADDR_LEN;
default:
return netdev_eth_set(netdev, opt, val, max_len);
@@ -679,6 +753,7 @@ static void _esp_wifi_isr(netdev_t *netdev)
dev->event_recv--;
dev->netdev.event_callback(netdev, NETDEV_EVENT_RX_COMPLETE);
}
+#ifndef MODULE_ESP_WIFI_AP
if (dev->event_conn) {
dev->event_conn--;
dev->netdev.event_callback(netdev, NETDEV_EVENT_LINK_UP);
@@ -687,6 +762,7 @@ static void _esp_wifi_isr(netdev_t *netdev)
dev->event_disc--;
dev->netdev.event_callback(netdev, NETDEV_EVENT_LINK_DOWN);
}
+#endif
return;
}
@@ -708,6 +784,7 @@ static const netdev_driver_t _esp_wifi_driver =
.set = _esp_wifi_set,
};
+#ifndef MODULE_ESP_WIFI_AP
/*
* Static configuration for the Station interface
*/
@@ -730,8 +807,9 @@ static wifi_config_t wifi_config_sta = {
#endif
}
};
+#endif /* MODULE_ESP_WIFI_AP */
-#if defined(MCU_ESP8266) && !defined(MODULE_ESP_NOW)
+#if (defined(MCU_ESP8266) && !defined(MODULE_ESP_NOW)) || defined(MODULE_ESP_WIFI_AP)
/**
* Static configuration for the SoftAP interface if ESP-NOW is not enabled.
*
@@ -751,20 +829,28 @@ static wifi_config_t wifi_config_sta = {
*/
static wifi_config_t wifi_config_ap = {
.ap = {
+#ifdef ESP_WIFI_SSID
.ssid = ESP_WIFI_SSID,
- .ssid_len = ARRAY_SIZE(ESP_WIFI_SSID),
- .ssid_hidden = 1, /* don't make the AP visible */
+ .ssid_len = ARRAY_SIZE(ESP_WIFI_SSID) - 1,
+#endif
#ifdef ESP_WIFI_PASS
.password = ESP_WIFI_PASS,
.authmode = WIFI_AUTH_WPA2_PSK,
#else
.authmode = WIFI_AUTH_OPEN,
#endif
- .max_connection = 0, /* don't allow connections */
- .beacon_interval = 60000, /* send beacon only every 60 s */
+#ifdef MODULE_ESP_WIFI_AP
+ .ssid_hidden = ESP_WIFI_SSID_HIDDEN, /* don't make the AP visible */
+ .max_connection = ESP_WIFI_MAX_CONN, /* maximum number of connections */
+ .beacon_interval = ESP_WIFI_BEACON_INTERVAL,
+#else
+ .ssid_hidden = 1,
+ .max_connection = 0, /* don't allow connections */
+ .beacon_interval = 60000, /* send beacon only every 60 s */
+#endif
}
};
-#endif /* defined(MCU_ESP8266) && !defined(MODULE_ESP_NOW) */
+#endif /* (defined(MCU_ESP8266) && !defined(MODULE_ESP_NOW)) || defined(MODULE_ESP_WIFI_AP) */
void esp_wifi_setup (esp_wifi_netdev_t* dev)
{
@@ -809,7 +895,10 @@ void esp_wifi_setup (esp_wifi_netdev_t* dev)
/* TODO */
#endif
-#ifdef MCU_ESP8266
+#ifdef MODULE_ESP_WIFI_AP
+ /* Activate the SoftAP interface */
+ result = esp_wifi_set_mode(WIFI_MODE_AP);
+#elif defined(MCU_ESP8266)
/*
* Although only the Station interface is needed, the SoftAP interface must
* also be enabled on ESP8266 for stability reasons to prevent the Station
@@ -819,34 +908,43 @@ void esp_wifi_setup (esp_wifi_netdev_t* dev)
*/
/* activate the Station and the SoftAP interface */
result = esp_wifi_set_mode(WIFI_MODE_APSTA);
-#else /* MCU_ESP8266 */
+#else /* defined(MCU_ESP8266) */
/* activate only the Station interface */
result = esp_wifi_set_mode(WIFI_MODE_STA);
-#endif /* MCU_ESP8266 */
+#endif /* defined(MCU_ESP8266) */
if (result != ESP_OK) {
ESP_WIFI_LOG_ERROR("esp_wifi_set_mode failed with return value %d", result);
return;
}
-#ifdef MCU_ESP8266
+#if defined(MCU_ESP8266) || defined(MODULE_ESP_WIFI_AP)
+#ifdef ESP_WIFI_AP_PREFIX
+ uint8_t mac[ETHERNET_ADDR_LEN];
+ esp_wifi_get_mac(ESP_MAC_WIFI_SOFTAP, mac);
+ sprintf((char*)wifi_config_ap.ap.ssid, "%s%02x%02x%02x%02x%02x%02x",
+ ESP_WIFI_AP_PREFIX, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+ wifi_config_ap.ap.ssid_len = strlen((char*)wifi_config_ap.ap.ssid);
+#endif /* ESP_WIFI_AP_PREFIX */
/* set the SoftAP configuration */
result = esp_wifi_set_config(ESP_IF_WIFI_AP, &wifi_config_ap);
if (result != ESP_OK) {
ESP_WIFI_LOG_ERROR("esp_wifi_set_config softap failed with return value %d", result);
return;
}
-#endif /* MCU_ESP8266 */
+#endif /* defined(MCU_ESP8266) || defined(MODULE_ESP_WIFI_AP) */
#endif /* MODULE_ESP_NOW */
+#ifndef MODULE_ESP_WIFI_AP
/* set the Station configuration */
result = esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config_sta);
if (result != ESP_OK) {
ESP_WIFI_LOG_ERROR("esp_wifi_set_config station failed with return value %d", result);
return;
}
+#endif /* MODULE_ESP_WIFI_AP */
-#ifdef MODULE_ESP_WIFI_ENTERPRISE
+#if defined(MODULE_ESP_WIFI_ENTERPRISE) && !defined(MODULE_ESP_WIFI_AP)
esp_wpa2_config_t wifi_config_wpa2 = WPA2_CONFIG_INIT_DEFAULT();
#ifdef ESP_WIFI_EAP_ID
@@ -865,7 +963,7 @@ void esp_wifi_setup (esp_wifi_netdev_t* dev)
and the password for EAP phase 2 authentication in esp_wifi_enterprise
#endif /* defined(ESP_WIFI_EAP_USER) && defined(ESP_WIFI_EAP_PASS) */
esp_wifi_sta_wpa2_ent_enable(&wifi_config_wpa2);
-#endif /* MODULE_ESP_WIFI_ENTERPRISE */
+#endif /* defined(MODULE_ESP_WIFI_ENTERPRISE) && !defined(MODULE_ESP_WIFI_AP) */
/* start the WiFi driver */
result = esp_wifi_start();
@@ -874,17 +972,18 @@ void esp_wifi_setup (esp_wifi_netdev_t* dev)
return;
}
- /* register RX callback function */
- esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_STA, _esp_wifi_rx_cb);
-
/* set the netdev driver */
dev->netdev.driver = &_esp_wifi_driver;
/* initialize netdev data structure */
- dev->connected = false;
dev->event_recv = 0;
+#ifdef MODULE_ESP_WIFI_AP
+ dev->sta_connected = 0;
+#else /* MODULE_ESP_WIFI_AP */
dev->event_conn = 0;
dev->event_disc = 0;
+ dev->connected = false;
+#endif /* MODULE_ESP_WIFI_AP */
}
#endif /* MODULE_ESP_WIFI */
diff --git a/cpu/esp_common/esp-wifi/esp_wifi_netdev.h b/cpu/esp_common/esp-wifi/esp_wifi_netdev.h
index 3a04d0ffd7..f7793e1397 100644
--- a/cpu/esp_common/esp-wifi/esp_wifi_netdev.h
+++ b/cpu/esp_common/esp-wifi/esp_wifi_netdev.h
@@ -56,10 +56,14 @@ typedef struct
uint8_t tx_buf[ETHERNET_MAX_LEN]; /**< transmit buffer */
uint8_t event_recv; /**< number of frame received events */
+#ifdef MODULE_ESP_WIFI_AP
+ uint8_t sta_connected; /**< number of connected stations */
+#else /* MODULE_ESP_WIFI_AP */
uint8_t event_conn; /**< number of pending connect events */
uint8_t event_disc; /**< number of pending disc events */
bool connected; /**< indicates whether connected to AP */
+#endif /* MODULE_ESP_WIFI_AP */
mutex_t dev_lock; /**< device is already in use */
diff --git a/cpu/esp_common/esp-wifi/esp_wifi_params.h b/cpu/esp_common/esp-wifi/esp_wifi_params.h
index 135e0bc8a5..f61358c73b 100644
--- a/cpu/esp_common/esp-wifi/esp_wifi_params.h
+++ b/cpu/esp_common/esp-wifi/esp_wifi_params.h
@@ -44,10 +44,17 @@
/**
* @brief SSID of the AP to be used.
*/
-#ifndef ESP_WIFI_SSID
+#if !defined(ESP_WIFI_SSID) && !defined(ESP_WIFI_AP_PREFIX)
#define ESP_WIFI_SSID "RIOT_AP"
#endif
+/**
+ * @brief Prefix to be used as part of the SSID (e.g.: RIOT_AP_aabbccddeeff)
+ */
+#if !defined(ESP_WIFI_SSID) && !defined(ESP_WIFI_AP_PREFIX) || defined(DOXYGEN)
+#define ESP_WIFI_AP_PREFIX "RIOT_AP_"
+#endif
+
/**
* @brief Passphrase used for the AP as clear text (max. 64 chars).
*/
@@ -55,6 +62,31 @@
#define ESP_WIFI_PASS "ThisistheRIOTporttoESP"
#endif
+#if defined(MODULE_ESP_WIFI_AP) || defined(DOXYGEN)
+
+/**
+ * @brief Whether SoftAP SSID should be hidden.
+ */
+#ifndef ESP_WIFI_SSID_HIDDEN
+#define ESP_WIFI_SSID_HIDDEN (0)
+#endif
+
+/**
+ * @brief WiFi SoftAP maximum connections (max. 4).
+ */
+#ifndef ESP_WIFI_MAX_CONN
+#define ESP_WIFI_MAX_CONN (4)
+#endif
+
+/**
+ * @brief WiFi SoftAP beacon interval, in milliseconds.
+ */
+#ifndef ESP_WIFI_BEACON_INTERVAL
+#define ESP_WIFI_BEACON_INTERVAL (100)
+#endif
+
+#endif /* defined(ESP_WIFI_AP) || defined(DOXYGEN) */
+
/**@}*/
#ifdef __cplusplus