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.
Needed information
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)
-
Signal strength
-
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.
Security/Privacy
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.