Skip to content

zephyr-cp: scan results lost and duplicated; two 10-deep queues drop, one silently #57

Description

@mikeysklar

Measured on hardware, board associated to an AP, build 10.3.0-alpha.4-57-gd96b766f32:

[connected] total: 61 uniq_bssid: 12

61 scan results for 12 real access points, about 5x duplication. Same SSID and RSSI repeat, for example six entries of one SSID all at -45 dBm on channel 6.

Cause

ports/zephyr-cp/common-hal/wifi/ScannedNetworks.c:83 sweeps channels one at a time, copied from the espressif port:

static uint8_t scan_pattern[] = {6, 1, 11, 3, 9, 13, 2, 4, 8, 12, 5, 7, 10, 14, 0};

Each entry issues its own NET_REQUEST_WIFI_SCAN. That works on espressif because esp_wifi_scan_start() honors the requested channel. It does not work here.

zephyr/drivers/wifi/siwx91x/siwx91x_wifi_scan.c:188 switches scan type once the radio is associated:

if (sidev->state == WIFI_STATE_COMPLETED) {
    siwx91x_configure_scan_dwell_time(SL_WIFI_SCAN_TYPE_ADV_SCAN, ...

and Silicon Labs documents that background scans ignore the channel selection (modules/hal/silabs/wiseconnect/components/protocol/wifi/inc/sl_wifi_types.h:274):

For background scans (SL_WIFI_SCAN_TYPE_ADV_SCAN): Scans the channels that were originally specified in channel_bitmap_2g4 during the first scan. The channel bitmap cannot be modified for background scans.

So while connected, every pass of the sweep re-reports the same APs. Nothing between the driver and Python filters them: wifi_scannednetworks_scan_result() puts every result straight on the msgq.

Knock-on

MAX_BUFFERED_SCAN_RESULTS is 10 (ScannedNetworks.h:17) and overflow is dropped with a Dropping scan result warning. Duplicates from a strong nearby AP can push genuine distant APs out of the results entirely, so this is not only cosmetic.

Not unique to this port

CircuitPython does not deduplicate scan results anywhere, on any port. espressif looks clean only because ESP-IDF returns a per-BSS deduplicated list. raspberrypi has the same visible symptom, reported by dhalbert in adafruit#7318, open since 2022 and labeled third-party.

MicroPython solves it for the same cyw43 chip in extmod/network_cyw43.c:159-169 by deduplicating on BSSID and keeping the strongest RSSI.

Options

  1. Deduplicate on BSSID before queueing. Fixes the symptom regardless of scan type, and generalizes to Pico W: network scanning shows a lot of duplicates adafruit/circuitpython#7318.
  2. Skip the per-channel sweep when the driver would use ADV_SCAN, since the channel restriction is ignored anyway.

These are complementary. 1 is the more useful upstream change.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions