加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長(zhǎng)期合作伙伴
立即加入
  • 正文
    • 1 sh腳本wifi聯(lián)網(wǎng)介紹
    • 2 fltest_wifi.sh腳本文件分析
    • 3 總結(jié)
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

嵌入式Linux之wifi配網(wǎng)腳本分析

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

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

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

1 sh腳本wifi聯(lián)網(wǎng)介紹

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

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

fltest_wifi.sh -i mlan0 -s "wifi_name" -p wifi_password
    wifi_name是自己的wifi名稱wifi_password是對(duì)于的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這個(gè)網(wǎng)絡(luò)接口的IP為192.168.5.111

2 fltest_wifi.sh腳本文件分析

下面來具體分析fltest_wifi.sh腳本的內(nèi)容。

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í)行一條指令,確認(rèn)正在運(yùn)行的hostapd進(jìn)程的個(gè)數(shù),保存在cnt1變量中

ps aux

    • :查看系統(tǒng)中當(dāng)前正在運(yùn)行的所有進(jìn)程的詳細(xì)信息

| grep hostapd | grep -v grep

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

| wc -l

    :統(tǒng)計(jì)行數(shù)(word count,字?jǐn)?shù)統(tǒng)計(jì))

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

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

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

hostapd的功能是用來創(chuàng)建AP,因?yàn)槭且B接wifi,而不是創(chuàng)建熱點(diǎn),所以如果有hostapd進(jìn)程,則停掉。

如果cnt1不為0,則殺掉所有的hostapd進(jìn)程

killall:用于通過進(jìn)程名來終止一個(gè)或多個(gè)正在運(yùn)行的進(jìn)程

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

/dev/null:一個(gè)特殊的設(shè)備文件,可以接收任何寫入的數(shù)據(jù),但會(huì)直接丟棄這些數(shù)據(jù)

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

2.1.1 S80dnsmasq腳本分析

S80dnsmasq 也是一個(gè)腳本,內(nèi)容為:

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

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

-f

    • :這是

test

    • 命令的一個(gè)選項(xiàng)參數(shù),用于判斷指定的對(duì)象是否為普通文件

||

    • :這是 shell 中的邏輯或運(yùn)算符

exit 0

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

接下來,case用來判斷腳本的輸入?yún)?shù)并進(jìn)行處理,如果參數(shù)是stop,則執(zhí)行:

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

分析:

start-stop-daemon

    • 是一個(gè)用于管理守護(hù)進(jìn)程(daemon)的工具,上述命令具體是要對(duì)

dnsmasq

    • 這個(gè)守護(hù)進(jìn)程進(jìn)行某種操作。

-K

    • :該選項(xiàng)通常用于向指定的守護(hù)進(jìn)程發(fā)送一個(gè)信號(hào),以實(shí)現(xiàn)停止(kill)該進(jìn)程的目的。

-q

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

-x /usr/sbin/dnsmasq

    • :其中

-x

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

/usr/sbin/dnsmasq

dnsmasq

    可執(zhí)行文件所對(duì)應(yīng)的守護(hù)進(jìn)程進(jìn)行操作。

dnsmasq 是Linux中一款輕量級(jí) DNS 轉(zhuǎn)發(fā)器和 DHCP 服務(wù)器軟件。

2.1.2 dnsmasq.conf

再來看下dnsmasq.conf 中的內(nèi)容:

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軟件的的一個(gè)配置文件

interface=uap0 :指定了要綁定或進(jìn)行相關(guān)網(wǎng)絡(luò)操作的網(wǎng)絡(luò)接口名稱為 uap0。

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

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

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

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

12h:表示租約期限為 12 小時(shí)。

dhcp-option=3,192.168.2.1 :這是設(shè)置 DHCP 選項(xiàng)的配置項(xiàng)。在這里的3 通常代表默認(rèn)網(wǎng)關(guān)選項(xiàng)(default gateway option)。

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

2.2 參數(shù)解析部分

usage()和parse_args()是編寫的兩個(gè)函數(shù),用于打印幫助信息和解析腳本的輸入?yún)?shù)

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腳本的輸入?yún)?shù)是否為6個(gè):

    如果不是,則打印幫助信息,并退出如果是,則對(duì)腳本的6個(gè)輸入?yún)?shù)進(jìn)行解析

再來回顧下,6個(gè)參數(shù):

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最終被修改后的內(nèi)容

#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指令關(guān)閉網(wǎng)絡(luò)接口

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)中所有網(wǎng)絡(luò)接口(包括已啟用和未啟用的)的詳細(xì)配置信息然后查找mlan0、mlan1、eth0、eth1,如果有這些網(wǎng)絡(luò)接口,則將其關(guān)閉

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 是全面詳細(xì)地查看系統(tǒng)中所有用戶啟動(dòng)的所有進(jìn)程的狀態(tài)信息

-f

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

-e

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

如果存在wpa_supplicant進(jìn)程在運(yùn)行,則殺掉該進(jìn)程

2.3.4 啟用指定的網(wǎng)絡(luò)接口

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

up

ifconfig

    • 命令中設(shè)置網(wǎng)絡(luò)接口為啟用狀態(tài)的一個(gè)參數(shù)。

$wifi

    :是一個(gè)變量,在parse_args()中對(duì)其進(jìn)行賦值,即mlan0這個(gè)網(wǎng)絡(luò)接口。

2.3.5 通過wpa_supplicant進(jìn)行配網(wǎng)

(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

先來看第一條,該命令是在后臺(tái)啟動(dòng) wpa_supplicant 進(jìn)程,并按照指定的參數(shù)進(jìn)行無線網(wǎng)絡(luò)配置相關(guān)的操作

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

主要分析wpa_supplicant的參數(shù)選項(xiàng):

-D:用于指定驅(qū)動(dòng)程序類型。

nl80211

wext:是兩種常見的無線網(wǎng)卡驅(qū)動(dòng)程序類型。在這里同時(shí)指定這兩種驅(qū)動(dòng)程序類型。

-i:用于指定要連接的無線網(wǎng)絡(luò)接口名稱。

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

等待3秒后,再來看這條指令,用于檢查通過指定無線網(wǎng)絡(luò)接口連接wifi的認(rèn)證過程是否已經(jīng)完成:

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

分析:

wpa_cli:是與wpa_supplicant

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

-i:用于指定要連接的無線網(wǎng)絡(luò)接口名稱。

status:是wpa_cli

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

我們可以手動(dòng)輸入前半部分指令:

[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

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

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

udhcpc

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

udhcpc 是Linux中一個(gè)常用的動(dòng)態(tài)主機(jī)配置協(xié)議(DHCP)客戶端程序,用于從網(wǎng)絡(luò)中的 DHCP 服務(wù)器獲取動(dòng)態(tài) IP 地址以及相關(guān)的網(wǎng)絡(luò)配置參數(shù)。

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

2.4 整體回顧

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

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

AP:Access Point,無線接入點(diǎn)

WPA:Wi-Fi Protected Access,Wi-Fi安全的無線接入點(diǎn)

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

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

wpa_supplicant:(Wi-Fi Protected Access Supplicant)用來掃描和連接AP,后臺(tái)運(yùn)行

wpa_cli:用來搜索、設(shè)置和連接網(wǎng)絡(luò)

udhcpd:工作在server端的DHCP服務(wù),用來為設(shè)備分配IP地址

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

3 總結(jié)

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

飛凌嵌入式

飛凌嵌入式

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

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

查看更多

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

控制科學(xué)與工程碩士,日常分享單片機(jī)、嵌入式、C/C++、Linux等學(xué)習(xí)經(jīng)驗(yàn)干貨~