Analysis of Wi-Fi Configuration Script in Embedded Linux

Follow “Coder Loves Learning“, set “Star Public Account

Practical Benefits Delivered First-Hand!

The embedded Linux system generally supports Wi-Fi connectivity, which can be achieved through shell scripts or other programming languages.

This article introduces the execution principle of a script that configures Wi-Fi using a shell script.

1 Introduction to Wi-Fi Connectivity via Shell Script

Here, we take the Wi-Fi startup script in the Feilin development board as an example.

Analysis of Wi-Fi Configuration Script in Embedded Linux

In the serial port of the Feilin development board, execute the following command (calling the fltest_wifi.sh script and specifying some parameters) to connect to Wi-Fi:
fltest_wifi.sh -i mlan0 -s "wifi_name" -p wifi_password
  • wifi_name is your Wi-Fi name
  • wifi_password is the corresponding Wi-Fi password

Then, the ifconfig command can be used to check the board’s IP information:

[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]#

As we can see, the IP address of the mlan0 network interface is 192.168.5.111

2 Analysis of fltest_wifi.sh Script File

Next, we will analyze the content of the fltest_wifi.sh script in detail.

2.1 Analysis of the Beginning Section

First, let’s look at this segment of the script:

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

Analysis:

First, a command is executed to confirm the number of running hostapd processes, which is stored in the cnt1 variable.

  • ps aux: View detailed information about all currently running processes in the system.
  • | grep hostapd | grep -v grep: Match lines containing hostapd and not containing grep.
  • | wc -l: Count the number of lines (word count).

Note: “ps aux” is actually a combined command form.

  • “ps” is short for “process status”.
  • “a” means to display processes of all users, not just those started by the current user.
  • “u” means to display process information in a user-oriented detailed format.
  • “x” means to display processes without a controlling terminal.

hostapd is a software used in Linux to create a Wireless Access Point (WAP).

The function of hostapd is to create an AP. Since we want to connect to Wi-Fi and not create a hotspot, if there is a hostapd process, it should be stopped.

Analysis of Wi-Fi Configuration Script in Embedded Linux

If cnt1 is not 0, all hostapd processes will be killed.

  • killall: Used to terminate one or more running processes by name.
  • >: A common redirection operation in Linux, used to redirect command output to a specified location.
  • /dev/null: A special device file that can receive any data written to it but will discard that data.

Then, execute /etc/init.d/S80dnsmasq stop.

2.1.1 Analysis of S80dnsmasq Script

S80dnsmasq is also a script, with the content:

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

First, let’s look at this line, which checks whether the specified file dnsmasq.conf exists and is a regular file. If it does not exist, it exits.

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

Analysis:

  • [ and ]: This is a syntactic sugar form of the test command, used for conditional testing.
  • -f: This is an option parameter of the test command, used to determine if the specified object is a regular file.
  • ||: This is the logical OR operator in shell.
  • exit 0: A shell command that exits the current script execution environment, returning 0 to indicate normal exit.

Next, the case statement is used to determine the input parameters of the script and process them. If the parameter is stop, it executes:

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

Analysis:

  • start-stop-daemon is a tool used to manage daemon processes. The above command specifically operates on the dnsmasq daemon.
  • -K: This option is typically used to send a signal to the specified daemon process to stop (kill) it.
  • -q: Indicates “quiet” mode, where the command execution will not produce excessive output.
  • -x /usr/sbin/dnsmasq: Here, -x is used to specify the path of the executable file to operate on, which is the dnsmasq executable located at /usr/sbin/dnsmasq.

dnsmasq is a lightweight DNS forwarder and DHCP server software in Linux.

2.1.2 dnsmasq.conf

Now let’s look at the content of 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

This is a configuration file for the dnsmasq software.

  • interface=uap0: Specifies that the network interface name for binding or related network operations is uap0.

  • bind-interfaces: Instructs the software to bind to the specified network interface (in this case, the previously mentioned uap0 interface). It ensures that related network services (such as DHCP service, DNS forwarding, etc.) will only operate on this specific interface and will not affect other unspecified interfaces.

  • except-interface=lo: lo typically represents the local loopback interface. Setting except-interface=lo means that during the binding operation and subsequent network service provision, the local loopback interface will be excluded.

  • dhcp-range=192.168.2.100,192.168.2.254,12h: As a configuration item for the DHCP server, it specifies the range of IP addresses to be allocated to clients and the lease duration. Specifically:

    • 192.168.2.100 and 192.168.2.254: These two IP addresses define the range of IP addresses that can be allocated to clients.
    • 12h: Indicates that the lease duration is 12 hours.
  • dhcp-option=3,192.168.2.1: This is a configuration item for setting DHCP options. Here, 3 typically represents the default gateway option.

  • dhcp-option=6,192.168.2.1: This is also a configuration item for setting DHCP options. Here, 6 typically represents the DNS server option.

2.2 Parameter Parsing Section

usage() and parse_args() are two functions written to print help information and parse the input parameters of the script.

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 $@

The functional part of this script is to check whether the input parameters of fltest_wifi.sh are 6:

  • If not, it prints help information and exits.
  • If yes, it parses the 6 input parameters of the script.

Let’s review the 6 parameters:

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

2.3 Wi-Fi Connection Section

Connecting to Wi-Fi uses the wpa_supplicant tool, which stands for Wi-Fi Protected Access Supplicant.

Analysis of Wi-Fi Configuration Script in Embedded Linux

2.3.1 Modifying the wpa_supplicant Configuration File

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

We can look at the final modified content of 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 Some ifconfig Commands to Disable Network Interfaces

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

Analysis:

  • ifconfig -a: Used to view detailed configuration information of all network interfaces in the system (including enabled and disabled).
  • Then check for mlan0, mlan1, eth0, eth1. If these network interfaces exist, they will be disabled.

2.3.3 Stopping wpa_supplicant

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

Analysis: ps -fe is used to view the status information of all processes started by all users in a comprehensive and detailed manner.

  • -f indicates to display process information in full format.
  • -e indicates to display processes of all users.

If the wpa_supplicant process is running, it will be killed.

2.3.4 Enabling the Specified Network Interface

sleep 1
ifconfig $wifi up > /dev/null 
sleep 1
  • up is a parameter in the ifconfig command that sets the network interface to enabled status.
  • $wifi: This is a variable assigned in parse_args(), which is the mlan0 network interface.

2.3.5 Configuring the Network via 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 "Finished!" 
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 "Finished!"
	else
		echo "************************************************"
			echo "connect failed, please check the password and ssid"
		kill -9 $(pidof wpa_supplicant)
		exit 1
	fi
fi

First, let’s look at the command that starts the wpa_supplicant process in the background and performs wireless network configuration operations according to the specified parameters:

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

Let’s analyze the parameters of wpa_supplicant:

  • -D: Used to specify the driver type.
  • nl80211 and wext: Two common types of wireless network card drivers. Here, both driver types are specified.
  • -i: Used to specify the name of the wireless network interface to connect to.
  • -c: Used to specify the path of the configuration file.

After waiting for 3 seconds, the following command checks whether the authentication process for connecting to Wi-Fi through the specified wireless network interface has been completed:

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

Analysis:

  • wpa_cli: A command-line tool used to interact with the wpa_supplicant process.
  • -i: Used to specify the name of the wireless network interface to connect to.
  • status: An operation of the wpa_cli command used to query the connection status information of the specified wireless network interface.
  • Then check if the output information contains the word COMPLETED.

We can manually input the first part of the command:

[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]#

As we can see, wpa_state=COMPLETED.

Based on the query result, if the connection is successful, it attempts to obtain a dynamic IP address. If it fails, it continues to try to connect:

if [ $? -eq 0 ]
then
	udhcpc -i $wifi
	echo "Finished!" 
else
	echo "try to connect again..."
  • udhcpc: A client program used to obtain dynamic IP addresses.

udhcpc is a commonly used Dynamic Host Configuration Protocol (DHCP) client program in Linux, used to obtain dynamic IP addresses and related network configuration parameters from a DHCP server in the network.

  • Obtain dynamic IP
  • Obtain dynamic IP configuration (subnet mask, dynamic gateway, DNS server address)

2.4 Overall Review

  • Stop hostapd (software for creating WAP wireless access points).
  • Stop dnsmasq (DNS forwarder and DHCP server software).
  • Read and parse parameters (network interface name, Wi-Fi name, Wi-Fi password).
  • Modify the /etc/wpa_supplicant.conf file based on parameters.
  • Disable mlan0, mlan1, eth0, eth1 network interfaces.
  • Stop wpa_supplicant.
  • Enable the specified network interface (mlan0).
  • Configure the network via wpa_supplicant (using wpa_supplicant.conf file).
  • Use udhcpc to obtain a dynamic IP address.

Additionally, here are some commonly confused terms:

AP: Access Point, wireless access point.

WPA: Wi-Fi Protected Access, secure wireless access point.

hostapd: A program in the Linux system for creating wireless access points (AP) with encryption capabilities.

hostapd_cli: A text-based utility included in hostapd.

wpa_supplicant: (Wi-Fi Protected Access Supplicant) used to scan and connect to APs, running in the background.

wpa_cli: Used to search, set, and connect to networks.

udhcpd: DHCP service running on the server side to allocate IP addresses to devices.

udhcpc: DHCP service running on the client side to obtain IP addresses.

3 Conclusion

This article, using the Feilin embedded Linux development board as an example, introduced the execution principle of its built-in Wi-Fi configuration script. It automatically configures the wpa_supplicant.conf file and calls wpa_supplicant for Wi-Fi configuration. The next article will continue to introduce how to implement Wi-Fi configuration through C/C++ programming.

Recommended Articles

RK3568 – Introduction to a Linux Development Board i.MX9352 – Introduction to a Multi-core Heterogeneous Development Board Embedded Basics – Testing Basic Concepts

Illustration: Various Wi-Fi Configuration Methods for IoT Devices

Leave a Comment