背景:
公司用的產品主板支持wifi接口,為了加強產品的功能,做wifi的底層支持。
有關知識點:淺談 Linux 內核無線子系統
概覽
主要的流程如下:
內核配置 + 有關驅動的移植 + 軟件的移植 + 軟件的配置
內核配置
# WIFI驅動
Networking support
<*> RF switch subsystem support --->
[*] Power off on suspend (NEW)
<*> Generic rfkill regulator driver
(防止使用wpa_supplicant會出現rfkill: Cannot open RFKILL control device錯誤。)
-*- Wireless --->
<*> cfg80211 - wireless configuration API
[*] nl80211 testmode command
[*] enable powersave by default
[*] cfg80211 wireless extensions compatibility
<*> Generic IEEE 802.11 Networking Stack (mac80211)
# WIFI作為AP熱點的額外配置
Device Drivers --->
[*] Network device support --->
[*] Wireless LAN --->
<*> IEEE 802.11 for Host AP (Prism2/2.5/3 and WEP/TKIP/CCMP)
[*] Support downloading firmware images with Host AP driver
[*] Support for non-volatile firmware download
wpa軟件移植
根據有關資料,移植wifi有關驅動各工具如下:
軟件包 | 說明 |
---|---|
WirelessTools | 只支持WEP認證方式 |
wpa_supplicant | 支持WPA認證方式 |
hostapd | hostapd能夠使得無線網卡切換為master模式,模擬AP(通常可以認為是路由器)功能軟AP(Soft AP) |
dhcpcd | dhcpcd是DHCP client的實現,可以作為后台守護進程運行。 |
一個腳本編譯 wpa_supplicant:
##
# Copyright By Schips, All Rights Reserved
# https://gitee.com/schips/
# File Name: make.sh
# Created : Tue 10 Dec 2019 05:42:56 PM CST
#!/bin/sh
BUILD_HOST=arm-linux
ARM_GCC=${BUILD_HOST}-gcc
BASE=`pwd`
OUTPUT_PATH=${BASE}/install
OPENSSL=openssl-1.0.2t
WPA_SUPPLICANT=wpa_supplicant-0.7.3
make_dirs() {
cd ${BASE}
mkdir compressed install source -p
}
tget () { #try wget
filename=`basename $1`
echo "Downloading [${filename}]..."
if [ ! -f ${filename} ];then
wget $1
fi
echo "[OK] Downloaded [${filename}] "
}
download_package () {
cd ${BASE}/compressed
#下載包
tget https://www.openssl.org/source/${OPENSSL}.tar.gz
tget http://w1.fi/releases/${WPA_SUPPLICANT}.tar.gz
}
tar_package () {
cd ${BASE}/compressed
ls * > /tmp/list.txt
for TAR in `cat /tmp/list.txt`
do
tar -xf $TAR -C ../source
done
rm -rf /tmp/list.txt
}
pre_make_ssl () {
cd ${BASE}/source/${OPENSSL}
startLine=`sed -n '/install_html_docs\:/=' Makefile | awk -F\b '{ print $1 }'`
echo $startLine
# 為了避免 多行結果
for startline in $startLine
do
lineAfter=99
endLine=`expr $startline + 999`
sed -i $startline','$endLine'd' Makefile
echo "install_html_docs:" >> Makefile
echo "\t@echo skip by Schips" >> Makefile
echo "install_docs:" >> Makefile
echo "\t@echo skip by Schips" >> Makefile
echo "# DO NOT DELETE THIS LINE -- make depend depends on it." >> Makefile
break
done
}
make_openssl () {
cd ${BASE}/source/${OPENSSL}
echo "SSL ABOUT"
./Configure --prefix=${OUTPUT_PATH}/${OPENSSL} os/compiler:${ARM_GCC}
pre_make_ssl
make && make install
}
make_wpa () {
cd ${BASE}/source/wpa*/wpa*
cp defconfig .config
echo "CC=${ARM_GCC} -L${OUTPUT_PATH}/${OPENSSL}/lib" >> .config
echo "CFLAGS += -I${OUTPUT_PATH}/${OPENSSL}/include" >> .config
echo "LIBS += -L${OUTPUT_PATH}/${OPENSSL}/lib" >> .config
make && make install DESTDIR=${BASE}/install/wpa_supplicant/
cp ${BASE}/source/wpa*/wpa*/examples/wpa-psk-tkip.conf ${BASE}/install/wpa_supplicant/wpa.conf
# 在ctrl_interface 當前行下插入 update_config=1
sed -i '/ctrl_interface/aupdate_config=1' ${BASE}/install/wpa_supplicant/wpa.conf
}
make_dirs
download_package
tar_package
make_openssl
make_wpa
生成結果的目錄結構如下:
$ tree install/wpa_supplicant
install/wpa_supplicant
├── usr
│ └── local
│ └── sbin
│ ├── wpa_cli
│ ├── wpa_passphrase
│ └── wpa_supplicant
└── wpa.conf
將install中wpa_supplicant/usr/local/sbin下的可執行程序拷貝到板子上
拷貝install中的wpa_supplicant/wpa.conf 一並拷出。
wpa軟件配置
運行wifi服務:
nohup wpa_supplicant -D nl80211 -i wlan0 -c $CONFIG > log &
-c 用於指定配置
使用wpa_supplicant工具主要有2種途徑:
1.基於配置文件的使用
在運行 wpa_supplicant 時指定
-c 配置文件名
這種使用方法一般只針對連接知道ssid與psk的網絡連接
2.wpa_cli 交互式控制
wpa_cli 是wpa_supplicant 的交互客戶端,可完成
通過配置文件
方法做不到的復雜操作。
注意,wpa_cli 需要在 wpa_supplicant 已經執行的情況下才有效(最好是是使用nohup .. & > log
這樣的方式運行)
- 掃描網絡並獲取結果:
# 掃描網絡
wpa_cli -i wlan0 scan
# 獲取當前結果
wpa_cli -i wlan0 scan_result
- 添加網絡連接:
NID=`wpa_cli -i wlan0 add_network`
SSID=test_wifi_name
wpa_cli -i wlan0 set_network $NID ssid '$SSID'
# 無密碼時的連接
wpa_cli -i wlan0 set_network $NID key_mgmt NONE
# 有密碼時的連接
wpa_cli -i wlan0 set_network $NID psk '$PASSWD"'
# 設置網絡屬性(默認即可)
wpa_cli -i wlan0 set_network $NID priority 2
wpa_cli -i wlan0 set_network $NID scan_ssid 1
# 啟動網絡
wpa_cli -i wlan0 enable_network $NID
wpa_cli -i wlan0 select_network $NID
-
獲取當前網絡狀態
wpa_cli -i wlan0 status
-
斷開網絡連接
wpa_cli -i wlan0 disable_network $NID
wpa_cli -i wlan0 remove_network $NID
- 保存網絡配置到當前使用的配置文件中(一般用於未連接狀態時)
wpa_cli -i wlan0 save_config
一般,本人會使用交互式的命令進行網絡掃描,將結果過濾到文件中再根據前端調用發過來的SSID與PSK,生成一份臨時的配置文件以后
最后重啟 wpa_supplicant 時,指定好 臨時的配置文件,再獲取> 當前網絡的狀態,以實現wifi的后續使用(分配IP)
連接wifi的環境已經搭建好了。
有關dhcp自動分配IP的部分請參考《arm linux 移植 udhcp 與 使用》