I've been tinkering with a couple of additions to the app this week. Many people use pings to test connectivity from mobile devices. As with most projects on Android, this comes with its tradeoffs...
- What to ping to? If we take the generic meaning of ping, rather than the specific function, we want to bounce a packet off something on the wired side of the AP (or even the AP itself) and see if we get a response within a reasonable time. It's good to have it at the IP layer, I think, so we need an IP address, and the easiest one to grab is the default gateway. I'm guessing this is usually a box that's not far from the mobility controller, and the controller is well-connected to the AP: because we want to get an idea of how good the WLAN is, not the wired network. And this default gateway IP address is easy to obtain from the Android Wi-Fi API, so you won't have to configure it separately.
- How to 'ping'? Being Android, there's no embedded ping function. I found three ways to do it.
i. InetAddress.isReachable(timeout) returns a boolean, success if a response was received before the timeout. This is a useful method because it won't hang if there's no response, but it reputedly doesn't actually use ICMP, rather it sends a TCP packet to the echo port 7. I haven't verified this with my sniffer yet. Also, I routinely get results that bounce around anywhere up to 100msec. Probably due to delays in the interior plumbing of Android rather than the very pristine Aruba WLAN I'm testing on, but I need to do some more investigation. By timestamping before and after the function I can get some idea of how long it took.
ii. Runtime.getRuntime().exec("ping -c 1 IPaddr") and iii. ProcessBuilder().command("/system/bin/ping"...) methods, which are probably identical if one digs deeper into Android. With these one can invoke a Linux ping function and I used the syntax to set up for single ping operation because that saves some concurrency and keeps the coding simple. Both methods work, but again the results fluctuate wildly in the 5 - 100msec range.
It was very difficult to compare the different methods for accuracy, but I coded them all up and picked the InetAddress.isReachable() option with timestamping for now.
- How often to ping? I'd like to be able to bound outages to a granularity of ~10msec. Can't get that accurate, but 500msec is achievable and it can probably be shaved down from there once the feature is tuned. Since many of the handover outages are multi-second (due to the client not looking for other APs very often and getting caught with its pants down when its signal drops), even 500msec gives some idea of what's going on.
- Now for how to display the information. Here are some screenshots:
The pings are represented by the green bar line near the top. Higher bars mean faster pings - is that counter-intuitive? Where a ping was transmitted but no ack received (failure in isReachable() terms) I print a hollow red rectangle. Where no ping was sent (the previous one took more than its 500msec or the Wifi interface lost its connection (I think that prevents me reading the default gateway address) there's nothing on the chart.
That's where we are today. I'm struggling with whether to present the round-trip time - the figures are all over the place and I'm quite sure it's not because of the Wi-Fi layer - or make it a boolean pass/fail.
What does the great Aruba public think?
Useful or not?
Better ways of displaying the information?
I'll be working on it next week.
Best,
Antar