The following sequence seems to produce a working AP and STA out of the builtin wifi adapter in Pi 3. This works around a few issues that I suspect related to the brcmfmac module.
This is a long post, so I'll go ahead and ask my question in advance:is this really the best way to make AP+STA work?
The virtual AP interface must be created before first use of wlan0. Removing/reloading the brcmfmac module could work to reset the system state, but I've seen crashes. A udev rule looks like the best solution to have the AP ready to serve when needed.
Code: Select all
rasp# cat /etc/udev/rules.d/virt-ap.rules
ACTION=="add", SUBSYSTEM=="ieee80211", ATTR{macaddress}=="b8:27:eb:??:??:??", KERNEL=="phy[0-9]", RUN+="/sbin/iw phy %k interface add ap%n type __ap"
Starting the AP breaks down the STA's association with its AP, and it never recovers. The only workaround I have found is to kill/restart the wpa_supplicant process altogether. No measure of reauth/reset/reload with wpa_cli would do.
It is possible to start wpa_supplicant standalone, and remove/add wlan0 via wpa_cli. It works and is easier than chasing for a PID in some circumstances.
Here is a sequence I've been running after boot, ap0 created by udev, eth0 networking up:
(Redirections to /dev/null to conceal my MACs)
Code: Select all
# execute as root
export WLAN_GW='172.17.0.1'
for IF in wlan0 ap0; do for OPT in c f m p; do iwgetid -${OPT} $IF; done; done # Live interfaces configs
grep channel /etc/hostapd.conf # AP channel in config file
wpa_supplicant -B -g/var/run/wpa_supplicant_master -Groot # Start WPA Supplicant master process
wpa_cli -g/var/run/wpa_supplicant_master interface_add wlan0 /etc/wpa_supplicant.wlan0.conf nl80211,wext >/dev/null 2>&1 # Start wlan0
sleep 1
udhcpc -i wlan0 -q >/dev/null 2>&1 # Get an IP addr
ping -c 3 ${WLAN_GW} # Check networking
sleep 5
ifconfig ap0 192.168.1.1 netmask 255.255.255.0 up # Config AP IP addr
dnsmasq -C /etc/dnsmasq.conf # For clients
lighttpd -f /etc/lighttpd/lighttpd.conf # To test clients access
wpa_cli -g/var/run/wpa_supplicant_master interface_remove wlan0 >/dev/null 2>&1 # Delete wlan0
hostapd -B /etc/hostapd.conf >/dev/null 2>&1 # Start the AP
wpa_cli -g/var/run/wpa_supplicant_master interface_add wlan0 /etc/wpa_supplicant.wlan0.conf nl80211,wext >/dev/null 2>&1 # Start wlan0 again
sleep 5
ping -c 3 ${WLAN_GW} # Check networking
# Interfaces configs
for IF in wlan0 ap0; do for OPT in c f m p; do iwgetid -${OPT} $IF; done; done # Live interfaces configs
iw ap0 info | grep -o 'channel.*' # AP channel in actual operation
# Platform info
cat /proc/cpuinfo | grep -P '(Hardware|Revision)'
uname -a
lsb_release -a
Code: Select all
rasp# # execute as root
rasp# export WLAN_GW='172.17.0.1'
rasp# for IF in wlan0 ap0; do for OPT in c f m p; do iwgetid -${OPT} $IF; done; done # Live interfaces configs
wlan0 Mode:Managed
wlan0 Protocol Name:"IEEE 802.11"
ap0 Mode:Master
ap0 Protocol Name:"IEEE 802.11"
rasp# grep channel /etc/hostapd.conf # AP channel in config file
channel=11
rasp#
rasp# wpa_supplicant -B -g/var/run/wpa_supplicant_master -Groot # Start WPA Supplicant master process
Successfully initialized wpa_supplicant
rasp# wpa_cli -g/var/run/wpa_supplicant_master interface_add wlan0 /etc/wpa_supplicant.wlan0.conf nl80211,wext >/dev/null 2>&1 # Start wlan0
rasp# sleep 1
rasp# udhcpc -i wlan0 -q >/dev/null 2>&1 # Get an IP addr
rasp# ping -c 3 ${WLAN_GW} # Check networking
PING 172.17.0.1 (172.17.0.1) 56(84) bytes of data.
64 bytes from 172.17.0.1: icmp_seq=1 ttl=64 time=1102 ms
64 bytes from 172.17.0.1: icmp_seq=2 ttl=64 time=39.0 ms
64 bytes from 172.17.0.1: icmp_seq=3 ttl=64 time=24.0 ms
--- 172.17.0.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2064ms
rtt min/avg/max/mdev = 24.054/388.698/1102.949/505.089 ms, pipe 2
rasp# sleep 5
rasp#
rasp# ifconfig ap0 192.168.1.1 netmask 255.255.255.0 up # Config AP IP addr
rasp# dnsmasq -C /etc/dnsmasq.conf # For clients
rasp# lighttpd -f /etc/lighttpd/lighttpd.conf # To test clients access
rasp#
rasp# wpa_cli -g/var/run/wpa_supplicant_master interface_remove wlan0 >/dev/null 2>&1 # Delete wlan0
rasp# hostapd -B /etc/hostapd.conf >/dev/null 2>&1 # Start the AP
rasp# wpa_cli -g/var/run/wpa_supplicant_master interface_add wlan0 /etc/wpa_supplicant.wlan0.conf nl80211,wext >/dev/null 2>&1 # Start wlan0 again
rasp# sleep 5
rasp# ping -c 3 ${WLAN_GW} # Check networking
PING 172.17.0.1 (172.17.0.1) 56(84) bytes of data.
64 bytes from 172.17.0.1: icmp_seq=1 ttl=64 time=1088 ms
64 bytes from 172.17.0.1: icmp_seq=2 ttl=64 time=39.6 ms
64 bytes from 172.17.0.1: icmp_seq=3 ttl=64 time=8.24 ms
--- 172.17.0.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2052ms
rtt min/avg/max/mdev = 8.245/378.815/1088.566/502.033 ms, pipe 2
rasp# # Interfaces configs
rasp# for IF in wlan0 ap0; do for OPT in c f m p; do iwgetid -${OPT} $IF; done; done # Live interfaces configs
wlan0 Channel:1
wlan0 Frequency:2.412 GHz
wlan0 Mode:Managed
wlan0 Protocol Name:"IEEE 802.11"
ap0 Mode:Master
ap0 Protocol Name:"IEEE 802.11"
rasp# iw ap0 info | grep -o 'channel.*' # AP channel in actual operation
channel 1 (2412 MHz), width: 20 MHz, center1: 2412 MHz
rasp#
rasp# # Platform info
rasp# cat /proc/cpuinfo | grep -P '(Hardware|Revision)'
Hardware : BCM2835
Revision : a02082
rasp# uname -a
Linux rasp 4.14.34-v7+ #1110 SMP Mon Apr 16 15:18:51 BST 2018 armv7l GNU/Linux
rasp# lsb_release -a
No LSB modules are available.
Distributor ID: Raspbian
Description: Raspbian GNU/Linux 9.4 (stretch)
Release: 9.4
Codename: stretch
rasp#

So my question again: is there anything that can be done to improve on this?