5

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.

René
  • 83
  • 3
  • 6
  • 2
    I don't think that this is possible to achieve from within an app. On WiFi driver level possibly but it's not even easy there: http://code.google.com/p/android/issues/detail?id=12649 (says "This is a hardware-specific feature" - so maybe not even on driver level) – zapl Jul 29 '13 at 16:18
  • Please see the answer https://stackoverflow.com/questions/37941746/android-wifi-roaming-through-ap-with-same-ssid/57161641#57161641 – Samantha Jul 23 '19 at 10:54

1 Answers1

1

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.

pajaja
  • 2,164
  • 4
  • 25
  • 33
  • I see, if it is a hardware limitation then not much can be done. However I was wondering, even with this disconnect/connect cycle whether there is a way to avoid the OS dropping existing connections. We have a remote display which times out and totally drops the connection when switching, and we are looking for some workaround, not involving fully reconnection of the app if possible. – René Jul 29 '13 at 22:08
  • If you can it's better to focus on how to maintain in-app connectivity even if the network connection is unstable. This is a likely scenario for wifi and beside that even if you roam to another AP, depending on HW and network implementation you can get connection interruptions that can last for several seconds even if the roaming process lasts less than 0.1s. Some routers/FWs can also send you a TCP/IP RST (resetting your connection) if your app is idle for some time. You should have some control in the app to handle those kinds of problems because unfortunately you can't eliminate them all. – pajaja Jul 30 '13 at 07:24
  • This can be tricky for realtime applications and there can possibly be more serious drawbacks when disconnecting/connecting to another AP instead of roaming. For example, other than completely resetting TCP connection DHCP can issue you another IP address which, depending on how you implemented authentication, can lead to more work for you in order to quickly establish a connection again. Sorry I can't be of more help to you. I'm no expert in Android so there can be already some built-in mechanisms that can do (or help you do) this but it is very unlikely that it can be avoided altogether. – pajaja Jul 30 '13 at 07:24
  • 1
    @René You could hide disconnects for one side by using a proxy that keeps the connection in one direction. Either stationary in the local network that keeps the connection towards the display and allows reconnection towards the app or locally on the phone but that would only move the problem to deal with disconnects from app to proxy implementation and I guess you'd have to do both. – zapl Aug 01 '13 at 17:49
  • Thanks for the comment. We thought about that but at the end, as you point out is only moving the problem one step. We'll implement reconnection mechanisms at application level, is a suboptimal solution but seems the only one. – René Aug 01 '13 at 21:34