检查来自 Python 应用程序的 wpa_supplicant 输出

Checking wpa_supplicant output from Python app

我在 Raspberry Pi 上有一个 Python/Flask 网络应用程序,它调用以下 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 在失败之前会挂起 forever

我想做的是在继续 dhclient 之前检测凭据是否正确。我知道如果 creds 错误,我可以检查 wpa_supplicant 命令的输出是否有 4 次握手失败,但是当我通过以下方式从我的 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... 行的输出的

None。如果我检测到握手失败,我只想立即结束,但我无法捕获 Python.

中的输出

它没有解决您的 Python 问题,但是(假设您有能力修改 BASH 脚本)您可以在 BASH 脚本中放置一个循环以检查 iw wlan0 link 的输出并等待它 return 成功消息或达到超时计数器。它将 return "Not Connected" 直到建立连接。

调用 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

John Bullard 的回答非常干净和可靠,但由于我对它的评论,我很难让它始终如一地工作:

There is a brief period where iw wlan0 link says it is connected even if invalid credentials are entered in wpa_supplicant.conf. I'm assuming it connects, then verifies creds, and if they're wrong, disconnects. So this script doesn't actually work, at least not every time.

在那个答案的帮助下,我最终做的是使用 wpa_supplicant 的 -f 标志并将 wpa_supplicant 的输出写入文件。然后 while 循环会查询连接状态,在这种情况下它将调用 dhclient。如果连接不上,要么超时,要么导致4次握手失败(如果是后者,脚本会提前结束)。

#!/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