panthema / 2019 / 0802-BlinkenSort-The-Sound-of-LED-Sorting-Algorithms-with-RaspberryPi3-and-APA102-or-SK9822 / wifi-ap-station

BlinkenSort with Sound - Optional: Set Up Both WiFi Station and an Access Point

Posted on 2019-07-27 19:00 by Timo Bingmann at Permlink.

Connecting the Raspberry Pi to a WiFi can easily be done using the raspi-config tool. However, since I take the BlinkenSort art installations to various places I like it to also open an access point (AP) simultaneously. That is much harder.

The following tutorial worked on 2019-07-10-raspbian-buster-lite.zip. Your mileage may vary in future versions.

# set up wifi using raspi-config
$ sudo raspi-config
# 2 Network Options > N2 Wi-fi

# install hostapd to advertise a WiFi AP
$ sudo apt install hostapd dnsmasq

Check which WiFi channel your local access point is on. The access point MUST be configured to use the same channel. My system uses channel 3.

$ iw wlan0 info

Create the uap0 interface by writing the file
sudo nano /etc/udev/rules.d/90-wireless.rules

ACTION=="add", SUBSYSTEM=="ieee80211", KERNEL=="phy0", \
    RUN+="/sbin/iw phy %k interface add uap0 type __ap"

Statically configure the uap0 interface by writing the file
sudo nano /etc/network/interfaces.d/uap0

allow-hotplug uap0
auto uap0
iface uap0 inet static
    address 10.3.141.1
    netmask 255.255.255.0

Configure hostapd by creating the following file:
sudo nano /etc/hostapd/hostapd.conf
Maybe change the WiFi SSID and key wpa_passphrase below.

# This is the name of the WiFi interface we configured above
interface=uap0

# Use the nl80211 driver with the brcmfmac driver
driver=nl80211

# This is the name of the network
ssid=Sort-Pi

# Use the 2.4GHz band
hw_mode=g

# Use channel 3
channel=3

# Enable 802.11n
#ieee80211n=1

# Enable WMM
wmm_enabled=0

# Enable 40MHz channels with 20ns guard interval
#ht_capab=[HT40][SHORT-GI-20][DSSS_CCK-40]

# Accept all MAC addresses
macaddr_acl=0

# Use WPA authentication
auth_algs=1

# Require clients to know the network name
ignore_broadcast_ssid=0

# Use WPA2
wpa=2

# Use a pre-shared key
wpa_key_mgmt=WPA-PSK

# The network passphrase
wpa_passphrase=tbsortingpi

# Use AES, instead of TKIP
rsn_pairwise=CCMP

Configure dnsmasq for the uap0 interface by creating the following file:
sudo nano /etc/dnsmasq.d/uap0.conf

# If you want dnsmasq to listen for DHCP and DNS requests only on
# specified interfaces (and the loopback) give the name of the
# interface (eg eth0) here.
interface=lo,uap0

# If you want dnsmasq to provide only DNS service on an interface,
# configure it as shown above, and then use the following line to
# disable DHCP and TFTP on it.
no-dhcp-interface=lo,eth0,wlan0

bind-interfaces

# Enable the integrated DHCP server
dhcp-range=10.3.141.50,10.3.141.255,12h

# Add other name servers here, with domain specs if they are for
# non-public domains.
server=8.8.8.8

# Override the default route supplied by dnsmasq and send no default
# route at all.
dhcp-option=3

Disable DHCP client on uap0 by appending the following to its config file:
sudo nano /etc/dhcpcd.conf

interface uap0
nohook wpa_supplicant

Reboot once with disabled hostapd and dnsmasq to test WiFi client and interface configurations, then enable services.

# disable hostapd and dnsmasq for now
$ sudo systemctl disable hostapd dnsmasq

# first reboot to get the network devices working
$ sudo reboot

# check that the WiFi client connects by watching the interfaces
$ ifconfig
(uap0 should exist, wlan0 should exist and be connected to your WiFi router)

# unmask service
$ sudo systemctl unmask hostapd dnsmasq

# enable services
$ sudo systemctl enable hostapd dnsmasq

Delay start-up of the DHCP client on wlan0 until after hostapd launches.
sudo nano /etc/systemd/system/dhcpcd5.service

Remove the following line from systemd's dhcpcd5.service file in the existing sections:

[Unit]
Before=network.target

Add the following lines to systemd's dhcpcd5.service file in the existing sections:

[Unit]
After=hostapd.service

[Service]
ExecStartPre=/bin/sleep 10

Then reboot and check that hostapd and dnsmasq are running correctly by watching ifconfig.

$ sudo reboot