Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update esp-idf; allow start/stop channels in wifi scanning #7023

Merged
merged 2 commits into from
Oct 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 6 additions & 3 deletions ports/espressif/common-hal/wifi/Radio.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ void common_hal_wifi_radio_set_mac_address_ap(wifi_radio_obj_t *self, const uint
esp_wifi_set_mac(ESP_IF_WIFI_AP, mac);
}

mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self) {
mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self, uint8_t start_channel, uint8_t stop_channel) {
if (self->current_scan != NULL) {
mp_raise_RuntimeError(translate("Already scanning for wifi networks"));
}
Expand All @@ -177,9 +177,12 @@ mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self) {
wifi_scannednetworks_obj_t *scan = m_new_obj(wifi_scannednetworks_obj_t);
scan->base.type = &wifi_scannednetworks_type;
self->current_scan = scan;
scan->start_channel = 1;
scan->end_channel = 11;
scan->current_channel_index = 0;
scan->start_channel = start_channel;
scan->end_channel = stop_channel;
scan->radio_event_group = self->event_group_handle;
scan->done = false;
scan->channel_scan_in_progress = false;
wifi_scannednetworks_scan_next_channel(scan);
return scan;
}
Expand Down
33 changes: 21 additions & 12 deletions ports/espressif/common-hal/wifi/ScannedNetworks.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ mp_obj_t common_hal_wifi_scannednetworks_next(wifi_scannednetworks_obj_t *self)
return mp_const_none;
}
// If we are scanning, wait and then load them.
if (self->scanning) {
if (self->channel_scan_in_progress) {
// We may have to scan more than one channel to get a result.
while (!self->done) {
if (!wifi_scannednetworks_wait_for_scan(self)) {
Expand All @@ -81,7 +81,7 @@ mp_obj_t common_hal_wifi_scannednetworks_next(wifi_scannednetworks_obj_t *self)
}

esp_wifi_scan_get_ap_num(&self->total_results);
self->scanning = false;
self->channel_scan_in_progress = false;
if (self->total_results > 0) {
break;
}
Expand Down Expand Up @@ -112,7 +112,7 @@ mp_obj_t common_hal_wifi_scannednetworks_next(wifi_scannednetworks_obj_t *self)
}
}
esp_wifi_scan_get_ap_records(&self->total_results, self->results);
self->scanning = false;
self->channel_scan_in_progress = false;
}

wifi_network_obj_t *entry = m_new_obj(wifi_network_obj_t);
Expand All @@ -132,40 +132,49 @@ 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.
static uint8_t scan_pattern[] = {6, 1, 11, 3, 9, 13, 2, 4, 8, 12, 5, 7, 10, 14};
static uint8_t scan_pattern[] = {6, 1, 11, 3, 9, 13, 2, 4, 8, 12, 5, 7, 10, 14, 0};

void wifi_scannednetworks_scan_next_channel(wifi_scannednetworks_obj_t *self) {
uint8_t next_channel = sizeof(scan_pattern);
// 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 == sizeof(scan_pattern)) {
if (next_channel == 0) {
wifi_scannednetworks_done(self);
} else {
esp_err_t result = esp_wifi_scan_start(&config, false);
if (result != ESP_OK) {
wifi_scannednetworks_done(self);
} else {
self->scanning = true;
self->channel_scan_in_progress = true;
}
}
}

void wifi_scannednetworks_deinit(wifi_scannednetworks_obj_t *self) {
// if a scan is active, make sure and clean up the idf's buffer of results.
if (self->scanning) {
if (self->channel_scan_in_progress) {
esp_wifi_scan_stop();
if (wifi_scannednetworks_wait_for_scan(self)) {
// Ignore the number of records since we're throwing them away.
uint16_t number = 0;
esp_wifi_scan_get_ap_records(&number, NULL);
self->scanning = false;
// Discard the scanned records, one at a time, to avoid memory leaks.
uint16_t number;
do {
number = 1;
wifi_ap_record_t record;
esp_wifi_scan_get_ap_records(&number, &record);
} while (number > 0);
// TODO: available in ESP-IDF v5.0; do instead of the above.
// Discard scan results.
// esp_wifi_clear_ap_list();
self->channel_scan_in_progress = false;
}
}
wifi_scannednetworks_done(self);
Expand Down
2 changes: 1 addition & 1 deletion ports/espressif/common-hal/wifi/ScannedNetworks.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ typedef struct {
uint8_t end_channel; // Inclusive

bool done;
bool scanning;
bool channel_scan_in_progress;
} wifi_scannednetworks_obj_t;

void wifi_scannednetworks_scan_next_channel(wifi_scannednetworks_obj_t *self);
Expand Down
2 changes: 1 addition & 1 deletion ports/espressif/common-hal/wifi/__init__.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ void common_hal_wifi_init(bool user_initiated) {
// Even though we just called esp_netif_create_default_wifi_sta,
// station mode isn't actually ready for use until esp_wifi_set_mode()
// is called and the configuration is loaded via esp_wifi_set_config().
// Set both convienence flags to false so it's not forgotten.
// Set both convenience flags to false so it's not forgotten.
self->sta_mode = 0;
self->ap_mode = 0;

Expand Down
2 changes: 1 addition & 1 deletion ports/espressif/esp-idf
Submodule esp-idf updated 724 files
3 changes: 2 additions & 1 deletion ports/raspberrypi/common-hal/wifi/Radio.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,8 @@ void common_hal_wifi_radio_set_mac_address_ap(wifi_radio_obj_t *self, const uint
ro_attribute(MP_QSTR_mac_address_ap);
}

mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self) {
mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self, uint8_t start_channel, uint8_t stop_channel) {
// channel bounds are ignored; not implemented in driver
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe raise not implemented error when provided channel range doesn't match the default range

Copy link
Collaborator Author

@dhalbert dhalbert Oct 8, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't actually know which channels are scanned by default. I looked for documentation, but maybe I am looking in the wrong place. These config params are set to zero:

    int32_t channel_num;
    uint16_t channel_list[1];

@jepler Do you know, or know where to look?

Maybe can figure this out later and add support.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I can tell there's no way to set the channels to scan in picow. some internal default is always used. It may be controlled by the country setting, which we never change.

if (self->current_scan) {
mp_raise_RuntimeError(translate("Already scanning for wifi networks"));
}
Expand Down
34 changes: 29 additions & 5 deletions shared-bindings/wifi/Radio.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,14 +216,38 @@ MP_PROPERTY_GETSET(wifi_radio_mac_address_ap_obj,
//| def start_scanning_networks(
//| self, *, start_channel: int = 1, stop_channel: int = 11
//| ) -> Iterable[Network]:
//| """Scans for available wifi networks over the given channel range. Make sure the channels are allowed in your country."""
//| """Scans for available wifi networks over the given channel range. Make sure the channels are allowed in your country.
//|
//| .. note::
//|
//| In the raspberrypi port (RP2040 CYW43), ``start_channel`` and ``stop_channel`` are ignored.
//| """
//| ...
STATIC mp_obj_t wifi_radio_start_scanning_networks(mp_obj_t self_in) {
wifi_radio_obj_t *self = MP_OBJ_TO_PTR(self_in);
STATIC mp_obj_t wifi_radio_start_scanning_networks(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
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} },
};

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);

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 stop_channel =
(uint8_t)mp_arg_validate_int_range(args[ARG_stop_channel].u_int, 1, 14, MP_QSTR_stop_channel);
// Swap if in reverse order, without complaining.
if (start_channel > stop_channel) {
uint8_t temp = stop_channel;
stop_channel = start_channel;
start_channel = temp;
}

return common_hal_wifi_radio_start_scanning_networks(self);
return common_hal_wifi_radio_start_scanning_networks(self, start_channel, stop_channel);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_start_scanning_networks_obj, wifi_radio_start_scanning_networks);
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wifi_radio_start_scanning_networks_obj, 1, wifi_radio_start_scanning_networks);

//| def stop_scanning_networks(self) -> None:
//| """Stop scanning for Wifi networks and free any resources used to do it."""
Expand Down
2 changes: 1 addition & 1 deletion shared-bindings/wifi/Radio.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ extern void common_hal_wifi_radio_set_mac_address_ap(wifi_radio_obj_t *self, con
extern mp_float_t common_hal_wifi_radio_get_tx_power(wifi_radio_obj_t *self);
extern void common_hal_wifi_radio_set_tx_power(wifi_radio_obj_t *self, const mp_float_t power);

extern mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self);
extern mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self, uint8_t start_channel, uint8_t stop_channel);
extern void common_hal_wifi_radio_stop_scanning_networks(wifi_radio_obj_t *self);

extern void common_hal_wifi_radio_start_station(wifi_radio_obj_t *self);
Expand Down