Сбой повторного подключения по Wifi от клиента ESP32 к RaspberryPi, настроенному в качестве точки доступа.

Вопрос или проблема

Я экспериментировал с ESP32, используя MicroPython, и пытался подключить его по WiFi к RaspberryPi, настроенному в качестве точки доступа (AP).

RPi настроен как точка доступа с помощью следующих команд:

$ sudo nmcli d wifi hotspot ifname wlan0 ssid raspi_ap password raspi_ap_pwd
$ sudo nmcli connection modify Hotspot ipv4.addresses 192.168.2.1/24
$ sudo nmcli connection modify Hotspot connection.autoconnect yes
$ sudo nmcli connection up Hotspot

Код на ESP использует эту функцию: https://pastebin.com/HQQkfN7F

Соединение работает хорошо, за исключением того, что если я перезагружу плату, нажав на кнопку сброса на плате (которая должна сбросить оба ядра ESP), следующая попытка подключения завершается неудачей с кодом STAT_WRONG_PASSWORD.

Я заметил, что следующее соединение после сброса ESP работает, если я жду, пока станция будет отключена на стороне RaspberryPi. (Я отслеживаю это с помощью iw dev wlan0 station dump).

Сначала я подумал о проблеме на стороне ESP, либо на уровне MicroPython, либо на уровне ESP-IDF, но после попытки с другой точкой доступа (моим роутером от провайдера) я не смог воспроизвести эту проблему, и следующее соединение сразу после сброса платы работает как ожидается.

Поэтому проблема, похоже, на стороне RPi.

Я пытался отслеживать с помощью Wireshark, что происходит во время этой попытки подключения после сброса, и не вижу никаких пакетов, в то время как я вижу запросы EAPOL/DHCP/ARP/MDNS, которые отправлялись во время предыдущего успешного соединения.

С стороны RPi я попытался установить уровень логирования NetworkManager и wpa_supplicant на уровень отладки и увидеть, что происходит во время этой попытки подключения после сброса, и ситуация та же, ничего не логируется во время попыток подключения, которые завершаются с кодом STAT_WRONG_PASSWORD. Однако я вижу, что во время этих попыток inactive time станции сбрасывается до 0 мс в результате iw dev wlan0 station dump.

Как только ESP перестает пытаться подключиться, я вижу, что inactive time станции (по команде iw выше) достигает примерно 60000 мс, прежде чем станция будет отключена и удалена оттуда. После этого, если я снова попытаюсь подключить ESP, это сработает.

Я публикую логи от wpa_supplicant здесь: https://pastebin.com/nS8NVV7d, так как это довольно длинно.

Что может объяснить такое поведение? Это проблема с драйвером nl80211?

Любые советы, которые помогут мне глубже расследовать эту проблему, приветствуются.

Так как, похоже, существует тайм-аут для отключения станции от NetworkManager/wpa_supplicant, есть ли способ уменьшить это время? Похоже, что каждые 10 секунд ESP отправляет сообщение в AP, чтобы поддерживать соединение, так что я полагаю, что могу безопасно уменьшить это время до ~15 секунд.

Ответ или решение

Конечно! Давайте разберемся в проблеме с подключением вашего клиента ESP32 к Raspberry Pi, настроенному в роли точки доступа (AP). Основное внимание будет уделено некоторым возможным причинам, а также предложением решений.

1. Анализ проблемы

Мы видим, что ESP32 корректно подключается к Raspberry Pi, но возникает проблема STAT_WRONG_PASSWORD после сброса платы. Это указывает на проблему с повторным подключением, связанную с состоянием AP или протоколом управления соединениями.

Почему это происходит:

  • Деинициализация: При сбросе ESP32 происходит деинициализация модуля WiFi. Если Raspberry Pi не успевает удалить старое соединение до того, как ESP32 пытается переподключиться, это может приводить к ошибке аутентификации.
  • Состояние бельд: Raspberry Pi может продолжать считать, что устройство ESP32 подключено, даже после его сброса, в течение некоторого времени, что может быть связано с тем, что настройки временных меток или протоколов управления соединениями, таких как EAPOL, не обновляются должным образом.

2. Проверка конфигурации AP

Убедитесь, что настройки вашего Raspberry Pi корректны. Обратите внимание на следующее:

  • Изменение таймаутов: Вы упомянули возможность снижения времени деассоциации. В большинстве случаев это можно настроить через параметры wpa_supplicant.conf или параметры NM.

    Например, вы можете добавить следующие строки в конфигурацию wpa_supplicant:

    ap_scan=1
    max_inactivity=20

    Это позволит вам упростить время ожидания деассоциации.

  • Настройки NetworkManager: Проверьте, установлен ли более короткий таймер для отключения. Вы можете использовать команды для изменения конфигурации таймеров NetworkManager.

3. Поведение EAPOL и DHCP

Логично, что при сбросе ESP32 соединение в AP нужно переинициализировать. Проверьте следующий момент:

  • Убедитесь, что EAPOL (Extensible Authentication Protocol over LAN) работает корректно. Периодический запрос на аутентификацию может не отправляться должным образом, если AP «думает», что устройство по-прежнему активно.

4. Выявление проблемы с помощью логов

Вы уже используете Wireshark и логи wpa_supplicant для мониторинга попыток подключения. Обратите внимание на:

  • Запись всех пакетов: Убедитесь, что вы захватываете не только аутентификацию, но и DHCP запросы, чтобы проследить весь цикл подключения.
  • Мониторинг ошибок: Обратите внимание на любые другие сообщения об ошибках или предостережениях.

5. Альтернативное решение

Если проблема продолжит возникать, возможно, стоит рассмотреть использование библиотеки ESP-IDF, которая более оптимизирована для таких случаев. Это может потребовать изменений в коде ESP32, но может улучшить устойчивость соединения.

Заключение

Проблема, с которой вы столкнулись, скорее всего, связана с управлением состояниями соединения на уровне вашего Raspberry Pi, поэтому работу необходимо вести в нескольких направлениях: изменять настройки таймаутов, проводить мониторинг состояния и анализировать логи для выявления повторяющихся закономерностей.

Если у вас появятся дополнительные вопросы или потребуются конкретные примеры конфигураций, не стесняйтесь задавать их!

Оцените материал
Добавить комментарий

Капча загружается...