Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions ports/espressif/common-hal/wifi/Radio.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

#include "components/esp_netif/include/esp_netif_net_stack.h"
#include "components/esp_wifi/include/esp_wifi.h"
#include "soc/soc_caps.h"
#include "components/lwip/include/apps/ping/ping_sock.h"
#include "lwip/sockets.h"

Expand Down Expand Up @@ -94,6 +95,11 @@ void common_hal_wifi_radio_set_enabled(wifi_radio_obj_t *self, bool enabled) {
}
if (!self->started && enabled) {
ESP_ERROR_CHECK(esp_wifi_start());
#if defined(SOC_WIFI_SUPPORT_5G) && SOC_WIFI_SUPPORT_5G
// Dual-band radios default to 2.4 GHz only. Enable both bands so that
// 5 GHz networks are visible to scans and can be connected to.
ESP_ERROR_CHECK(esp_wifi_set_band_mode(WIFI_BAND_MODE_AUTO));
#endif
self->started = true;
common_hal_wifi_radio_set_tx_power(self, CIRCUITPY_WIFI_DEFAULT_TX_POWER);
return;
Expand Down
44 changes: 27 additions & 17 deletions ports/espressif/common-hal/wifi/ScannedNetworks.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "shared-bindings/wifi/ScannedNetworks.h"

#include "components/esp_wifi/include/esp_wifi.h"
#include "soc/soc_caps.h"

static void wifi_scannednetworks_done(wifi_scannednetworks_obj_t *self) {
self->done = true;
Expand Down Expand Up @@ -111,29 +112,38 @@ mp_obj_t common_hal_wifi_scannednetworks_next(wifi_scannednetworks_obj_t *self)
}

// We don't do a linear scan so that we look at a variety of spectrum up front.
#if defined(SOC_WIFI_SUPPORT_5G) && SOC_WIFI_SUPPORT_5G
// 2.4 GHz first, then the 5 GHz U-NII bands. DFS channels are omitted:
// they require radar detection before transmitting.
static uint8_t scan_pattern[] = {6, 1, 11, 3, 9, 13, 2, 4, 8, 12, 5, 7, 10, 14,
36, 40, 44, 48, 149, 153, 157, 161, 165, 0};
#else
static uint8_t scan_pattern[] = {6, 1, 11, 3, 9, 13, 2, 4, 8, 12, 5, 7, 10, 14, 0};
#endif

void wifi_scannednetworks_scan_next_channel(wifi_scannednetworks_obj_t *self) {
// There is no channel 0, so use that as a flag to indicate we've run out of channels to scan.
uint8_t next_channel = 0;
while (self->current_channel_index < sizeof(scan_pattern)) {
next_channel = scan_pattern[self->current_channel_index];
self->current_channel_index++;
// Scan only channels that are in the specified range.
if (self->start_channel <= next_channel && next_channel <= self->end_channel) {
break;
while (true) {
// There is no channel 0, so use that as a flag to indicate we've run out of channels to scan.
uint8_t next_channel = 0;
while (self->current_channel_index < sizeof(scan_pattern)) {
next_channel = scan_pattern[self->current_channel_index];
self->current_channel_index++;
// Scan only channels that are in the specified range.
if (self->start_channel <= next_channel && next_channel <= self->end_channel) {
break;
}
}
}
wifi_scan_config_t config = { 0 };
config.channel = next_channel;
if (next_channel == 0) {
wifi_scannednetworks_done(self);
} else {
esp_err_t result = esp_wifi_scan_start(&config, false);
if (result != ESP_OK) {
if (next_channel == 0) {
wifi_scannednetworks_done(self);
} else {
return;
}
wifi_scan_config_t config = { 0 };
config.channel = next_channel;
// The radio rejects channels outside the band it is set to. Skip those
// rather than ending the scan, so the rest of the pattern still runs.
if (esp_wifi_scan_start(&config, false) == ESP_OK) {
self->channel_scan_in_progress = true;
return;
}
}
}
Expand Down
13 changes: 9 additions & 4 deletions shared-bindings/wifi/Radio.c
Original file line number Diff line number Diff line change
Expand Up @@ -254,10 +254,13 @@ MP_PROPERTY_GETTER(wifi_radio_mac_address_ap_obj,
#endif

//| def start_scanning_networks(
//| self, *, start_channel: int = 1, stop_channel: int = 11
//| self, *, start_channel: int = 1, stop_channel: int = 165
//| ) -> Iterable[Network]:
//| """Scans for available wifi networks over the given channel range. Make sure the channels are allowed in your country.
//|
//| On dual-band radios, 5 GHz channels (36 and above) may also be given.
//| Channel numbers that the radio does not support are skipped.
//|
//| .. note::
//|
//| In the raspberrypi port (RP2040 CYW43), ``start_channel`` and ``stop_channel`` are ignored.
Expand All @@ -268,17 +271,19 @@ static mp_obj_t wifi_radio_start_scanning_networks(size_t n_args, const mp_obj_t
enum { ARG_start_channel, ARG_stop_channel };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_start_channel, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} },
{ MP_QSTR_stop_channel, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 11} },
{ MP_QSTR_stop_channel, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 165} },
};

wifi_radio_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);

// 165 is the highest 5 GHz channel number. Channels the radio doesn't
// support are skipped while scanning rather than rejected here.
uint8_t start_channel =
(uint8_t)mp_arg_validate_int_range(args[ARG_start_channel].u_int, 1, 14, MP_QSTR_start_channel);
(uint8_t)mp_arg_validate_int_range(args[ARG_start_channel].u_int, 1, 165, MP_QSTR_start_channel);
uint8_t stop_channel =
(uint8_t)mp_arg_validate_int_range(args[ARG_stop_channel].u_int, 1, 14, MP_QSTR_stop_channel);
(uint8_t)mp_arg_validate_int_range(args[ARG_stop_channel].u_int, 1, 165, MP_QSTR_stop_channel);
// Swap if in reverse order, without complaining.
if (start_channel > stop_channel) {
uint8_t temp = stop_channel;
Expand Down
Loading