2

There must be a way to read the list of available WiFi SSIDs using Qt?

Attempted:

QNetworkConfigurationManager nwkMgr;
// UPDATE:
// Need to call nwkMgr.updateConfigurations() here

// UPDATE this code needs to run in the slot for QNetworkManager::updateCompleted signal
QList<QNetworkConfiguration> nwkCnfList = nwkMgr.allConfigurations();
for(const QNetworkConfiguration &ncnf : nwkCnfList)
{
    qDebug() << ncnf.name() << ncnf.bearerType();
    if (ncnf.bearerType() == QNetworkConfiguration::BearerWLAN)
    {
       // would like to detect WiFi here
       qDebug() << "WiFi:" << ncnf.name();
    }
}

The environment is Qt 5.7 and OS X El Capitan 10.11.6. The output is:

"en1" 0
"en5" 0
"en2" 0
"bridge0" 0
"p2p0" 0
"awdl0" 0
"gif0" 0
"stf0" 0
"en0" 0
"fw0" 0

UPDATE: The result above with interfaces instead of SSIDs is for the first run of the code sample. I've added the Refresh button for my cross-platform app and attempted to do the 'refresh' on Mac as well and the second run several seconds after app start up shows interfaces followed by SSIDs of all the networks available. That must be some Qt bug (?) which I intend to report.

But the same code above on both Windows and Linux Ubuntu outputs real SSIDs and finds WiFi. The desired (but I want all not only 'preferred') list of WiFi networks can be obtained from command line:

bash-3.2$ networksetup -listpreferredwirelessnetworks en0
Preferred networks on en0:
WiFi-N1
WiFi-N2
WiFi-N3
....
WiFi-NN

I also read on calling airport program from command line to get all WiFi networks and there is a long path to the framework binary directory which I don't want to hardcode.

Please suggest how to deal with it. The worst case ia to deal with MacOS API (in C++) here and it is also acceptable. The goal is to having read SSIDs let the user to open one WiFi connection with Qt and the initiate some 'exchange' via it. If the password needs to be provided we can even deal with 'preferred' pre-set connection but that'd be better to handle it programmatically as well.

Community
  • 1
  • 1
Alexander V
  • 8,351
  • 4
  • 38
  • 47

2 Answers2

2

It is likely that the bug scope is: Qt 5.7 and OS X El Capitan 10.11.6 because of quite a few reports that similar code should just work.

UPDATE: The result above with interfaces instead of SSIDs is for the first run of the code sample. I've added the Refresh button for my cross-platform app and attempted to do the 'refresh' on Mac as well and the second run several seconds after the app starts up shows interfaces followed by SSIDs of all the networks available. That must be some Qt bug (?) which I intend to report.

Basically, something is preventing the process or the Qt framework on OSX from reporting SSIDs immediately after start up and it takes several seconds to enable the functionality. And the other inconsistency with other platforms is that interfaces reported as SSIDs.

UPDATE2:

Mind QNetworkConfigurationManager::updateConfigurations call. Only to reply to that we can read actual SSID list.

Alexander V
  • 8,351
  • 4
  • 38
  • 47
1

Read SSID using command line arguments in Windows

This will show the profiles the current profile is the connection

Netsh wlan show profiles

Other example: SSID is the current connected Wi-Fi.

Netsh WLAN show interfaces

in Linux with QProcess for running the commands

    QProcess process;
    QStringList arguments;
    QString stdout;
    process.start("ifconfig wlan0 up");
    process.waitForFinished(-1);
    arguments << "-c" << "iw dev wlan0 scan | grep SSID";
    process.start("sh" ,arguments);
    process.waitForFinished();

OR

Using Qt convention way using connect();

process = new QProcess(this);  // create on the heap, so it doesn't go out of scope
    connect (process, SIGNAL(readyReadStandardOutput()), this, SLOT(readData()));  // connect process signals with your code
    process->start("netsh WLAN show interfaces");  // start the process


void readData()
{
    QTextStream StdoutStream(process->readAllStandardOutput());
    QString line;
    QString profileStr;

    do {
        line = StdoutStream.readLine();
        if ( line.contains("SSID")) // if ( line.contains("Profile"))
        {
            profileStr =  line;
            process->close();
            break;
        }
    } while (!line.isNull());

}
Greenonline
  • 1,330
  • 8
  • 23
  • 31
  • Please explain also your answer. Code without any explanation is consider a proper SO answer (from review). – FrankS101 Nov 12 '18 at 13:17
  • Here we have read the SSID of the connected wifi from the output of the command line arguments(netsh WLAN show interfaces) . Here the command is executed using QProcess. And read the standard output after the SIGNAL readyReadStandardOutput(); This is one way we can fetch the SSID for the connected wifi. But not sure its how much effectively. – Neelamani Padhy Nov 13 '18 at 12:39