AnimaDock
You need three things: the systemd services, the 5 GHz bridge, and the tablet-side NBD server for optional NAS storage.
git clone https://github.com/animaios/animadock
cd animadockTwo kernel/firmware gremlins. Fix once, forget forever:
sudo iw reg set US # clears NO-IR lock on 5 GHz channel 36sudo tee /etc/NetworkManager/conf.d/wifi-powersave.conf << 'EOF'
[connection]
wifi.powersave=2
EOFPersist the regdomain across reboots via /etc/rc.local or a oneshot unit:
/usr/bin/iw reg set US
mkdir -p ~/.config/systemd/user/
cp android-audio.service android-net.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now android-net.service android-audio.serviceExecStart= inside android-net.service must point to your local clone. Verify:
grep ExecStart ~/.config/systemd/user/android-net.servicesystemctl --user status android-net.service
# Main PID should be hostapd, with dnsmasq as a child
iw dev wlan0 info
# type AP, channel 36 (5180 MHz), width: 40 MHzConnect your tablet to Direct_Tablet_Bridge (password bkguxnjx1). Internet flows at ~360 Mbps; the tablet gets a 192.168.60.x address from the host's dnsmasq.
The bridge can mount the tablet's free storage as /nas over NBD. Good for logs, bulk archive, and anything that doesn't need sub-millisecond latency.
See NAS.md for the full procedure (Termux qemu-nbd, host nbd-client, ext4 format, /etc/fstab, auto-mount).
┌────────────────────────────────────────────────────────────────────┐
│ Tablet (Android 12, HarmonyOS) │
│ │
│ ┌──────────┐ USB 2.0 ┌──────────────────┐ │
│ │ audio in │◄────────────────│ scrcpy (on host) │ │
│ │ charging │◄────────────────│ │ │
│ │ MTP disk │◄────────────────│ │ │
│ └──────────┘ └──────────────────┘ │
│ │
│ ┌──────────────────────┐ 5 GHz, ~360 Mbps │
│ │ internet (NAT) │◄──────────────────────┐ │
│ └──────────────────────┘ │ │
│ │ │
│ ┌──────────────────────────────────────────────┼── NBD 10809 ─┐│
│ │ Termux: qemu-nbd serving nas.img │ TCP ││
│ └──────────────────────────────────────────────┘ ││
└─────────────────────────────────────────────────────────────────┘│
│
┌─────────────────────────────────────────────────────────────┘
│
┌────┴───────────────────────────────────────────────────────────────┐
│ Linux host │
│ │
│ android-net.service │
│ └─ start-5g-bridge.sh │
│ ├─ iw reg set US (clear NO-IR) │
│ ├─ rfkill unblock wifi (clear soft-block) │
│ ├─ nmcli device managed no (drop NM ownership) │
│ ├─ hostapd 5 GHz AP, channel 36 │
│ └─ dnsmasq DHCP .10–.50 │
│ │
│ android-audio.service │
│ └─ scrcpy -d --no-video --no-window (USB audio only) │
│ │
│ Optional: /nas via NBD (see NAS.md) │
└──────────────────────────────────────────────────────────────────┘
| Medium | Carries |
|---|---|
| USB 2.0 (480 Mbps) | Continuous charge, MTP file transfers, scrcpy audio forced with -d |
| 5 GHz Wi-Fi | Internet to the tablet, NBD block device for optional NAS |
| File | Purpose |
|---|---|
start-5g-bridge.sh |
Bridge init: rfkill, NM detach, hostapd foreground, dnsmasq, NBD |
hostapd-5g.conf |
5 GHz AP config — channel 36, WPA2, HT40+ |
dnsmasq-tablet.conf |
DHCP server bound to wlan0, subnet 192.168.60.0/24 |
android-audio.service |
systemd user unit: scrcpy USB audio |
android-net.service |
systemd user unit: 5 GHz bridge daemon |
| NAS.md | Optional NAS: mount tablet storage as /nas via NBD |
interface=wlan0
driver=nl80211
ssid=Direct_Tablet_Bridge
hw_mode=a # 5 GHz
channel=36 # 5180 MHz — DFS-free once reg US is set
ieee80211n=1 # HT
ieee80211ac=1 # VHT
ht_capab=[HT40+] # 40 MHz channel (80 MHz crashes rtw89/iwlwifi firmware)
wpa=2
wpa_passphrase=bkguxnjx1
wpa_key_mgmt=WPA-PSK
wpa_pairwise=CCMP
rsn_pairwise=CCMP
No vht_oper_chwidth — that option segfaults rtw89_8852ce and iwlwifi firmware. 40 MHz is the stable sweet spot.
interface=wlan0
bind-interfaces
dhcp-range=192.168.60.10,192.168.60.50,255.255.255.0,12h
| Step | Action | Why |
|---|---|---|
[1/5] |
Kill stale wpa_supplicant, dnsmasq, hostapd, nbd-client |
Prevent ghosts from previous runs |
[2/5] |
iw reg set US → rfkill unblock → nmcli managed no → wlan0 down/up |
Clear regulatory lock, soft-block, and NM ownership |
[3/5] |
ip addr 192.168.60.1/24 → dnsmasq -C |
Bring up the subnet and DHCP |
[4/5] |
(nbd-client, mkfs.ext4, mount /nas) & |
Non-blocking: tablet offline won't hang the script |
[5/5] |
exec sudo hostapd … |
Replace the script process — systemd owns hostapd as Main PID |
exec is mandatory. Without it, systemd tracks the wrapping shell; the shell exits, cgroup cleanup kills hostapd, and the AP dies silently.
[Unit]
Description=Android 5GHz Wi-Fi Bridge Daemon
After=network.target
[Service]
Type=simple
ExecStart=/home/YOUR_USER/animadock/start-5g-bridge.sh
Restart=always
RestartSec=5s
KillMode=process
[Install]
WantedBy=default.targetType=simple + exec hostapd = the service's Main PID is hostapd.
KillMode=process = on restart, systemd only kills the Main PID, not the dnsmasq child.
[Unit]
Description=Stream Android Audio via USB Cable
After=sound.target
[Service]
Type=simple
ExecStart=/usr/bin/scrcpy -d --no-video --no-window
Restart=always
RestartSec=4s
[Install]
WantedBy=default.targetThe -d flag forces scrcpy to grab the USB device, not any TCP interface.
Channel is regulatory-locked.
sudo iw reg set USVerify: iw list | grep -A5 "5180" after — should show no no IR.
sudo rfkill unblock wifiServer-side export name is missing or mismatched.
On the tablet:
qemu-nbd -t -b <bridge-IP> -p 10809 -f raw -x nas ~/nas.img &The -x nas flag must match the host's -N nas.
ExecStart= path is wrong.
systemctl --user daemon-reload
systemctl --user restart android-net.serviceYou're on 2.4 GHz. Force the tablet onto 5 GHz in Wi-Fi settings, or verify with iw dev wlan0 info. 2.4 GHz caps at ~144 Mbps; 5 GHz runs ~320–360 Mbps.
sudo nmcli device set wlan0 managed no
sudo ip link set wlan0 down && sudo ip link set wlan0 up# Live logs
journalctl --user -u android-net.service -u android-audio.service -f
# AP status
iw dev wlan0 info
hostapd_cli -i wlan0 status
# DHCP leases
cat /var/lib/misc/dnsmasq.leases
# NAS mount
sudo mount /nas
sudo umount /nas
# Stop the dock
systemctl --user stop android-audio.service android-net.serviceunLICENSE — see LICENSE.