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