Проверка вывода wpa_supplicant из приложения Python

У меня есть веб-приложение Python/Flask на Raspberry Pi, которое вызывает следующий скрипт bash (connect_to_wifi) для подключения к WiFi:

sudo killall wpa_supplicant
sudo wpa_supplicant -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf
sudo dhclient wlan0

Как правило, пользователь вводит свои учетные данные WiFi, которые сохраняются в wpa_supplicant.conf, а затем этот скрипт запускается. Это прекрасно работает... однако, если они неправильно набирают свои учетные данные, dhclient зависает навсегда, прежде чем терпит неудачу.

То, что я хочу сделать, это определить правильность учетных данных, прежде чем продолжить работу с dhclient. Я знаю, что я могу проверить вывод wpa_supplicant команда для сбоя 4-Way Handshake, если кредиты неверны, но когда я вызываю этот скрипт из моего приложения Python через:

p = Popen(['connect_to_wifi'], stdout=PIPE, bufsize=1)
with p.stdout:
    for line in iter(p.stdout.readline, b''):
        print line,
p.wait()

Ни один из вывода из sudo wpa_supplicant -i... линия захватывается. Все, что я хочу сделать, это немедленно прекратить, если я обнаружу сбой рукопожатия, но у меня возникли проблемы с захватом вывода в Python.

2 ответа

Решение

Ответ Джона Булларда был действительно чистым и твердым, но у меня были проблемы с его последовательной работой из-за комментария, который я сделал к нему:

Существует краткий период, когда ссылка iw wlan0 сообщает, что она подключена, даже если в wpa_supplicant.conf введены неверные учетные данные. Я предполагаю, что он подключается, затем проверяет кредиты, а если они ошибаются, отключается. Так что этот скрипт на самом деле не работает, по крайней мере, не каждый раз.

С помощью этого ответа я закончил тем, что использовал флаг -f для wpa_supplicant и запись вывода wpa_supplicant в файл. Затем цикл while ищет состояние подключения, и в этом случае он вызывает dhclient, Если он не подключится, он либо прервется по тайм-ауту, либо приведет к сбою четырехстороннего рукопожатия (если последнее, сценарий завершится раньше).

#!/bin/bash

sudo ip addr flush dev wlan0
sudo killall wpa_supplicant
sudo truncate -s 0 wifi_connection_status.txt
sudo wpa_supplicant -B -i wlan0 -f wifi_connection_status.txt -c /etc/wpa_supplicant/wpa_supplicant.conf

declare -i i=0
declare -i timeout=15
while [ $i -le $timeout ]; do
    if grep -iq 'CTRL-EVENT-CONNECTED' wifi_connection_status.txt; then
        sudo dhclient wlan0
        exit 2
    elif grep -iq '4-Way Handshake failed' wifi_connection_status.txt; then
        exit 2
    fi

    (( i++ ))
    sleep 1
done

Это не решает вашу проблему с Python, но (при условии, что у вас есть возможность изменить скрипт BASH), вы можете поместить цикл в скрипт BASH, чтобы проверить вывод iw wlan0 link и дождитесь, пока он вернет сообщение об успешном завершении или достигнут тайм-аут. Он вернет "Не подключен", пока не будет установлено соединение.

Сделайте это непосредственно перед вызовом dhclient, и вы должны быть совершенно уверены в действительном соединении для запуска.

Что-то вроде:

sudo killall wpa_supplicant
sudo wpa_supplicant -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf

declare -i waitcount=0;
while sudo iw wlan0 link | grep -iq "Not connected"; do
    ((waitcount+=1))
    if (( waitcount > 30 ))
    then
       echo;
       echo "Timeout while waiting for successful association and authentication."
       exit 2;
    fi
    sleep 1s;
    echo -n ".";
done

sudo dhclient wlan0
Другие вопросы по тегам