Hi guys,
This is a recipe for Pi3B only (not 3B+, not 0w), to get the built-in
wlan0 interface working as a WPA2 STA and the "virtual AP" interface
working at the same time. For now I use an open AP, IIRC a WPA2 AP works
as well, I haven't tried other combinations.
It seems to work so far for me on a buildroot, 32-bit, busybox init with
ifupdown, Pi 3B (Linux rpi3 4.14.50-v7 #1 SMP Mon Oct 15 14:26:41 CEST
2018 armv7l GNU/Linux)
I'm posting this because:
- I've spent a long time trying to make STA+AP work on brcm 43430 in a
reliable and repeatable way, and according to my stress-test it seems
I've achieved that
- I suppose some here might want to test that with PcP, which is not
too different from my buildroot system, and I have a hunch the wifi
virtual AP could sustain streaming to a couple of wifi speakers.
Unfortunately I don't have time to test this recipe myself on PcP but
I think it should mostly apply and work.
I can't really answer further questions:
- I expose here the gist of my recipe and fundamentally I do not
understand why it works...
- For sure you can't expect it to work with something like Raspbian
or a systemd-based OS: dhcpcd and systemd have their way of managing
interfaces, and this changes everything.
- Along my quest I've had systems where removing/reinserting the
brcmfmac module would help getting STA+AP work, and others where doing
that just makes the OS crash...
Folks running Raspbian or a systemd OS might want to refer to 'this
excellent post'
(https://raspberrypi.stackexchange.com/questions/89803/access-point-as-wifi-repeater-optional-with-bridge)
on StackExchange. I know for a fact the author Ingo has been researching
on the question for a while, too.
Ok, now the recipe:
- Bring up the wlan0 interface with the normal wpa_supplicant daemon
(in "pre-up") and next, add a wpa_cli instance with something like
this...
Code:
--------------------
[ -f /var/run/wpastate.wlan0.pid ] || /usr/sbin/wpa_cli -B -i wlan0 -a
/usr/local/bin/hostapd_helper.sh -P /var/run/wpastate.wlan0.pid
--------------------
...having hostapd_helper.sh as this:
Code:
--------------------
#!/bin/sh
freq_to_chan(){
F="$1"
[ $F -eq 2484 ] && echo 14 && return
[ $F -lt 2484 ] && echo $(( (F-2407) / 5)) && return
echo $(( F / 5 - 1000))
}
case $2 in
"CONNECTED")
F=$(/usr/sbin/wpa_cli -i ${1} status | grep freq | cut -d '=' -f 2 | xargs)
[ -n "$F" ] && C=$(freq_to_chan ${F})
[ -n "$C" ] && echo ${F} ${C} > /var/run/network/wpastate.${1}
;;
"DISCONNECTED")
rm -f /var/run/network/wpastate.${1}
;;
esac
exit 0
--------------------
This makes wpa_supplicant report its current frequency and channel in
file /var/run/wpastate.wlan0 when it is connected. hostapd needs that
to launch the AP successfully.
- Tear wlan0 down like that (in "post-down"):
Code:
--------------------
# Use the cli to stop the backend. Our cli exits in turn
if [ -e /var/run/wpastate.wlan0.pid ]; then
/usr/sbin/wpa_cli -i wlan0 terminate
else
pkill -f "/usr/sbin/wpa_supplicant -B -i wlan0"
pkill -f "/usr/sbin/wpa_cli -B -i wlan0"
fi
rm -f /var/run/wpastate.wlan0.pid
rm -f /var/run/network/wpastate.wlan0
--------------------
- Bring up the ap0 interface this way (in "pre-up"):
Code:
--------------------
/usr/sbin/iw phy0 interface add ap0 type __ap
/usr/sbin/iw ap0 set power_save off
/sbin/ip link set ap0 address 02:96:ea:ca:ff:f4
--------------------
I suggest you set the MAC to "02:something" (see MAC addr classes and
linux bridge behaviour as to why.) power_save off really seems to make
a difference, make sure to apply it to both ap0 and wlan0.
- Tear ap0 down like that (in "post-down"):
Code:
--------------------
/usr/sbin/iw ap0 del
--------------------
- You also need a bridge interface (I called it local0), there is
nothing special about it. Recommend not shutting down STP but using a
short forward delay to speed up DHCP lease acquisition.
- You need a DHCP server listening on the bridge, as usual dnsmasq
does just fine.
- You need a hostapd config, nothing special about it. For the record
here is my open AP test config in /etc/hostapd/hostapd-ap0.conf:
Code:
--------------------
ctrl_interface=/var/run/hostapd
ctrl_interface_group=netdev
interface=ap0
bridge=local0
driver=nl80211
country_code=FR
ssid=test
wpa=0
hw_mode=g
channel=11
wmm_enabled=1
ieee80211n=1
ieee80211d=1
max_num_sta=5
logger_syslog=0
logger_stdout=0
--------------------
- The last piece of the puzzle is the start/stop hostapd script. The
stop action is simple, in essence it does:
Code:
--------------------
kill $(cat /var/run/hostapd.ap0.pid)
rm -f /tmp/hostapd-ap0.conf
ifdown ap0
ifdown local0
--------------------
- The start action is a little bit more involved...
Code:
--------------------
cp -f /etc/hostapd/hostapd-ap0.conf /tmp/hostapd-ap0.conf
# If wlan0 is active we need to know
STA_IS_UP=0
[ -s /var/run/network/wpastate.wlan0 ] && STA_IS_UP=1
if [ ${STA_IS_UP} -eq 1 ]; then
echo "wlan0 is in use, reset..."
CHAN=$(cat /var/run/network/wpastate.wlan0 | cut -d' ' -f 2)
echo "set AP channel to ${CHAN}..."
sed -e "s/channel=.*/channel=${CHAN}/" -i /tmp/hostapd-ap0.conf
ifdown wlan0
fi
echo "set AP interfaces up..."
ifup ap0
ifup local0
echo "start hostapd and bridge helper..."
/usr/sbin/hostapd -B -P /var/run/hostapd.ap0.pid /tmp/hostapd-ap0.conf
/usr/bin/hostapd_cli -B -i ap0 -a /usr/local/bin/bridge_helper.sh
if [ $STA_IS_UP -eq 1 ]; then
echo "reconfigure wlan0..."
ifup wlan0
fi
--------------------
...having bridge_helper.sh as this:
Code:
--------------------
#!/bin/sh
[ "$#" -eq 3 ] || exit 1
[ "${2}" == 'AP-STA-CONNECTED' ] && /sbin/ip link set ${1} up
exit 0
--------------------
Basically, if wpa_supplicant has engaged with the bcrmfmac driver, it
is impossible to start the AP. So we need to stop wlan0. Catch-22, the
wlan0 interface won't be able to reconnect if the virtual AP isn't
initially operating on the channel the STA needs to use to connect
with its AP. So we get the channel used by wlan0 before stopping it,
and fudge the hostapd conf with it. Then restarting wlan0 will
succeed.
Curiously, once the AP+STA couple is active, if the STA changes
channel, the AP will have no problem switching channel. There is no
need to repeatedly change hostapd.conf and restart hostapd. Only once
at startup.
By uselessly setting ap0 up each time a new client connects to the AP,
the bridge_helper script makes bridging actually work. Without it, the
AP client takes a long time obtaining an IP address over DHCP and
after that it isn't able to connect beyond the bridge itself, it
doesn't see any other MACs. This is pure magic to me, but reasserting
link up works.
That's it. Caveat emptor and good luck :)
3 SB 3 Libratone Loop, Zipp Mini iPeng (iPhone + iPad) LMS 7.9
(linux) with plugins: CD Player, WaveInput, Triode's BBC iPlayer by bpa
IRBlaster by Gwendesign (Felix) Server Power Control by Gordon
Harris Smart Mix, Music Walk With Me, What Was That Tune? by Michael
Herger PowerSave by Jason Holtzapple Song Info, Song Lyrics by
Erland Isaksson AirPlay Bridge by philippe_44 WeatherTime by Martin
Rehfeld Auto Dim Display, SaverSwitcher, ContextMenu by Peter Watkins.
------------------------------------------------------------------------
epoch1970's Profile: http://forums.slimdevices.com/member.php?userid=16711
View this thread: http://forums.slimdevices.com/showthread.php?t=109621
_______________________________________________
unix mailing list
[email protected]
http://lists.slimdevices.com/mailman/listinfo/unix