Jan 6, 2016

Device Discovery in Wifi Networks

To use a baby monitor two smartphones have to connect. They have to find and see each other in the network, one device needs to discover another device automatically without much user interaction.

There was an IT world before the smartphone entered our lifes. So all the nuts and bolts are already available: to discover devices in a network you simply send a UDP broadcast message into the wifi network and listen for such messages on each device. This is the textbook approach which only took a few minutes of coding to build. Then the details of Android-reality bit me.

Does your babysitter talk "IP MULTICAST"?
In order to work with UDP broadcast Messages an Android application needs to have the permission CHANGE_WIFI_MULTICAST_STATE. Appearently, that is a safety measure in Google's thinking. However, I wonder which typical user actually understands whether an app should be allowed multicasts? Do your babysitter and your grandma understand what this is? Mine don't - but well, who cares, this permission is easily added to the application.

    Persmission CHANGE_WIFI_MULTICAST_STATE
    Allows applications to enter Wi-Fi Multicast mode.

From now on, when grandma does the babysitting with the app, I'll just tell her IP-multicasting is a good thing... sure she will understand.

Some devices just kill broadcasts but won't tell you
Android provides features and functions to manage IP-multicasting. Ultimately, this is to save battery life and avoid excessive use of multicasting which is a battery burner. You can switch multicasting on and off to cover only specific moments when you really need it. However, some manufacturers/devices simly ignore this without notice. Reason unknown, they just won't do UDP discovery. Go figure... The worst part of it is that there is no way for a developer to get feedback from the device, nothing like a reliable active/inactive status for multicasting.

To make device discovery working also for such non-multicast devices another discovery technique must be in place. The obvious choice is to use a TCP scan: check the whole subnet and ask each possible IP address if there is a baby monitor available. The major drawback of this is obvious - it can be a long running process for large Wifi networks in hotels and company buildings.

No netmask? An Android bug.
When building a TCP scan I noticed that on one of my devices, a new Moto G, the scan went on for very, very long. Other devices did well, though. After a lengthy tracing and log search analysis it turned out that Android 5 has a significant bug: it won't give your app the current Wifi netmask - it'll simply return zero which can lead to unpredictable behaviour. To Google this is a known issue (issue 82477). By now Google's bug database contains a good workaround. It is difficult to understand how such a fundamental flaw can make it into a consumer grade operating system.

Summary: while device discovery is easy in the textbooks, the reality in the fragmented Android device and version space makes it a challenging task using a combination of UDP broadcast, TCP scan and working around Android bugs.