friedrith / node-wifi

📶 NodeJS tool to manage wifi (connections, scans)
MIT License
396 stars 160 forks source link

Windows: getCurrentConnections returns null when multiple interfaces exist #110

Open jimba81 opened 4 years ago

jimba81 commented 4 years ago

When there are multiple wifi interfaces exist in Windows environment and if the first one is disconnected, the getCurrentConnections() returns null.

Expected Behavior

The getCurrentConnections() should return connected connections from any interfaces

Current Behavior

When there are multiple wifi interfaces exist in Windows environment and if the first one is disconnected, the getCurrentConnections() returns null.

Affected features

Possible Solution

I have confirmed working after modified the windows-current-connections.js by following:

function parseShowInterfaces(stdout) {
...
    for (var j = 0; j < fields.length; j++) {
      var line = lines[i + j];
//=====  MY CHANGE START
 // tmpConnection[fields[j]] = line.match(/.*: (.*)/)[1];
      const lineMatch = line.match(/.*: (.*)/);
      if (lineMatch == null) { 
        // bad line, skip current interface and move to next one
        i += j + 1;
        j = -1;
      } else {
        tmpConnection[fields[j]] = lineMatch[1];
      }
//=====  MY CHANGE END
...
}

Steps to Reproduce (for bugs)

  1. Prepare environment with two wifi interfaces
  2. Only connect wifi from second wifi interfaces. I.e. second means whatever it appears in second from 'netsh wlan show interfaces'
  3. Run wifi-node.getCurrentConnections()
  4. Check the output.

Context

Your Environment

jimba81 commented 4 years ago

I had to modify little to so the function can finish nicely:

function parseShowInterfaces(stdout) {
...
    for (var j = 0; j < fields.length; j++) {
      var line = lines[i + j];
//=====  MY CHANGE START
      // tmpConnection[fields[j]] = line.match(/.*: (.*)/)[1];
      const lineMatch = line.match(/.*: (.*)/);
      if (lineMatch == null) { 
        // bad line, skip current interface and move to next one
        i += j + 1;
        j = -1;
        if (i >= lines.length) {
          tmpConnection = {};
          break;
        }
      } else {
        tmpConnection[fields[j]] = lineMatch[1];
      }
//=====  MY CHANGE END
...
}
juanmartin commented 2 years ago

Hi! In my case I'm getting an empty array on Windows. Happens on multiple systems, both W10 and W11. I also tried disabling all other interfaces, but the problem persists. Any ideas on why this could be happening @friedrith ? Thx

friedrith commented 2 years ago

Can you try to type the following command in your terminal and print the result here?

netsh wlan show interfaces

Remember to slightly modify the ssid and bssid please.

juanmartin commented 2 years ago
❯ netsh wlan show interfaces

There is 1 interface on the system:

    Name                   : Wi-Fi
    Description            : TP-Link Wireless USB Adapter
    GUID                   : 21b1df15-2701-41a0-a09e-47a825cea287
    Physical address       : 50:3e:aa:e5:98:3c
    Interface type         : Primary
    State                  : connected
    SSID                   : XXXX-BXA2
    BSSID                  : xx:18:xx:69:xx:a2
    Network type           : Infrastructure
    Radio type             : 802.11n
    Authentication         : Open
    Cipher                 : None
    Connection mode        : Profile
    Band                   : 2.4 GHz
    Channel                : 11
    Receive rate (Mbps)    : 144.4
    Transmit rate (Mbps)   : 144.4
    Signal                 : 100%
    Profile                : XXXX-BXA2

    Hosted network status  : Not available
friedrith commented 2 years ago

Ok I will try to propose a fix

juanmartin commented 2 years ago

I think I figured the problem. Turns out the computer needs some time to connect and I was checking the currentConnections immediately, thus getting an empty array. I put the getCurrentConnections() call inside of a setTimeout() in the .connect() callback and voilà!

friedrith commented 2 years ago

I am glad you found a workaround. Unfortunately, windows use async commands so you don't know exactly when the job will be finished.