几个月以来,我们在我的设备上安装了 WiFi 模块,您可以从用户界面扫描可用的 WiFi 网络并连接到其中之一。 如果连接成功,我会存储有关该连接的数据,以便在以后的设备启动时自动重新连接。
我的 UI 应用程序是在 LUA 中实现的,并且从代码中我能够运行 linux 命令(我在 Buildroot 环境中工作),由于各种原因我没有可用的 connman,因此我使用 wpa_supplicant 管理网络连接。
目前来说,我的解决方案非常糟糕,它可以工作,但它肯定不能称为好工作。
我会尝试快速总结一下: 每 10 秒我都会使用以下命令更新可用网络列表
iwlist wlan0 scan
然后我更新可用 wifi 列表及其特征。 同时,我还有另一个例程(Lua),每 5 秒检查一次连接状态,如果连接建立正常,否则它会尝试与存储的网络之一建立连接。 为了建立连接,我使用 wpa_supplicant,问题是 wpa_supplicant 不是瞬时的,我需要一些时间范围(变量)来了解连接是否已建立。
管理这部分的代码部分如下:
if(counter_500ms % 10 == 0 )then
local file = io.open("/tmp/connesso","r")
if(not(file)) then
Connesso_A_Internet = false
else
local lettura = tonumber(file:read("*a"))
file:close()
if(lettura == 1)then
print("connesso")
Connesso_A_Internet = true
Tempo_Last_Check_Connection = gre.mstime() / 1000
else
if(Connesso_A_Internet and math.abs(Tempo_Last_Check_Connection - gre.mstime() / 1000) >= 20)then
Connesso_A_Internet = false
First_Connection_Wifi(mapargs)
elseif(Connesso_A_Internet and math.abs(Tempo_Last_Check_Connection - gre.mstime() / 1000) < 10)then
Connesso_A_Internet = true
else
Connesso_A_Internet = false
if( math.abs(Tempo_Last_Check_Connection - gre.mstime() / 1000) >= 20)then
First_Connection_Wifi(mapargs)
end
end
end
end
end
-----
function First_Connection_Wifi(mapargs)
-- enter only if internet connection is not present
if(not Connesso_A_Internet)then
local index = 0
local f,p
local nome_temp = nil
-- parse the structure that contains information about available internet connection
for i=1,#struttura_reti do
local stringa_da_cercare = struttura_reti[i].name
-- extract the ssid of available connections
stringa_da_cercare = string.gsub(stringa_da_cercare," ","\\ ")
-- check if this ssid has been used in the past
local file = io.open("/mnt/tables/wpa_supplicant_"..stringa_da_cercare..".conf","r")
if(not(file)) then
-- this ssid has never been used in the past
-- it seems that in this case a [sh] process is addes to ps output
print("non c'è file", struttura_reti[i].name)
else
-- this ssid has never been used in the past since I have a .conf file with connection information
print("c'è il file ->",struttura_reti[i].name)
nome_temp = struttura_reti[i].name
file:close()
break
end
end
-- if I found a ssid in memory I try to connect to this network
-- since the connection is established, the [sh] problem is solved
if(nome_temp ~= nil)then
os.execute("killall wpa_supplicant &")
gre.timer_set_timeout(function()
Tempo_Last_Check_Connection = gre.mstime() / 1000
Rete_In_Connessione = nome_temp
local stringa_da_cercare = nome_temp
stringa_da_cercare = string.gsub(stringa_da_cercare," ","\\ ")
os.execute("wpa_supplicant -B -D nl80211 -i wlan0 -c /mnt/tables/wpa_supplicant_"..stringa_da_cercare..".conf &")
end,500)
end
end
end
要了解连接是否已建立,我运行以下脚本:
#!/bin/sh
FirstIP="8.8.8.8" #(Google public DNS)
SecondIP="8.8.4.4" #(OpenDNS public DNS)
IDX="208"
DomoIP="192.168.1.103"
DomoPort="8080"
pingo="ping -c 5 -w 1 -q "$FirstIP"";
if $pingo | grep -E "min/avg/max" > /tmp/OutputPing;
then
echo "1" > /tmp/connesso
else
#echo "--> No response from first IP ("$FirstIP"), now trying second one ("$SecondIP")"
pingo="ping -c 5 -w 1 -q "$SecondIP"";
if $pingo | grep -E "min/avg/max" > /tmp/OutputPing;
then
echo "1" > /tmp/connesso
else
echo "0" > /tmp/connesso
fi
fi
通过检查 /tmp/connection 的值,我可以确定连接是否已建立。 现在,既然这个解决方案有效,但看起来很愚蠢,我怎样才能更智能地使用 wpa_supplicant 呢?
最好的方法是不要一直重新启动
wpa_supplicant
,而是使用wpa_cli
动态重新配置它。
wpa_cli
连接到 wpa_supplicant
侦听的套接字 - 您还可以直接从 Lua 代码连接到此套接字,而不是使用 wpa_cli
。这给了你更多的灵活性。
为了能够使用
wpa_cli
或套接字,您需要在构建过程中启用它。为此,请使用 Buildroot 选项 BR2_PACKAGE_WPA_SUPPLICANT_CLI
(它会自动启用 BR2_PACKAGE_WPA_SUPPLICANT_CTRL_IFACE
,这是您需要在套接字上侦听的内容)。