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 unix@lists.slimdevices.com http://lists.slimdevices.com/mailman/listinfo/unix