Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Smooth WiFi handover in Android

We are developing a small App for Android to smoothly switch between two different wireless access points in the same network (same SSID and same network configuration but different physical locations), with the goal of not dropping existing connections after the handover is performed. I've been reading several posts here explaining how to control the wifi programmatically, and now we have a half working solution.

The way we implemented it, the service is scanning for the AP matching our criteria with best signal, and if it's different than the one the system is currently connected to, it will switch to the new AP. The relevant part of the code:

...
// Some initializations and bestOne is the ScanResult with the best signal
conf.BSSID = bestOne.BSSID;
actualNid = mWifiManager.updateNetwork(conf);
mWifiManager.enableNetwork(actualNid, false);
mWifiManager.saveConfiguration();
conf = getWifiConfiguration(mWifiManager, conf);
if(conf == null) {
    return;
}
if(!mWifiManager.enableNetwork(conf.networkId, true)) {
    return;
}
if (mWifiManager.reconnect()) {
    // Great
} else {
    // Error
}

The problem is that all the execution goes through the expected code path. However the handover is not really performed, the logs show as the reconnect is executed, and true is returned. Moreover there are no events received from any SUPPLICANT_CONNECTION_CHANGE_ACTION, or SUPPLICANT_STATE_CHANGED_ACTION, so it seems that the handover is not even triggered.

Another fact is that if we insert a mWifiManager.disconnect() before enabling the network the handover is actually performed. Nevertheless, this is not an option as the running apps lose connectivity, thus dropping the session, which is precisely what we want to avoid.

Any suggestion is more than welcome.

like image 342
René Avatar asked Nov 13 '22 00:11

René


1 Answers

This may not be just software related problem. Usually the network adapter (wifi) is responsible for keeping track of signal levels and deciding when to roam and where to roam to. These algorithms are vendor specific and there might not be a way for you to affect them. Roaming is done by sending 802.11 reassociations frames (requests) from a client and the roaming process is done on L2 level (in your scenario). But the process might not be just that simple. Both APs should be aware if the client roamed and the switch sending frames to those AP should have that update in its CAM table. The AP from which the client is roaming from might buffer all frames destined for a client and send it to a new AP when the client reassociates resulting in no data loss. Since this is not required by 802.11 standard roaming could cause a data loss and plainly reconnecting to an AP with stronger signal would cause a drop in connection because it is not just roaming but a full disconnect and reconnect to the network.

This is probably not helping you solve your problem but I was trying to point out that this is really something that should be done on lower levels (physical, data link or transport) not on application level. Weather the roaming will be virtually seamless depends a lot of the hardware used (on both sides) and the configuration of network, and there is not much you can do to change that. The only thing that comes in mind is sending 802.11 probe requests so that the client is aware of other APs with possibly stronger signals, which you already are doing in your code, and leaving the decision to roam to a network adapter.

like image 148
pajaja Avatar answered Nov 14 '22 23:11

pajaja