Extending the Ubuntu Touch connectivity-api for WiFi scanning
One of the Ubuntu Touch apps I’m currently developing is a WiFi scanner. I think a platform should support this kind of application because many users need the functionality to debug and optimize their setups, and a mobile device has the perfect form factor if you’re walking around trying to find out how strong the signal is at a given location and/or which frequency band and channel to use. Some WiFi scanners hit the 50 million downloads mark in the Android App Store. I think a WiFi scanner written in Qt/QML and using the connectivity-api is not only useful on the phone, but also the desktop, since there is currently no user-friendly Linux GUI app available for this purpose.
Exposing information about detected WiFi networks through the connectivity-api would not only benefit WiFi scanner apps, but also enable location-based services.
As stated in my original article, the minimum amount of information needed is:
A list of all broadcasting stations (BSS/IBSS) in range
Broadcast station MAC address
SSID (may be emtpy)
Center frequency or channel (the one can be converted into the other)
Available authentication and encryption schemes
Timestamp when the station was last seen
This is basically the same information as encapsulated in an android.net.wifi.ScanResult object on Android or exposed via D-Bus by NetworkManager.
Optional, but “nice to have” information would be:
The contents of the “Capability Info” field of the beacon frame.
Supported data rates, so one can distinguish between 802.11b/g/n/ac networks. This information is encoded in the “Rates” and “Supported MCS Set” fields of the beacon frame.
The contents of the “HT Capability Info” field (if present) of the beacon frame.
This optional information is already recorded by the kernel and is e.g. decoded/displayed by a call to
iw dev wlan0 scan.
API calls and features
Since the network management service has to monitor its surroundings anyways, e.g. to detect and connect to an already known network or to switch to a better access point during movement, the information should be readily available. A single
scanResults() call returning a list of broadcast station objects should therefore already be enough.
I propose the following additional API features:
A method to register a callback function which is called after every successful scan. This frees the application from polling the API, may save power and the app can process new information instantly.
A method to set the scan interval within a pre-defined range. The network management service may decide to adapt its scan interval to the current situation to save power, e.g. a longer interval when not currently connected and a short one when connected. A scanner app may require a short, constant interval.
A hostile app may calculate the location of a user from the list of access points in range, and because of the short-range nature of WiFi this location will be quite accurate. I therefore propose that the first call to
scanResults() triggers a system popup informing the user about possible privacy implications and asking for permission.
The corresponding Launchpad bug report is 1415098. As always you can find me on the FreeNode IRC.