linux icon indicating copy to clipboard operation
linux copied to clipboard

AP mode re-connection issue with IoT devices using ESP32

Open mshioji opened this issue 7 months ago • 2 comments

Describe the bug

Hello,

I am reporting a persistent issue with my Raspberry Pi's AP mode connection, with IoT devices using ESP32.

Problem Description: When an ESP32 device disconnects from the Raspberry Pi's Wi-Fi AP (e.g., by sudden power loss, which prevents deauthentication frames from being sent), the AP continues to list the ESP32 as a connected station for an extended period (around 27 - 70 seconds) according to $ iw dev ap0 station dump. If the ESP32 is powered on again during this window, it will never reconnect to the AP. The ESP32's connection attempts are completely ignored, and the AP interface needs to be manually reset with $ nmcli connection up ap0 to re-connect.

Observed Behavior on Older System (Comparison): On an older OS version, when an ESP32 disconnected without a deauthentication frame, $ iw dev ap0 station dump would initially keep showing the disconnected ESP32 for about 35 seconds, which is a similar behavior. Crucially, if the ESP32 attempted to reconnect during this period, the AP would "proactively clear" the old station entry after approximately 6 seconds (from the new connection attempt), and then successfully establish a new connection within another 5 seconds. This "proactive clearing" behavior allowed for stable and quick re-connections, demonstrating intelligent handling of clients that don't send deauthentication frames. This feature appears to be lost in newer versions.

Steps to reproduce the behaviour

  1. setup Raspberry Pi as an AP.
  2. connect IoT device using ESP32 (or something) to Raspberry Pi AP with WiFi.
  3. turn off ESP32 device (pull plug out from USB Power)
  4. power on ESP32 device again in "few" seconds.
  5. -> ESP32 Device will Never reconnect to Pi AP (forever).
  6. nmcli connection up pi_ap needed to reconnect.
  • if we wait for 90sec before 4. power on again, ESP32 device is able to connect.
  • on older version of Raspberry Pi OS, ESP32 re-connection goes smoothly.

here is the AP configurations with dummy password:

  $ sudo nmcli connection add \
  type wifi \
  ifname ap0 \
  con-name pi_ap \
  autoconnect yes \
  ssid pi_ap \
  802-11-wireless.mode ap \
  802-11-wireless.band bg \
  802-11-wireless.channel 6 \
  ipv4.method shared \
  ipv4.never-default yes \
  wifi-sec.key-mgmt wpa-psk \
  wifi-sec.pairwise ccmp \
  wifi-sec.group ccmp \
  wifi-sec.proto rsn \
  wifi-sec.psk "p@ssw0rd"

Device (s)

Raspberry Pi 4 Mod. B and Raspberry Pi 5

System

"NG" System (Newer Kernel/Driver/Firmware - observed on recent Bookworm):

OS: Debian GNU/Linux 12 (bookworm) (or Bullseye after relevant updates)
Kernel: Linux riot-b7b7 6.12.25+rpt-rpi-v8 #1 SMP PREEMPT Debian 1:6.12.25-1+rpt1 (2025-04-30) aarch64 GNU/Linux
brcmfmac Driver: srcversion: 9F4DA02FA39ED55C624CB1F
brcmfmac Firmware: version 7.45.265 (28bca26 CY) FWID 01-b677b91b (Aug 29 2023)

"OK" System (Older Kernel/Driver/Firmware):

OS: Debian GNU/Linux 11 (bullseye)
Kernel: Linux qmgr-4e43 6.1.21-v8+ #1642 SMP PREEMPT Mon Apr 3 17:24:16 BST 2023 aarch64 GNU/Linux
brcmfmac Driver: srcversion: 0EA2B0D5930C402A5A7CD6A
brcmfmac Firmware: version 7.45.241 (1a2f2fa CY) FWID 01-703fd60 (Nov 1 2021)

Logs

Log of “old” operating system. (In this case, the wlan0 interface is being used.) issue $ iw dev wlan0 station dump every one second to monitor.

  • Please note this is the OK case:
kuroneko@qmgr-4e43:~ $ iw dev wlan0 station dump
Station e0:e2:e6:0c:2f:14 (on wlan0)                                    // <-- this is the old connection kept by system.
	inactive time:	17000 ms
	rx bytes:	5169
	rx packets:	61
	tx bytes:	10789
	tx packets:	81
	tx failed:	0
	tx bitrate:	54.0 MBit/s
	rx bitrate:	6.0 MBit/s
	authorized:	yes
	authenticated:	yes
	associated:	yes
	WMM/WME:	yes
	TDLS peer:	yes
	DTIM period:	2
	beacon interval:100
	short slot time:yes
	connected time:	59 seconds
	current time:	1748672363850 ms
kuroneko@qmgr-4e43:~ $ iw dev wlan0 station dump  // <-- connection reset happened here in "OLD" system
kuroneko@qmgr-4e43:~ $ iw dev wlan0 station dump  //  but this will not happen in latest Bookworm.
kuroneko@qmgr-4e43:~ $ iw dev wlan0 station dump
kuroneko@qmgr-4e43:~ $ iw dev wlan0 station dump
kuroneko@qmgr-4e43:~ $ iw dev wlan0 station dump
Station e0:e2:e6:0c:2f:14 (on wlan0)                                 // <-- new connection established.
	inactive time:	0 ms
	rx bytes:	1264
	rx packets:	7
	tx bytes:	10766
	tx packets:	74
	tx failed:	0
	tx bitrate:	54.0 MBit/s
	rx bitrate:	6.0 MBit/s
	authorized:	yes
	authenticated:	yes
	associated:	yes
	WMM/WME:	yes
	TDLS peer:	yes
	DTIM period:	2
	beacon interval:100
	short slot time:yes
	connected time:	0 seconds
	current time:	1748672368867 ms
kuroneko@qmgr-4e43:~ $ iw dev wlan0 station dump

Additional context

Troubleshooting Steps Taken: I tried configuring the AP manually by setting ap0 to be unmanaged by NetworkManager and then directly setting up hostapd and dnsmasq for ap0 (while wlan0 remained managed by NetworkManager for STA mode). However, the result was the same.

It seems this behavior is consistent across different Raspberry Pi OS releases like upgraded-bullseye and Bookworm, once these newer components are in place.

Conclusion: These observations may probably implies this regression is caused by specific updates within the Linux kernel, the brcmfmac Wi-Fi driver, or its associated firmware? The "proactive clearing" mechanism for old station entries (which allowed new connections to override old, un-deauthenticated ones) that was present in older versions seems to be absent in the latest versions.

Any insights or assistance, especially from those familiar with this area, would be greatly appreciated. Thank you for your time and consideration.

mshioji avatar May 31 '25 10:05 mshioji

Hello,

To help with reproducing the issue, I've prepared a setup shell script. (I was unable to configure the AP to allow ESP32 connections using the GUI's "Create Wireless Hotspot" feature unfortunately.)

This script sets up the Raspberry Pi to operate an AP on a virtual interface ap0, separate from wlan0. The SSID is "RaspberryPi-AP" and the dummy-password is "p@ssw0rd".

The issue might be reproducible with any client device that stops communicating without sending a deauthentication frame (e.g., by simply pulling the power), not necessarily just ESP32.

Here is the setup script:

#!/bin/bash
set -e

###### Create virtual AP interface
echo "Create virtual AP interface ap0"
# Get current phy name and wlan0 MAC address
PHY_NAME=$(iw dev | awk '/phy#/ {print $1}')
MAC_ADDR=$(iw dev wlan0 info | awk '/addr/ {print $2}')

if [ -z "$PHY_NAME" ] || [ -z "$MAC_ADDR" ]; then
    echo "> can't get info wlan0"
    exit 1
fi

echo "> PHY_NAME: $PHY_NAME"
echo "> MAC_ADDR: $MAC_ADDR"

# If ap0 doesn't exist, create it
if iw dev | grep -q "ap0"; then
    echo "> ap0 already exists."
else
    sudo iw dev wlan0 interface add ap0 type __ap
    echo "> ap0 added."
fi

# create systemd service file
AP0_SERVICE_FILE="/etc/systemd/system/ap0.service"

cat <<EOF | sudo tee "$AP0_SERVICE_FILE" > /dev/null
[Unit]
Description=Create ap0 interface for AP mode
After=network.target network-online.target

[Service]
Type=oneshot
ExecStart=/sbin/iw dev wlan0 interface add ap0 type __ap
ExecStartPost=/sbin/ip link set ap0 address $MAC_ADDR
ExecStartPost=/bin/ip link set ap0 up
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
EOF

###### setting network manager
SSID="RaspberryPi-AP"
APPASSWORD="p@ssw0rd"
CON_NAME="pi_ap"

# Delete existing connection if it exists
if nmcli connection show "$CON_NAME" > /dev/null 2>&1; then
  echo "> '$CON_NAME' already exists, deleting..."
  sudo nmcli connection delete "$CON_NAME"
fi
  sudo nmcli connection add \
  type wifi \
  ifname ap0 \
  con-name "$CON_NAME" \
  autoconnect yes \
  ssid "$SSID" \
  802-11-wireless.mode ap \
  802-11-wireless.band bg \
  802-11-wireless.channel 6 \
  ipv4.method shared \
  ipv4.never-default yes \
  wifi-sec.key-mgmt wpa-psk \
  wifi-sec.pairwise ccmp \
  wifi-sec.group ccmp \
  wifi-sec.proto rsn \
  wifi-sec.psk "$APPASSWORD"

###### enable rules and activate AP
sudo rfkill unblock wifi
sudo systemctl daemon-reload
sudo systemctl enable ap0.service
sudo nmcli device set ap0 managed yes

# Activate the AP connection via NetworkManager for the current session
sudo nmcli connection up "$CON_NAME"

###### finish process
echo -n "process finished. "

mshioji avatar Jun 05 '25 00:06 mshioji

I attempted to test this issue on Trixie to see if it was resolved, but encountered a firmware crash issue. (#7092). During the brief period before the crash, the reconnection behavior appeared to be improved compared to Bookworm. Once #7092 is resolved, I'll try testing for this issue again.

mshioji avatar Oct 17 '25 04:10 mshioji