Connecting to secondary WLAN interface



  • My computer has 2 WLAN interfaces: One integrated ("Wi-Fi") and an external adapter ("Wi-Fi 2"). How can I make my Qt application establish a connection to a given access point (AP) through the second interface?

    I want to make sure that the first interface is always used to connect to the internet (my ISP router), while the second interface is used to connect to a third-party device (which is a Wi-Fi AP itself).

    The following code connects to an AP (SSID = DeviceRouter). But I don't know how to force it to use my secondary interface (Wi-Fi 2) instead.

    // My target SSID and interface (let's assume this is an open AP)
    QString ssid = "DeviceRouter";
    QString interface = "Wi-Fi 2";  // I want to use my secondary interface
    
    // Get all configurations
    QNetworkConfigurationManager mgr;
    mgr.updateConfigurations();
    waitForSignal( &mgr, SIGNAL( updateCompleted() ), 20000 ); // implemented elsewhere
    QList<QNetworkConfiguration> allConfigs = mgr.allConfigurations();
    
    // Select the configuration matching my target SSID
    bool connected = false;
    foreach( QNetworkConfiguration config, allConfigs ) {
        if( config.name() == ssid && config.bearerType == QNetworkConfiguration::BearerWLAN ) {
            QNetworkSession s( config );
            // How can I set the interface for the session?
            s.open();
            connected = s.waitForOpened( 30000 );
            if( connected ) {
                qDebug() << "You're connected on interface: " << s.interface().humanReadableName();
            }
            break;
        }
    }
    

    The above code always reports: You're connected on interface: Wi-Fi, as expected. But, how can I specify Wi-Fi 2 as my desired interface?

    Any help/hint would be greatly appreciated.


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    AFAIK, that's done on your system level and is outside of Qt's scope.

    You can select the configuration you want to use but is not meant as a system network configuration manager.



  • @NeuroSamuel from the code snippet you pasted, it looks to me that you're always only checking the first QNetworkConfiguration available, because of the break statement that exits the foreach() loop... Am I missing something?


  • Lifetime Qt Champion

    @NeuroSamuel said in Connecting to secondary WLAN interface:

    QString interface = "Wi-Fi 2";

    You define this string at the beginning of your code, but don't use it to actually check the interface. Together with the break @Pablo-J-Rogina already mentioned, you never get to interface 2.

    By the way:

    waitForSignal( &mgr, SIGNAL( updateCompleted() ), 20000 );

    connected = s.waitForOpened( 30000 );

    Unless you run this code in a thread, this already screams for problems. Don't use waitFor... in the main thread, please.

    Regards



  • Thank you guys, for your comments and hints. Really appreciated!

    @aha_1980 I'm aware of your point regarding the use of waitFor... in the main thread. This was just a sample minimal code to help explain what I want to achieve.

    @Pablo-J-Rogina and @aha_1980 You're right, the break in the foreach(...) loop will make me connect to the first interface. But, again, this is just sample code (not a very good one, though), not the real implementation. If I remove the break, nothing changes: I only get connected to one network, through the first WLAN interface. The origin of the problem here is that I would expect QNetworkConfigurationManager::allConfigurations() to return two configurations for each SSID: one for each interface. Then, I could open a QNetworkSession with the one I want. But instead, this function returns one configuration for each SSID. No way to specify the interface I want to use.

    I think @SGaist is right. Such fine manipulation of network connections is probably out of Qt's scope. So, I will go for a system-specific implementation. I will try with Native Wifi in Windows and probably Core WLAN for MacOS.


  • Qt Champions 2019

    @NeuroSamuel You don't use "interface" variable anywhere! And your if() statement simply matches the first interface and connects to that one.

    if( config.name() == ssid && config.bearerType == QNetworkConfiguration::BearerWLAN )
    

    this matches already first one I guess...

    Did you check how many elements allConfigs contains?



  • @jsulm Yes, I did check allConfigs. And it contains only one instance of each available SSID.


  • Qt Champions 2019

    @NeuroSamuel said in Connecting to secondary WLAN interface:

    And it contains only one instance of each available SSID

    So, two of them since you have two SSIDs?



  • @jsulm Yes, allConfigs contains two QNetworkConfigurations: If I inspect their name(), I see that they correspond to the SSID's of the available access points (say, HomeRouter and DeviceRouter).

    The following code:

    QList<QNetworkConfiguration> allConfigs = QNetworkConfigurationManager::allConfigurations();
    foreach( QNetworkConfiguration config, allConfigs ) {
        if( config.bearerType == QNetworkConfiguration::BearerWLAN )
            qDebug() << "*" << config.name();
    }
    

    returns:

    * HomeRouter
    * DeviceRouter
    

    My problem is that I see no way to open a QNetworkSession from one of those configurations choosing the hardware interface. I wish there was a method like

    QNetworkSession s( allConfigs[1], "Wifi 2");    //  <-- this constructor doesn't exist
    

    But QNetworkSession does not provide that functionality and I can't find any OS-independent workaround.



  • @NeuroSamuel said in Connecting to secondary WLAN interface:

    My problem is that I see no way to open a QNetworkSession from one of those configurations choosing the hardware interface.

    Is not something you (or your sysadmin) did already when configuring the networking devices for your system?
    Not that I have that much experience with QNetworkSession, but it looks that behavior to be fine, given that you are setting one WLAN interface to one SSID at OS level. Thinking of wpa_supplicant on Linux for instance:
    wpa_supplicant.conf

    network={
            ssid="home"
            scan_ssid=1
            key_mgmt=WPA-PSK
            psk="very secret passphrase"
    }
    

    and then command line:

    wpa_supplicant -iwlan0 -c/etc/wpa_supplicant.conf -d
    

    Because at the end it'll be a question of OS routing, won't it?