Note: This recipe was originally posted on July/2020 and updated on July/2022.
About Wi-Fi roaming, I'd like to share my experience. I hope it will be useful to all of you.
I've been "googling" a lot about wi-fi roaming. What I wanted was a seamless switch from one AP to another one.
802.11 extensions k, v and r are supposed to help, but as 2020, not every client implements them. Android and Windows use extension r when available. It does help. I've read that iOS devices seem to take better use, but I can't confirm since I don't own one.
There were people claiming that a good solution was to disable low transfer rates. This seems to be incorrect and could lead to a worse scenario.
A really good solution is to reduce transmission power on each AP. When signal becomes very weak, clients will search for a better AP and make the switch. But only in this very weak signal situation. This is why you need to reduce transmission power. You can use an app (such has Android Wifi Analyzer) to monitor signal strength while you walk around. Adjust power as needed.
Even with all this, some clients may still get attached to a low signal (but still useful) AP and refuse to switch. To help with that, I used the wifi-disconnect-low-signal script on all APs, which disconnects clients when signal is not good, forcing them to switch AP. It works great.
Now for the recipe: First, enable extension 802.11r. If it is not available, you might need to replace the wpad package for the complete one. For 19.07 this might require a new build. Second, adjust transmission power in each AP so that you get a lower limit of -70dBm at the furthest places. Then configure wifi-disconnect-low-signal SNR limits to 35 (connect) and -30 (stay). It is important to make sure that when the scripts disconnects a client, there will be a strong AP nearby. Otherwise, the client will be disconnect again, resulting in a bad experience. "Try and error" is needed until you get a good balance. For this, open two SSH sessions on each AP: on the first session run wifi-disconnect-low-signal in verbose mode (-v -v); on the second session watch OpenWrt system log (logread -f). Then slowly walk around, while monitoring it all. This way you could watch when you get disconnected from one AP and connected to another one, verifying if it occurred at the right time/place.
I used this for 2 years with great results. I've been able to walk around and still get a stable SSH connection and a stable phone VoIP conversation.