Photo by rawpixel on Unsplash

Wifi Scanner App for Linux in C++ using Qt

László Harri Németh
The Coding Hype
Published in
6 min readApr 16, 2019

--

Last year I’ve implemented a Wifi Scanner app for Linux. The source code of this app can be accessed on my Github profile.

By creating this app I was able to learn the following concepts and technologies:

The implementation is done in C++. The present article describes the implementation details with some code snippets.

Keywords: C, C++, Wifi, Wifi Scanner, threads, mutex, mutual exclusion, file, vector, promise, Qt, RSSI, QMake

DISCLAIMER: THE VIEWS AND OPINIONS EXPRESSED IN THIS ARTICLE ARE THOSE OF THE AUTHOR AND DO NOT REFLECT THE OFFICIAL POLICY OR POSITION OF THE EMPLOYER OF THE AUTHOR. THE ARTICLE IS NOT ENDORSED BY, DIRECTLY AFFILIATED WITH, MAINTAINED, AUTHORIZED, OR SPONSORED BY ANY CORPORATION OR ORGANIZATION. THE INFORMATION CONTAINED ON THIS ARTICLE IS INTENDED SOLELY TO PROVIDE GENERAL GUIDANCE ON MATTERS OF INTEREST FOR THE PERSONAL USE OF THE READER, WHO ACCEPTS FULL RESPONSIBILITY FOR ITS USE. ALTHOUGH THE AUTHOR HAS MADE EVERY EFFORT TO ENSURE THAT THE INFORMATION IN THIS ARTICLE WAS CORRECT AT THE TIME OF THE WRITING, THE AUTHOR DOES NOT ASSUME AND HEREBY DISCLAIM ANY LIABILITY TO ANY PARTY FOR ANY LOSS, DAMAGE, OR DISRUPTION CAUSED BY ERRORS OR OMISSIONS, WHETHER SUCH ERRORS OR OMISSIONS RESULT FROM NEGLIGENCE, ACCIDENT, OR ANY OTHER CAUSE.

Table of Content

The article is divided into the following chapters:

  • Motivation
  • Required knowledge
  • Introduction
  • Building the app
  • Configuring the app
  • Running the app
  • Implementation details
  • The main() method
  • The wifiScannerThread() method
  • The WifiAPCollection class
  • The ShapedDashboard class
  • The WifiAP class
  • References

Motivation

“person using laptop computer” by rawpixel on Unsplash

During the year I spent in the university as a PhD student I had two research topics I worked on. One of them was Wi-Fi based positioning techniques for presence and location based services. I was implementing various positioning algorithms to be able to simulate their behavior and analyze their accuracy.

During this research work we have implemented an application in Java, which reads signal strengths of surrounding Wi-Fi routers and saves this information for further processing. I was interested in how to implement the reading of signal strengths in a programming language different from Java.

I like working in Linux environment, therefore I choose Linux and C++. In the meantime I found Qt as a suitable GUI widget toolkit for the visualization of signal strengths.

Required knowledge

In order to understand this article you need basic understanding of C++ programming, Qt, and Wi-Fi signal strengths. The following links can be a good starting point:

Introduction

Photo by Frank Wang on Unsplash

The Wifi Scanner App is built under Linux, and it shows a circle shaped window with the surrounding access point names. The size of the arc in the circle and the darkness of the color indicates the signal strength of the Wifi AP. The visualization was inspired by the Analog Clock example app of Qt: http://doc.qt.io/qt-5/qtwidgets-widgets-analogclock-example.html.

The app was built and tested on Ubuntu 17.10 (artful). Qt version 5.9.1, QMake version 3.1, g++ version 7.2.0 (Ubuntu 7.2.0–8ubuntu3.2).

Building the app

The build script will run qmake to generate the Makefile and the run make to build the app:

./build.sh

The qmake project file MeerkatWifiScannerLinux.pro contains the reference to be able to use libmnl which is needed to build the app.

QMAKE_CFLAGS += -lmnl
QMAKE_LIBS += -lmnl

If you don’t have libmnl in your system, try the following:

sudo apt-get update && sudo apt-get install build-essential libmnl0 libmnl-dev

The app requires Qt as well, which can be installed with:

sudo apt-get install qtcreator qt5-default qtdeclarative5-dev

Configuring the app

This script will get the default wireless adapter name and saves it to MeerkatWifiScanner.conf:

./configure.sh

(Originally I called the app “MeerkatWifiScanner”, that’s why the config file is named like this.) The Wifi Scanner app reads this config file to determine which Wireless Adapter needs to be used. This script also calls xhost to ensure that the app can be run as root.

Running the app

The Wifi Scanner app will run as root. This is needed to be able to query the list of AP’s.

./run.sh

Implementation details

The starting point of the application is main.cpp. The application needs many standard libraries, as well as the Wi-Fi scanner library.

#include <QApplication>
#include <iostream>
#include <chrono>
#include <future>
#include <mutex>
#include <vector>
#include <fstream>
#include "wifi_scan.h"
#include "shapeddashboard.h"
#include "wifiapcollection.h"
#include "wifiap.h"

We use mutex for handling the refresh of the list of Wi-Fi access points.

The list of Wi-Fi access points is read in a thread, and stored in a Vector. The method is defined before the main()method in order to be able to use it there.

std::mutex mu;void wifiScannerThread(std::future<void> futureObj, std::string WifiIfName, WifiAPCollection *wifiAPCollection);

The main() method

First the configuration file is read, to get the default Wi-Fi adapter name (the name of the Wi-Fi device in your computer), then the WifiAPCollectionobject is instantiated. This object stores the list of Wi-Fi access points. It will be described later. The WifiAPCollectionobject is used as volatile, because it is modified in a thread.

The wifiScannerThreadmethod is registered with:

After this the Qt application is initialized.

For the thread handling we need to call the setValue() method of the exitSignal promise, and we need to call th.join() method:

The visualization, the dashboard is implemented in shapeddashboard.cpp.

Themain()method looks like the following:

The wifiScannerThread() method

The list of Wi-Fi access points is read in a thread, and stored in a Vector. The refresh frequency is 3 seconds. There is also a limit introduced that the max number of APs which are processed is 6.

The documentation of the Wi-Fi Scanner library can be accessed at: https://github.com/bmegli/wifi-scan

In order to visualize the signal strengths properly, some correction needed to be implemented on the result set returned by the Wi-Fi Scanner library.

To handle the 3 seconds refresh, I used

The WifiAPCollection class

The list of APs with the signal strengths are stored in a class. This is implemented in wifiapcollection.cpp.

The ShapedDashboard class

The ShapedDashboard class is inherited from the QWidget class. It processing the signal strength data and visualized it in the widget. Also a progress indicator is implemented, because the scanning might take some time, and therefore the signal strength data is not always available.

The moving of the window is also implemented by processing the corresponding mouse events.

The full implementation looks like the following.

The WifiAP class

To handle the data of one Wi-Fi access point, also a class was implemented. It’s a simple class.

References

To be able to implement this app, several sources were used on the web. Most important sources were the website of Qt, especially the example apps, and the docs of the Wi-Fi scanner library. Of course lot of information can be found on stackoverflow and also on C++ related websites.

--

--

László Harri Németh
The Coding Hype

Software developer. Python, SQL, ABAP, Swift, Javascript, Java, C, C++, Ruby, noSQL, Bash, Linux. http://nlharri.hu http://github.nlharri.hu hello@nlharri.hu