# Wi-Fi networking for Raspberry Pi <small>*Practice using Raspberry Pi 4B with Raspberry Pi OS (64-bit) 2023-12-05.*</small> ## Wireless interface - **rfkill** unblock Make sure the wireless card is enabled. Use **rfkill** to check the status of wireless card. ```shell $ rfkill list ``` If the wireless card is blocked, use the following command to unblock it. ```shell $ rfkill unblock wifi ``` - disable **NetworkManager** If using the desktop version of Raspberry Pi OS or Ubuntu, then stop NetworkManager. ```shell $ sudo systemctl status NetworkManager $ sudo systemctl stop NetworkManager $ sudo systemctl disable NetworkManager ``` - **wireless interface and wireless network** Use **iwconfig** or **iw dev** to find the name of wireless interfaces. ```shell $ iwconfig $ iw dev ``` Find the wireless network name by scanning nearby networks with the command below. ```shell $ sudo iwlist wlan0 scan | grep ESSID ``` If it shows error message "**Network is down**", turn on the interface using command below. ```shell $ sudo ifconfig wlan0 up #or $ sudo ip link set dev wlan0 up ``` - **show the capabilities of the wireless interface** Use **iw list** to show the capabilities of all Wi-Fi interfaces, or use **iw phy <phyname> info** to see the specified interface information. It will show the supported modes of the interface. ```shell $ iw list $ iw phy phy0 info ... Supported interface modes: * IBSS * managed * AP * P2P-client * P2P-GO * P2P-device ... ``` ## Infrastructure Wi-Fi network - **wpa_supplicant for infrastructure mode** Install wpa_supplicant if not installed. ```shell $ sudo apt install wpasupplicant ``` Create a configuration file named *wpa_supplicant_IFCE.conf* using the **wpa_passphrase** utility. ```shell $ wpa_passphrase <AP-ESSID> <AP-passphrase> | tee wpa_supplicant_wlan0.conf ``` Use the following command to connect the wireless card to wireless access point. ```shell $ sudo wpa_supplicant -B -i wlan0 -c wpa_supplicant_wlan0.conf ``` See the connection information. ```shell $ iw dev ``` - **dhclient** Although the network is connected, but we don't have an IP address yet. To obtail a private IP address from DHCP server, user the following command: ```shell $ sudo dhclient wlan0 $ ifconfig wlan0 ``` To release the private IP address, run ```shell $ sudo dhclient wlan0 -r ``` ## ad-hoc network - **wpa_supplicant for ad-hoc mode** Create a configuration file named *wpa_supplicant_adhoc.conf* with the following text. ```txt ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev country=TW update_config=1 p2p_disabled=1 network={ ssid="cloud" mode=1 frequency=2421 key_mgmt=NONE } ``` **wpa_supplicant** has peer-to-peer enabled by default, which is used by WiFi-Direct. If you do not disable P2P with the option *p2p_disabled=1*, you cannot enable IBSS mode and will receive the following error messages: ```txt nl80211: Failed to set interface into IBSS mode wlan0: Association request to the driver failed ``` Connect the wireless card to the ad-hoc network. ```shell $ sudo wpa_supplicant -B -i wlan0 -c wpa_supplicant_adhoc.conf ``` See the connection information. ```shell $ iw dev ``` - **Static IP address** Use the **ip addr** command to assign a static IP address to the interface. ```shell $ sudo ip addr add 10.0.0.1/24 dev wlan0 ``` See the IP address of the interface. ```shell $ ip -c addr show wlan0 ``` To obtain node information within the ad-hoc network and check for duplicate IP addresses, use the following command. ```shell $ sudo arp-scan -I wlan0 -l ``` **Note:** If the duplicated IP address is assigned to the interface itself, it may not receive the response packets, resulting in an empty result. Another way to setup a static IP address is to use the **networking service** to create a network interface configuratioin file, for example, named *wlan0* ,in /etc/network/interfaces.d/ directory. It can also configure ad-hoc mode in this file instead of using **wpa_supplicant**. ```txt auto wlan0 iface wlan0 inet static address 10.0.0.1 netmask 255.255.255.0 # set up ad-hoc mode instead of using wpa_supplicant wireless-channel 1 wireless-essid cloud wireless-mode ad-hoc ``` Then, restart the networking service. ```shell $ sudo systemctl restart networking $ sudo systemctl status networking ``` - **routing table** Use the **ip route** command to check the routing table for a route to the ad-hoc network associated with the interface. If there isn't one, add it. ```shell $ ip route $ ip route add 10.0.0.0/24 dev wlan0 ``` **Note:** Another way is to use the **route** command to add a route. ```shell $ route -n $ route add -net 10.0.0.0/24 dev wlan0 ``` - **Signal strength** Use the **iw** command to check the information of associated peers in the ad-hoc network, including the signal strength data. ```shell $ iw dev wlan0 station dump ``` This may yield an empty result on Raspberry Pi, so specifying the MAC address can obtain the desired result. ```shell $ iw dev wlan0 station get <MAC address> ``` ### Auto Wi-Fi connect on startup - **wpa_supplicant service** To automatically connect to wireless network at boot time, we need to edit the *wpa_supplicant.service* file. It's good idea to copy the file from */lib/systemd/system/* directory to ***/etc/systemd/system/*** directory, then edit it because we don't want newer version of **wpasupplicant** to override our modifications. ```shell sudo cp /lib/systemd/system/wpa_supplicant.service /etc/systemd/system/wpa_supplicant.service sudo vim /etc/systemd/system/wpa_supplicant.service ``` Change the line as the following. ```txt #ExecStart=/sbin/wpa_supplicant -u -s -O "DIR=/run/wpa_supplicant GROUP=netdev" ExecStart=/sbin/wpa_supplicant -u -s -c /etc/wpa_supplicant.conf -i wlan0 ``` Comment the line if exists. ```txt #Alias=dbus-fi.w1.wpa_supplicant1.service ``` It's recommended to always try to restart wpa_supplicant when failure is detected. Add the following right below the `ExecStart` line. ```txt Restart=always ``` If the external WiFi device **wlan1** is used, add and change the content as follows. ```txt BindsTo=sys-subsystem-net-devices-wlan1.device After=sys-subsystem-net-devices-wlan1.device #After=dbus.service ``` So, the fianl service file is ```txt [Unit] Description=WPA supplicant Before=network.target BindsTo=sys-subsystem-net-devices-wlan1.device After=sys-subsystem-net-devices-wlan1.device #After=dbus.service Wants=network.target IgnoreOnIsolate=true [Service] Type=dbus BusName=fi.w1.wpa_supplicant1 ExecStart=/sbin/wpa_supplicant -u -s -c /etc/wpa_supplicant/wpa_supplicant-connTimotion.conf -i wlan1 #ExecStart=/sbin/wpa_supplicant -u -s -O "DIR=/run/wpa_supplicant GROUP=netdev" ExecReload=/bin/kill -HUP $MAINPID Group=netdev RuntimeDirectory=wpa_supplicant RuntimeDirectoryMode=0750 [Install] WantedBy=multi-user.target #Alias=dbus-fi.w1.wpa_supplicant1.service ``` Enable wpa_supplicant service. ```shell $ sudo systemctl enable wpa_supplicant.service ``` - **dhclient service** Create a systemd service unit for **dhclient** if the interface does not use a static IP address. ```shell $ sudo vim /etc/systemd/system/dhclient.service ``` Put the following text into the file. ```text [Unit] Description= DHCP Client Before=network.target # If the external WiFi device 'wlan1' is used. BindsTo=sys-subsystem-net-devices-wlan1.device After=sys-subsystem-net-devices-wlan1.device [Service] Type=forking ExecStart=/sbin/dhclient wlan0 -v ExecStop=/sbin/dhclient wlan0 -r Restart=always [Install] WantedBy=multi-user.target ``` Restart this service. ```shell $ sudo systemctl restart dhclient.service ``` Enable this service. ```shell $ sudo systemctl enable dhclient.service ``` **Note:** The **dhclient** service can be used to set up a static IP address without a DHCP server by using the following confuguration. ```shell $ sudo vim /etc/dhcp/dhclient.conf ... lease { interface "wlan0"; fixed-address 10.0.0.3; option subnet-mask 255.255.255.0; } ``` ### References - The wpa_supplicant official site: [Developers' documentation for wpa_supplicant](https://w1.fi/wpa_supplicant/devel/index.html) and [wpa_supplicant.conf](https://w1.fi/cgit/hostap/plain/wpa_supplicant/wpa_supplicant.conf) - Debian wifi: [NetworkConfiguration](https://wiki.debian.org/NetworkConfiguration) and [WiFi Ad-hoc Network](https://wiki.debian.org/WiFi/AdHoc) - [Linux *ip* Command Examples](https://www.cyberciti.biz/faq/linux-ip-command-examples-usage-syntax/) - [Using WPA_Supplicant to Connect to WPA2 Wi-fi from Terminal on Ubuntu 16.04 Server](https://www.linuxbabe.com/command-line/ubuntu-server-16-04-wifi-wpa-supplicant) - [How to setup an Ad Hoc (IBSS) Network](https://raspberrypi.stackexchange.com/questions/94047/how-to-setup-an-unprotected-ad-hoc-ibss-network-and-if-possible-with-wpa-encry) - [How to bring up network on boot-up when NetworkManager is uninstalled?](https://askubuntu.com/questions/22663/how-to-bring-up-network-on-boot-up-when-networkmanager-is-uninstalled) - [Create a Mesh Network over WiFi using Raspberry Pi](https://github.com/binnes/WiFiMeshRaspberryPi)