加入星計劃,您可以享受以下權益:

  • 創(chuàng)作內容快速變現
  • 行業(yè)影響力擴散
  • 作品版權保護
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
    • 1 sh腳本wifi聯網介紹
    • 2 fltest_wifi.sh腳本文件分析
    • 3 總結
  • 相關推薦
  • 電子產業(yè)圖譜
申請入駐 產業(yè)圖譜

嵌入式Linux之wifi配網腳本分析

12/02 16:08
1325
閱讀需 28 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

嵌入式Linux系統(tǒng),一般都支持wifi聯網,可以通過sh腳本或其它語言代碼編程來實現wifi聯網。

本篇來介紹一種通過sh腳本來配置wifi的腳本執(zhí)行原理。

1 sh腳本wifi聯網介紹

這里以飛凌開發(fā)板中的wifi啟動腳本為例來介紹。

在飛凌開發(fā)板的串口中,執(zhí)行如下命令(調用fltest_wifi.sh腳本,并指定一些參數),進行wifi連接:

fltest_wifi.sh -i mlan0 -s "wifi_name" -p wifi_password
    wifi_name是自己的wifi名稱wifi_password是對于的wifi密碼

然后ifconfig指令可以查看板子IP信息:

[root@ok3568:/usr/sbin]# ifconfig
lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:239 errors:0 dropped:0 overruns:0 frame:0
          TX packets:239 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:346556 (338.4 KiB)  TX bytes:346556 (338.4 KiB)

mlan0     Link encap:Ethernet  HWaddr E8:FB:1C:66:AF:DF
          inet addr:192.168.5.111  Bcast:192.168.5.255  Mask:255.255.255.0
          inet6 addr: fe80::eafb:1cff:fe66:afdf/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1799 errors:0 dropped:0 overruns:0 frame:0
          TX packets:981 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:109635 (107.0 KiB)  TX bytes:331552 (323.7 KiB)

[root@ok3568:/usr/sbin]#

可以看到,mlan0這個網絡接口的IP為192.168.5.111

2 fltest_wifi.sh腳本文件分析

下面來具體分析fltest_wifi.sh腳本的內容。

2.1 開頭部分分析

先來看開頭的這段腳本:

cnt1=`ps aux | grep hostapd | grep -v grep  | wc -l`
if [ "$cnt1" != "0" ];then
        killall hostapd > /dev/null
fi

/etc/init.d/S80dnsmasq stop > /dev/null

分析:

首先是執(zhí)行一條指令,確認正在運行的hostapd進程的個數,保存在cnt1變量中

ps aux

    • :查看系統(tǒng)中當前正在運行的所有進程的詳細信息

| grep hostapd | grep -v grep

    • :匹配包含hostapd 并且不包含grep字樣的行

| wc -l

    :統(tǒng)計行數(word count,字數統(tǒng)計)

注:“ps aux” 其實是一種組合使用的命令形式

    “ps” 是 “process status”(進程狀態(tài))的縮寫“a” 表示顯示所有用戶(包括其他用戶和終端用戶)的進程,不僅僅是當前用戶啟動的進程“u” 表示以用戶為導向的詳細格式(user-oriented detailed format)來顯示進程信息,會給出諸如啟動進程的用戶、進程占用的 CPU 和內存資源百分比、進程狀態(tài)等更為詳細的信息“x” 表示顯示沒有控制終端的進程,也就是那些在后臺運行的、不是通過常規(guī)終端啟動的進程

hostapd 是Linux中一款用于創(chuàng)建無線接入點(Wireless Access Point,WAP)的軟件

hostapd的功能是用來創(chuàng)建AP,因為是要連接wifi,而不是創(chuàng)建熱點,所以如果有hostapd進程,則停掉。

如果cnt1不為0,則殺掉所有的hostapd進程

killall:用于通過進程名來終止一個或多個正在運行的進程

    • :Linux中常用的一種重定向操作,用于將命令的輸出重定向到指定的位置

/dev/null:一個特殊的設備文件,可以接收任何寫入的數據,但會直接丟棄這些數據

然后,執(zhí)行/etc/init.d/S80dnsmasq stop

2.1.1 S80dnsmasq腳本分析

S80dnsmasq 也是一個腳本,內容為:

#!/bin/sh

[ -f /etc/dnsmasq.conf ] || exit 0

case "$1" in
        start)
                printf "Starting dnsmasq: "
                start-stop-daemon -S -x /usr/sbin/dnsmasq
                [ $? = 0 ] && echo "OK" || echo "FAIL"
                ;;
        stop)
                printf "Stopping dnsmasq: "
                start-stop-daemon -K -q -x /usr/sbin/dnsmasq
                [ $? = 0 ] && echo "OK" || echo "FAIL"
                ;;
        restart|reload)
                $0 stop
                $0 start
                ;;
        *)
                echo "Usage: $0 {start|stop|restart}"
                exit 1
esac

exit 0

先來看這一句,含義是檢查指定文件dnsmasq.conf是否存在且為普通文件,若不存在,則退出

[ -f /etc/dnsmasq.conf ] || exit 0

分析:

[

]

    • :這是

test

    • 命令的一種語法糖形式(一種更簡潔、方便書寫的等效形式),用于條件測試。

-f

    • :這是

test

    • 命令的一個選項參數,用于判斷指定的對象是否為普通文件

||

    • :這是 shell 中的邏輯或運算符

exit 0

    :shell 命令,退出當前的腳本執(zhí)行環(huán)境或者命令行執(zhí)行環(huán)境,返回值0表示正常退出

接下來,case用來判斷腳本的輸入參數并進行處理,如果參數是stop,則執(zhí)行:

printf "Stopping dnsmasq: "
start-stop-daemon -K -q -x /usr/sbin/dnsmasq
[ $? = 0 ] && echo "OK" || echo "FAIL"

分析:

start-stop-daemon

    • 是一個用于管理守護進程(daemon)的工具,上述命令具體是要對

dnsmasq

    • 這個守護進程進行某種操作。

-K

    • :該選項通常用于向指定的守護進程發(fā)送一個信號,以實現停止(kill)該進程的目的。

-q

    • :表示 “quiet”,即安靜模式。在這種模式下,命令執(zhí)行過程中不會產生太多的額外輸出信息。

-x /usr/sbin/dnsmasq

    • :其中

-x

    • 用于指定要操作的可執(zhí)行文件路徑,這里明確指定了要對位于

/usr/sbin/dnsmasq

dnsmasq

    可執(zhí)行文件所對應的守護進程進行操作。

dnsmasq 是Linux中一款輕量級 DNS 轉發(fā)器和 DHCP 服務器軟件。

2.1.2 dnsmasq.conf

再來看下dnsmasq.conf 中的內容:

interface=uap0
bind-interfaces
except-interface=lo
dhcp-range=192.168.2.100,192.168.2.254,12h
dhcp-option=3,192.168.2.1
dhcp-option=6,192.168.2.1

它是dnsmasq軟件的的一個配置文件

interface=uap0 :指定了要綁定或進行相關網絡操作的網絡接口名稱為 uap0。

bind-interfaces :指示軟件要綁定到指定的網絡接口(在這里就是前面提到的 uap0 接口)。它確保了相關的網絡服務(如 DHCP 服務、DNS 轉發(fā)等,如果適用)只會在這個特定接口上進行操作,而不會影響到其他未指定的接口。

except-interface=lolo 通常代表本地回環(huán)接口(loopback interface)。設置 except-interface=lo 表示在進行上述的綁定操作以及后續(xù)的網絡服務提供過程中,要排除本地回環(huán)接口。

dhcp-range=192.168.2.100,192.168.2.254,12h :作為 DHCP 服務器的配置項,它指定了要分配給客戶端的 IP 地址范圍以及租約期限。具體來說:

192.168.2.100192.168.2.254:這兩個 IP 地址界定了可分配給客戶端的 IP 地址區(qū)間。

12h:表示租約期限為 12 小時。

dhcp-option=3,192.168.2.1 :這是設置 DHCP 選項的配置項。在這里的3 通常代表默認網關選項(default gateway option)。

dhcp-option=6,192.168.2.1:同樣是設置 DHCP 選項的配置項。這里的 6 通常代表 DNS 服務器選項(DNS server option)。

2.2 參數解析部分

usage()和parse_args()是編寫的兩個函數,用于打印幫助信息和解析腳本的輸入參數

function usage()
{
    echo "Usage: -i <wifi> -s <ssid> -p <password>"
    echo "eg: ./wifi.sh -i mlan0 -s bjforlinx -p 12345678 "
    echo "eg: ./wifi.sh -i mlan0 -s bjforlinx -p NONE "
    echo " -i : mlan0 or mlan1"
    echo " -s : wifi ssid"
    echo " -p : wifi password or NONE"
}

function parse_args()
{
    while true; do
        case "$1" in
            -i ) wifi=$2;echo wifi $wifi;shift 2 ;;
            -s ) ssid=$2;echo ssid $ssid;shift 2 ;;
            -p ) pasw=$2;echo pasw $pasw;shift 2 ;;
            -h ) usage; exit 1 ;;
            * ) break ;;
        esac
    done
}

if [ $# != 6 ]
then
    usage;
    exit 1;
fi

parse_args $@

該腳本的功能部分是:判斷fltest_wifi.sh腳本的輸入參數是否為6個:

    如果不是,則打印幫助信息,并退出如果是,則對腳本的6個輸入參數進行解析

再來回顧下,6個參數:

fltest_wifi.sh -i mlan0 -s "wifi_name" -p wifi_password

2.3 連接wifi部分

連接wifi使用的是wpa_supplicant工具,wpa_supplicant全稱Wi-Fi Protected Access Supplicant。

2.3.1 修改wpa_supplicant配置文件

if [ -e /etc/wpa_supplicant.conf ]
then
    rm /etc/wpa_supplicant.conf
fi
    echo #PSK/TKIP >> /etc/wpa_supplicant.conf
	echo ctrl_interface=/var/run/wpa_supplicant >>/etc/wpa_supplicant.conf
	echo ctrl_interface_group=0 >>/etc/wpa_supplicant.conf
	echo update_config=1 >>/etc/wpa_supplicant.conf
	echo network={ >>/etc/wpa_supplicant.conf
    echo ssid="$ssid" >>/etc/wpa_supplicant.conf
	echo scan_ssid=1 >>/etc/wpa_supplicant.conf
    if [ $pasw == NONE ]
	then
		echo key_mgmt=NONE >>/etc/wpa_supplicant.conf
	else
		echo psk="$pasw" >>/etc/wpa_supplicant.conf
		echo key_mgmt=WPA-EAP WPA-PSK IEEE8021X NONE >>/etc/wpa_supplicant.conf
		echo group=CCMP TKIP WEP104 WEP40 >>/etc/wpa_supplicant.conf
	fi
    echo } >>/etc/wpa_supplicant.conf

我們可以看下wpa_supplicant.conf最終被修改后的內容

#PSK/TKIP
ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group=0
update_config=1
network={
ssid="MERCURY_3394"
scan_ssid=1
psk="2H2+O2=2H2O"
key_mgmt=WPA-EAP WPA-PSK IEEE8021X NONE
group=CCMP TKIP WEP104 WEP40
}

2.3.2 一些ifconfig指令關閉網絡接口

ifconfig -a|grep mlan0 |grep -v grep  > /dev/null
if [ $? -eq 0 ]
then
	ifconfig mlan0 down > /dev/null
fi

ifconfig -a|grep mlan1 |grep -v grep  > /dev/null
if [ $? -eq 0 ]
then
	ifconfig mlan1 down > /dev/null
fi

ifconfig -a|grep eth0 |grep -v grep  > /dev/null
if [ $? -eq 0 ]
then
	ifconfig eth0 down > /dev/null
fi

ifconfig -a|grep eth1 |grep -v grep  > /dev/null
if [ $? -eq 0 ]
then
	ifconfig eth1 down > /dev/null
fi

分析:

ifconfig -a

    :用于查看系統(tǒng)中所有網絡接口(包括已啟用和未啟用的)的詳細配置信息然后查找mlan0、mlan1、eth0、eth1,如果有這些網絡接口,則將其關閉

2.3.3 停掉wpa_supplicant

ps -fe|grep wpa_supplicant |grep -v grep > /dev/null
if [ $? -eq 0 ]
then
	kill -9 $(pidof wpa_supplicant)
fi

分析:ps -fe 是全面詳細地查看系統(tǒng)中所有用戶啟動的所有進程的狀態(tài)信息

-f

    • 表示以全格式(full format)顯示進程信息

-e

    表示顯示所有用戶(包括其他用戶和終端用戶)的進程

如果存在wpa_supplicant進程在運行,則殺掉該進程

2.3.4 啟用指定的網絡接口

sleep 1
ifconfig $wifi up > /dev/null 
sleep 1

up

ifconfig

    • 命令中設置網絡接口為啟用狀態(tài)的一個參數。

$wifi

    :是一個變量,在parse_args()中對其進行賦值,即mlan0這個網絡接口。

2.3.5 通過wpa_supplicant進行配網

(wpa_supplicant -Dnl80211,wext -i$wifi -c/etc/wpa_supplicant.conf  >/dev/null) &
echo "waiting..."
sleep 3
wpa_cli -i$wifi status |grep COMPLETED |grep -v grep >/dev/null
if [ $? -eq 0 ]
then
	udhcpc -i $wifi
	echo "Finshed!" 
else
	echo "try to connect again..."
	sleep 3
	wpa_cli -i$wifi status |grep COMPLETED |grep -v grep >/dev/null
		if [ $? -eq 0 ]
		then
        		udhcpc -i $wifi
				echo "nameserver 114.114.114.114" > /etc/resolv.conf
       			echo "Finshed!"
		else
        		echo "************************************************"
       	 		echo "connect faild,please check the passward and ssid"
  		      	kill -9 $(pidof wpa_supplicant)
			exit 1
		fi
fi

先來看第一條,該命令是在后臺啟動 wpa_supplicant 進程,并按照指定的參數進行無線網絡配置相關的操作

(wpa_supplicant -Dnl80211,wext -i$wifi -c/etc/wpa_supplicant.conf  >/dev/null) &

主要分析wpa_supplicant的參數選項:

-D:用于指定驅動程序類型。

nl80211

wext:是兩種常見的無線網卡驅動程序類型。在這里同時指定這兩種驅動程序類型。

-i:用于指定要連接的無線網絡接口名稱。

-c:用于指定配置文件的路徑。

等待3秒后,再來看這條指令,用于檢查通過指定無線網絡接口連接wifi的認證過程是否已經完成:

wpa_cli -i$wifi status |grep COMPLETED |grep -v grep >/dev/null

分析:

wpa_cli:是與wpa_supplicant

    • 配套使用的命令行工具,用于與wpa_supplicant
    • 進程進行交互。

-i:用于指定要連接的無線網絡接口名稱。

status:是wpa_cli

    命令的一個操作,用于查詢指定無線網絡接口的連接狀態(tài)信息。然后查找輸出信息中是否包含COMPLETED字樣

我們可以手動輸入前半部分指令:

[root@ok3568:/usr/sbin]# wpa_cli -imlan0 status
bssid=f4:ee:14:1b:33:94
freq=2412
ssid=MERCURY_3394
id=0
mode=station
pairwise_cipher=CCMP
group_cipher=CCMP
key_mgmt=WPA2-PSK
wpa_state=COMPLETED
ip_address=192.168.5.111
p2p_device_address=e8:fb:1c:66:af:df
address=e8:fb:1c:66:af:df
uuid=dbddbcf1-3fcd-54be-b9aa-57858a84189f
[root@ok3568:/usr/sbin]#

可以看到,wpa_state=COMPLETED

根據查詢結果,如果連接成功,則嘗試獲取一個動態(tài) IP 地址。如果失敗,則繼續(xù)嘗試連接:

if [ $? -eq 0 ]
then
	udhcpc -i $wifi
	echo "Finshed!" 
else
	echo "try to connect again..."

udhcpc

    :用于獲取動態(tài) IP 地址的客戶端程序。

udhcpc 是Linux中一個常用的動態(tài)主機配置協(xié)議(DHCP)客戶端程序,用于從網絡中的 DHCP 服務器獲取動態(tài) IP 地址以及相關的網絡配置參數。

    獲取動態(tài)IP獲取獲取動態(tài)IP獲?。?a class="article-link" target="_blank" href="/baike/1568921.html">子網掩碼、動態(tài)網關、DNS服務器地址)

2.4 整體回顧

    停掉hostapd(創(chuàng)建WAP無線接入點的軟件)停掉dnsmasq(DNS 轉發(fā)器和 DHCP 服務器軟)讀取解析參數(網絡接口名、wifi名稱、wifi密碼)根據參數,修改/etc/wpa_supplicant.conf文件關閉mlan0、mlan1、eth0、eth1這些網絡接口停掉wpa_supplicant啟用指定的網絡接口(mlan0)通過wpa_supplicant進行配網(搭配wpa_supplicant.conf文件)使用udhcpc獲取一個動態(tài) IP 地址

另外,這里再整理一些易混的名詞:

AP:Access Point,無線接入點

WPA:Wi-Fi Protected Access,Wi-Fi安全的無線接入點

hostapd:是Linux系統(tǒng)中帶加密功能的無線接入點(AP)程序

hostapd_cli:是hostapd中包含一個基于文本的使用工具

wpa_supplicant:(Wi-Fi Protected Access Supplicant)用來掃描和連接AP,后臺運行

wpa_cli:用來搜索、設置和連接網絡

udhcpd:工作在server端的DHCP服務,用來為設備分配IP地址

udhcpc:工作在client端的DHCP服務,用來獲取IP地址

3 總結

本篇,以飛凌嵌入式Linux開發(fā)板為例,介紹了其自帶的wifi配網腳本的執(zhí)行原理。通過自動配置wpa_supplicant.conf文件,并調用wpa_supplicant進行wifi配網。下篇,將繼續(xù)介紹如何通過C/C++編程,來實現wifi配網。

飛凌嵌入式

飛凌嵌入式

保定飛凌嵌入式技術有限公司,創(chuàng)建于2006年,是一家專注嵌入式核心控制系統(tǒng)研發(fā)、設計和生產的高新技術企業(yè),是國內較早專業(yè)從事嵌入式技術的企業(yè)之一。 經過十幾年的發(fā)展與積累,公司擁有業(yè)內優(yōu)秀的軟硬件研發(fā)團隊,在北京及保定建立兩大研發(fā)基地,在蘇州、深圳設有華東、華南技術服務中心,并在北美、歐洲以及亞太等其他國家和地區(qū)擁有國際業(yè)務網絡。公司研發(fā)的智能設備核心平臺廣泛應用于物聯網、工控、軌道交通、醫(yī)療、電力、商業(yè)電子、智能家居、安防、機器人、環(huán)境監(jiān)測等諸多領域。

保定飛凌嵌入式技術有限公司,創(chuàng)建于2006年,是一家專注嵌入式核心控制系統(tǒng)研發(fā)、設計和生產的高新技術企業(yè),是國內較早專業(yè)從事嵌入式技術的企業(yè)之一。 經過十幾年的發(fā)展與積累,公司擁有業(yè)內優(yōu)秀的軟硬件研發(fā)團隊,在北京及保定建立兩大研發(fā)基地,在蘇州、深圳設有華東、華南技術服務中心,并在北美、歐洲以及亞太等其他國家和地區(qū)擁有國際業(yè)務網絡。公司研發(fā)的智能設備核心平臺廣泛應用于物聯網、工控、軌道交通、醫(yī)療、電力、商業(yè)電子、智能家居、安防、機器人、環(huán)境監(jiān)測等諸多領域。收起

查看更多

相關推薦

電子產業(yè)圖譜

控制科學與工程碩士,日常分享單片機、嵌入式、C/C++、Linux等學習經驗干貨~