Merge pull request #13676 from gschorcht/cpu/esp/netopt_channel

cpu/esp: add NETOPT_CHANNEL for esp_wifi and esp_now
This commit is contained in:
benpicco 2020-03-27 16:37:41 +01:00 committed by GitHub
commit ad81a88bf0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 88 additions and 8 deletions

View File

@ -1260,6 +1260,9 @@ the verification of the AP certificate is not yet supported.
[ESP-NOW network interface](#esp32_esp_now_network_interface) (module `esp_now`) [ESP-NOW network interface](#esp32_esp_now_network_interface) (module `esp_now`)
can be used simultaneously, for example, to realize a border router for can be used simultaneously, for example, to realize a border router for
a mesh network which uses ESP-NOW. a mesh network which uses ESP-NOW.
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_esp_now_network_interface \anchor esp32_esp_now_network_interface
## <a name="esp32_esp_now_network_interface"> ESP-NOW Network Interface </a> &nbsp;[[TOC](#esp32_toc)] ## <a name="esp32_esp_now_network_interface"> ESP-NOW Network Interface </a> &nbsp;[[TOC](#esp32_toc)]
@ -1294,6 +1297,9 @@ ESP_NOW_KEY | NULL | Defines a key that is used for encrypted communication betw
[Wifi network interface](#esp32_wifi_network_interface) (module `esp_wifi` or `esp_wifi_enterprise`) [Wifi network interface](#esp32_wifi_network_interface) (module `esp_wifi` or `esp_wifi_enterprise`)
can be used simultaneously, for example, to realize a border router for can be used simultaneously, for example, to realize a border router for
a mesh network which uses ESP-NOW. a mesh network which uses ESP-NOW.
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'.
## <a name="esp32_other_network_devices"> Other Network Devices </a> &nbsp;[[TOC](#esp32_toc)] ## <a name="esp32_other_network_devices"> Other Network Devices </a> &nbsp;[[TOC](#esp32_toc)]

View File

@ -710,6 +710,9 @@ make -C examples/gnrc_networking BOARD=...
[ESP-NOW network interface](#esp8266_esp_now_network_interface) [ESP-NOW network interface](#esp8266_esp_now_network_interface)
(module `esp_now`) can be used simultaneously, for example, to realize a (module `esp_now`) can be used simultaneously, for example, to realize a
border router for a mesh network which uses ESP-NOW. border router for a mesh network which uses ESP-NOW.
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_esp_now_network_interface \anchor esp8266_esp_now_network_interface
## <a name="esp8266_esp_now_network_interface"> ESP-NOW Network Interface </a> &nbsp;[[TOC](#esp8266_toc)] ## <a name="esp8266_esp_now_network_interface"> ESP-NOW Network Interface </a> &nbsp;[[TOC](#esp8266_toc)]
@ -756,6 +759,9 @@ Parameter | Default | Description
[Wifi network interface](#esp8266_wifi_network_interface) (module `esp_wifi`) [Wifi network interface](#esp8266_wifi_network_interface) (module `esp_wifi`)
can be used simultaneously, for example, to realize a border router for can be used simultaneously, for example, to realize a border router for
a mesh network which uses ESP-NOW. a mesh network which uses ESP-NOW.
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'.
# <a name="esp8266_preconfigured_devices"> Preconfigured Devices </a> &nbsp;[[TOC](#esp8266_toc)] # <a name="esp8266_preconfigured_devices"> Preconfigured Devices </a> &nbsp;[[TOC](#esp8266_toc)]

View File

@ -45,5 +45,8 @@ ESP_NOW_KEY | NULL | Defines a key that is used for encrypted communication betw
Wifi network interface (module `esp_wifi`) Wifi network interface (module `esp_wifi`)
can be used simultaneously, for example, to realize a border router for can be used simultaneously, for example, to realize a border router for
a mesh network which uses ESP-NOW. a mesh network which uses ESP-NOW.
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'.
*/ */

View File

@ -100,7 +100,7 @@ static bool _esp_now_scan_peers_done = false;
static wifi_ap_record_t* aps = NULL; static wifi_ap_record_t* aps = NULL;
static uint32_t aps_size = 0; static uint32_t aps_size = 0;
static const wifi_scan_config_t scan_cfg = { static wifi_scan_config_t scan_cfg = {
.ssid = NULL, .ssid = NULL,
.bssid = NULL, .bssid = NULL,
.channel = ESP_NOW_CHANNEL, .channel = ESP_NOW_CHANNEL,
@ -290,6 +290,9 @@ static esp_err_t IRAM_ATTR _esp_system_event_handler(void *ctx, system_event_t *
extern esp_err_t esp_system_event_add_handler(system_event_cb_t handler, extern esp_err_t esp_system_event_add_handler(system_event_cb_t handler,
void *arg); void *arg);
/* ESP-NOW SoftAP configuration */
static wifi_config_t wifi_config_ap = {};
esp_now_netdev_t *netdev_esp_now_setup(void) esp_now_netdev_t *netdev_esp_now_setup(void)
{ {
esp_now_netdev_t* dev = &_esp_now_dev; esp_now_netdev_t* dev = &_esp_now_dev;
@ -360,9 +363,7 @@ esp_now_netdev_t *netdev_esp_now_setup(void)
/* get SoftAP interface mac address and store it as device address */ /* get SoftAP interface mac address and store it as device address */
esp_read_mac(dev->addr, ESP_MAC_WIFI_SOFTAP); esp_read_mac(dev->addr, ESP_MAC_WIFI_SOFTAP);
/* prepare the ESP_NOW configuration for SoftAP */ /* prepare initial ESP_NOW configuration for SoftAP */
wifi_config_t wifi_config_ap = {};
strcpy ((char*)wifi_config_ap.ap.password, esp_now_params.softap_pass); strcpy ((char*)wifi_config_ap.ap.password, esp_now_params.softap_pass);
sprintf((char*)wifi_config_ap.ap.ssid, "%s%02x%02x%02x%02x%02x%02x", sprintf((char*)wifi_config_ap.ap.ssid, "%s%02x%02x%02x%02x%02x%02x",
ESP_NOW_AP_PREFIX, ESP_NOW_AP_PREFIX,
@ -452,6 +453,31 @@ esp_now_netdev_t *netdev_esp_now_setup(void)
return dev; return dev;
} }
int esp_now_set_channel(uint8_t channel)
{
#ifdef ESP_NOW_UNICAST
scan_cfg.channel = channel;
#endif
#ifdef MODULE_ESP_WIFI
/* channel is controlled by `esp_wifi`, only update SoftAP info */
wifi_config_ap.ap.channel = channel;
return ESP_ERR_NOT_SUPPORTED;
#else
/* channel is controlled by `esp_now`, try to reconfigure SoftAP */
uint8_t old_channel = wifi_config_ap.ap.channel;
wifi_config_ap.ap.channel = channel;
esp_err_t result = esp_wifi_set_config(ESP_IF_WIFI_AP, &wifi_config_ap);
if (result != ESP_OK) {
LOG_TAG_ERROR("esp_now",
"esp_wifi_set_config softap failed with return value %d\n",
result);
wifi_config_ap.ap.channel = old_channel;
return result;
}
return ESP_OK;
#endif
}
static int _init(netdev_t *netdev) static int _init(netdev_t *netdev)
{ {
DEBUG("%s: %p\n", __func__, netdev); DEBUG("%s: %p\n", __func__, netdev);
@ -636,6 +662,12 @@ static int _get(netdev_t *netdev, netopt_t opt, void *val, size_t max_len)
res = sizeof(dev->addr); res = sizeof(dev->addr);
break; break;
case NETOPT_CHANNEL:
CHECK_PARAM_RET(max_len >= sizeof(uint16_t), -EOVERFLOW);
*((uint16_t *)val) = wifi_config_ap.ap.channel;
res = sizeof(uint16_t);
break;
default: default:
DEBUG("%s: %s not supported\n", __func__, netopt2str(opt)); DEBUG("%s: %s not supported\n", __func__, netopt2str(opt));
break; break;
@ -669,6 +701,15 @@ static int _set(netdev_t *netdev, netopt_t opt, const void *val, size_t max_len)
res = sizeof(dev->addr); res = sizeof(dev->addr);
break; break;
case NETOPT_CHANNEL:
CHECK_PARAM_RET(max_len >= sizeof(uint16_t), -EOVERFLOW);
uint16_t channel = *((uint16_t *)val);
if (esp_now_set_channel(channel) != ESP_OK) {
return -ENOTSUP;
}
res = sizeof(uint16_t);
break;
default: default:
DEBUG("%s: %s not supported\n", __func__, netopt2str(opt)); DEBUG("%s: %s not supported\n", __func__, netopt2str(opt));
break; break;

View File

@ -94,17 +94,25 @@ typedef struct
mutex_t dev_lock; /**< device is already in use */ mutex_t dev_lock; /**< device is already in use */
uint8_t scan_event; /**< ESP-NOW peers have to be scannged */ uint8_t scan_event; /**< ESP-NOW peers have to be scanned */
} esp_now_netdev_t; } esp_now_netdev_t;
/** /**
* @brief netdev <-> esp_npw glue code initialization function * @brief ESP-NOW netdev initialization function
* *
* @return NULL on error, pointer to esp_now_netdev on success * @return NULL on error, pointer to esp_now_netdev on success
*/ */
esp_now_netdev_t *netdev_esp_now_setup(void); esp_now_netdev_t *netdev_esp_now_setup(void);
/**
* @brief Set the channel used by ESP-NOW netdev
*
* @param channel Channel to be used
* @return ESP_OK on success, an ESP error code otherwise
*/
int esp_now_set_channel(uint8_t channel);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -114,4 +114,8 @@ the verification of the AP certificate is not yet supported.
ESP-NOW network interface (module `esp_now`) ESP-NOW network interface (module `esp_now`)
can be used simultaneously, for example, to realize a border router for can be used simultaneously, for example, to realize a border router for
a mesh network which uses ESP-NOW. a mesh network which uses ESP-NOW.
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'.
*/ */

View File

@ -402,8 +402,12 @@ static const char *_esp_wifi_disc_reasons [] = {
"HANDSHAKE_TIMEOUT" /* 204 */ "HANDSHAKE_TIMEOUT" /* 204 */
}; };
/* indicator whether the WiFi interface is started */
static unsigned _esp_wifi_started = 0; static unsigned _esp_wifi_started = 0;
/* current channel used by the WiFi interface */
static unsigned _esp_wifi_channel = 0;
/* /*
* Event handler for esp system events. * Event handler for esp system events.
*/ */
@ -440,7 +444,11 @@ static esp_err_t IRAM_ATTR _esp_system_event_handler(void *ctx, system_event_t *
ESP_WIFI_LOG_INFO("WiFi connected to ssid %s, channel %d", ESP_WIFI_LOG_INFO("WiFi connected to ssid %s, channel %d",
event->event_info.connected.ssid, event->event_info.connected.ssid,
event->event_info.connected.channel); event->event_info.connected.channel);
_esp_wifi_channel = event->event_info.connected.channel;
#ifdef MODULE_ESP_NOW
extern void esp_now_set_channel(uint8_t channel);
esp_now_set_channel(_esp_wifi_channel);
#endif
/* register RX callback function */ /* register RX callback function */
esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_STA, _esp_wifi_rx_cb); esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_STA, _esp_wifi_rx_cb);
@ -623,6 +631,10 @@ static int _esp_wifi_get(netdev_t *netdev, netopt_t opt, void *val, size_t max_l
switch (opt) { switch (opt) {
case NETOPT_IS_WIRED: case NETOPT_IS_WIRED:
return -ENOTSUP; return -ENOTSUP;
case NETOPT_CHANNEL:
CHECK_PARAM_RET(max_len >= sizeof(uint16_t), -EOVERFLOW);
*((uint16_t *)val) = _esp_wifi_channel;
return sizeof(uint16_t);
case NETOPT_ADDRESS: case NETOPT_ADDRESS:
assert(max_len >= ETHERNET_ADDR_LEN); assert(max_len >= ETHERNET_ADDR_LEN);
esp_wifi_get_mac(ESP_MAC_WIFI_STA,(uint8_t *)val); esp_wifi_get_mac(ESP_MAC_WIFI_STA,(uint8_t *)val);