---
# System prepended metadata

title: Wi-Fi networking for Raspberry Pi
tags: [wpa_supplicant, Raspberry Pi]

---

# 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)