Вопрос или проблема
Я экспериментировал с 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, поэтому работу необходимо вести в нескольких направлениях: изменять настройки таймаутов, проводить мониторинг состояния и анализировать логи для выявления повторяющихся закономерностей.
Если у вас появятся дополнительные вопросы или потребуются конкретные примеры конфигураций, не стесняйтесь задавать их!