AP+STA Single-Channel Concurrency
tests for wi fi as access point + station single channel concurrency (ap+sta scc) running hotspot (ap) and client (sta) modes simultaneously on the same band and channel test sequence repeat on each band (2 4 ghz, 5 ghz, 6 ghz) bring up an access point and connect to an external access point as a client, both on the same channel confirm both interfaces stay associated simultaneously measure throughput on each interface with iperf3 โ
test log ap+sta same channel (scc) tested and recorded using build 1350 at 23 jun 2026 5 ghz ap 5 ghz sta environment debian trixie; made sure that networkmanager , iw and dnsmasq are present in the system set regulatory domain if not set sudo iw reg set hk run to see your wi fi card name nmcli device status | grep wifi in our case it is called wlxb06b11673af2 device type state connection lo loopback connected (externally) lo wlxb06b11673af2 wifi disconnected the ap will live on a second virtual interface named ap0 on the same phy, because one netdev can't be sta and ap simultaneously udev will try to rename a freshly created ap0 to a wlx predictable name, which breaks the nm profile binding pin the name with a link file sudo tee /etc/systemd/network/10 ap0 link >/dev/null <<'eof' \[match] originalname=ap0 \[link] name=ap0 eof apply it sudo udevadm control reload create a lan bridge (nat + dhcp) change 192 168 50 1/24 if it overlaps the upstream ap subnet these two subnets must differ; otherwise, routing collapses sudo nmcli connection add type bridge con name br lan ifname br lan \\ ipv4 method shared ipv4 addresses 192 168 50 1/24 \\ ipv6 method ignore \\ connection autoconnect yes bring it up sudo nmcli connection up br lan verify that the bridge is nm owned (not "externally" managed) nmcli f general state device show br lan # must not say 'externally' ip addr show br lan | grep inet # expect 192 168 50 1/24 pgrep a dnsmasq # expect one bound to br lan in our case $ nmcli f general state device show br lan general state 100 (connected) $ ip addr show br lan | grep inet inet 192 168 50 1/24 brd 192 168 50 255 scope global noprefixroute br lan $ pgrep a dnsmasq 11182 /usr/sbin/dnsmasq conf file=/dev/null no hosts keep in foreground bind interfaces except interface=lo clear on reload strict order listen address=192 168 50 1 dhcp range=192 168 50 10,192 168 50 254,3600 dhcp leasefile=/var/lib/networkmanager/dnsmasq br lan leases pid file=/run/nm dnsmasq br lan pid conf dir=/etc/networkmanager/dnsmasq shared d create an sta uplink replace wlan0 , yourhomewifi , and upstream password with your values sudo nmcli connection add type wifi con name sta uplink ifname wlan0 \\ ssid yourhomewifi \\ wifi sec key mgmt wpa psk wifi sec psk 'upstream password' \\ ipv4 method auto ipv6 method ignore \\ connection autoconnect yes bring it up sudo nmcli connection up sta uplink verify (change wlan0 here first) iw dev wlan0 info we got this output iw dev "wlxb06b11673af2" info interface wlxb06b11673af2 	ifindex 5 	wdev 0x1 	addr b0 6b 11 67 3a\ f2 	type managed 	wiphy 0 	channel 36 (5180 mhz), width 80 mhz, center1 5210 mhz 	txpower 3 00 dbm 	multicast txq 	 qsz byt qsz pkt flows drops marks overlmt hashcol tx bytes tx packets 	 0 0 0 0 0 0 0 0 0 create an ap profile sudo nmcli connection add type wifi con name ap downlink ifname ap0 \\ ssid flipperone \\ wifi sec key mgmt wpa psk wifi sec psk 'flipperone' \\ 802 11 wireless mode ap \\ 802 11 wireless powersave 2 \\ master br lan slave type bridge \\ connection autoconnect no bring up helper this is the piece that makes scc work it brings the sta up first (so it owns the channel context), reads the sta's channel/width, creates ap0 with a stable mac set atomically at creation, pins the ap chandef to the sta, and activates the ap first, write an /apsta up script sudo tee /apsta up >/dev/null <<'eof' \#!/bin/sh \# bring up an scc ap on ap0 locked to the sta's current channel set eu sta con=sta uplink ap con=ap downlink ap if=ap0 \# 1 resolve the base wifi device (first real wifi; never p2p dev, never ap0) sta=$(nmcli t f device,type device status \\ \| awk f v ap="$ap if" '$2=="wifi" && $1!=ap {print $1; exit}') \[ n "$sta" ] || { echo "apsta no wifi device found" >&2; exit 1; } \# 2 ensure uplink is up; wait for association (channel context owner) nmcli connection up "$sta con" >/dev/null 2>&1 || true i=0 while ; do ch=$(iw dev "$sta" info 2>/dev/null | awk '/channel/{print $2}') \[ n "${ch }" ] && break i=$((i+1)); \[ "$i" ge 30 ] && { echo "apsta sta not associated after 30s" >&2; exit 1; } sleep 1 done wmhz=$(iw dev "$sta" info | sed n 's/ width \\(\[0 9] \\) /\1/p') \[ "$ch" le 14 ] && band=bg || band=a \# 3 stable locally administered mac for the ap vif (distinct from sta on same phy) phy=$(iw dev "$sta" info | awk '/wiphy/{print "phy"$2}') mac=$(cat /sys/class/net/"$sta"/address) apmac="02 ${mac# }" \# 4 (re)create ap0 with the mac set atomically at creation iw dev "$ap if" del 2>/dev/null || true iw phy "$phy" interface add "$ap if" type ap addr "$apmac" \# 5 pin ap chandef to the sta (scc) and force the stable mac (disables randomization) nmcli connection modify "$ap con" \\ 802 11 wireless band "$band" \\ 802 11 wireless channel "$ch" \\ 802 11 wireless cloned mac address "$apmac" \# channel width only exists on nm >= 1 50; ignore failure on older releases nmcli connection modify "$ap con" 802 11 wireless channel width "${wmhz 20}" 2>/dev/null || true \# 6 activate nmcli connection up "$ap con" echo "apsta $ap if up band=$band ch=$ch width=${wmhz 20} mac=$apmac (matched to $sta)" eof set script permissions sudo chmod +x /apsta up run the script sudo /apsta up example output $ sudo /apsta up \<skipped> connection successfully activated (d bus active path /org/freedesktop/networkmanager/activeconnection/9) apsta ap0 up band=a ch=36 width=80 mac=xx\ xx\ xx\ xx\ xx\ xx (matched to wlxb06b11673af2) check network connectivity ping flipper net connect to your freshly created ssid flipperone with your phone/laptop and check the network connectivity
Have a question?
Our support team and an awesome community will get you an answer in a flash. Please leave your questions in English.
To ask a question or participate in discussions, you'll need to authenticate first.