How to Get Rssi Value of WlanGetNetworkBssList Function Return Value

1.8k views Asked by At

Windows's WlanAPi has a function which is WlanGetNetworkBssList.This function return a variable which type is PWLAN_AVAILABLE_NETWORK. How to get rssi value of PWLAN_AVAILABLE_NETWORK rssi value using windows wlan api ?

1

There are 1 answers

0
MikeF On

These structure definitions and constructors work in my code works from WlanGetAvailableNetworkList it is incomplete and does not completely parse the structure, but it does get RSSI.

[StructLayout(LayoutKind.Sequential)]
    public struct WLAN_AVAILABLE_NETWORKS_LIST
    {
        public UInt32 NumberOfNetworks;
        //Current Not used by Native System, can be used to indicate desired network
        public UInt32 CurrentNetwork;

        //one per network found
        public WLAN_AVAILABLE_NETWORK[] Available_Network;

        //input for constructor
        private   IntPtr p;
        public    WLAN_AVAILABLE_NETWORKS_LIST(IntPtr _p)
            {
                IntPtr pn = new IntPtr();
                // TODO: Complete member initialization
                 this.p = _p;
                 this.NumberOfNetworks = (UInt32)Marshal.ReadInt32(p);
                 this.CurrentNetwork = (UInt32)Marshal.ReadInt32(p, 4);
                 this.Available_Network = new WLAN_AVAILABLE_NETWORK[NumberOfNetworks];
                 for (int i = 0; i < NumberOfNetworks; i++)
                 {
                     pn = (IntPtr)(p.ToInt32() + 8 + (628 * i));
                     //Available_Network[i] = (WLAN_AVAILABLE_NETWORK)Marshal.PtrToStructure(pn, typeof(WLAN_AVAILABLE_NETWORK));
                     Available_Network[i].strProfileName = Marshal.PtrToStringUni(pn);
                     Available_Network[i].SSID = new dot11_SSID(new IntPtr(pn.ToInt32() + 512));
                     Available_Network[i].dot11BssType = (DOT11_BSS_TYPE)Marshal.ReadInt32(pn, 512 + 36);
                     Available_Network[i].uNumberOfBssids = (UInt32)Marshal.ReadInt32(pn, 512+36+4);
                     Available_Network[i].wlanSignalQuality = (UInt32)Marshal.ReadInt32(pn, 512 + 36 + 5*4+32+4);
                 }
            }          
    }

Structure for WLAN_AVAILABLE_NETWORK

            [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct WLAN_AVAILABLE_NETWORK //size = 628
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
        public string strProfileName;//size 512
        public dot11_SSID SSID;//size 36
        public DOT11_BSS_TYPE dot11BssType; // size 4
        public UInt32 uNumberOfBssids; // 4
        //public bool bNetworkConnectable; // 4
        //public UInt32 wlanNotConnectableReason; // 4
        //public UInt32 uNumberOfPhyTypes; // 4
        ////public DOT11_PHY_TYPE[] dot11PhyTypes; // max is 8, size is 8*4 = 32
        //public UInt32[] dot11PhyTypes; // max is 8, size is 8*4 = 32
        //public bool bMorePhyTypes;// 4
        public UInt32 wlanSignalQuality; //  size 4
                    //A percentage value that represents the signal quality of the network. WLAN_SIGNAL_QUALITY is of type ULONG. This member contains a value between 0 and 100. A value of 0 implies an actual RSSI signal strength of -100 dbm. A value of 100 implies an actual RSSI signal strength of -50 dbm. You can calculate the RSSI signal strength value for wlanSignalQuality values between 1 and 99 using linear interpolation.
        //public bool bSecurityEnabled;// 4
        ////public DOT11_AUTH_ALGORITHM dot11DefaultAuthAlgorithm;// 4
        ////public DOT11_CIPHER_ALGORITHM dot11DefaultCipherAlgorithm;// 4
        //public UInt32 dot11DefaultAuthAlgorithm;// 4
        //public UInt32 dot11DefaultCipherAlgorithm;// 4
        //public UInt32 dwFlags;// 4
        //public UInt32 dwReserved;// 4
        }

I could not make the Marshal.PtrToStructure work.

Here is the function that calls the WlanGetAvailableNetworkList

        public static WLAN_AVAILABLE_NETWORKS_LIST GetAvailNetworkList()
    {
        UInt32 _dwflags = 3;
        IntPtr handle = GetClientHandle();
        IntPtr pGuid = GetCurrentInterfaceGuidPointer();
        IntPtr _ppAvailNetworkList = new IntPtr();
        uint error = WlanGetAvailableNetworkList(handle, pGuid, _dwflags, IntPtr.Zero, out _ppAvailNetworkList);
        if (error != 0)
        {
            Console.WriteLine("WlanEnumerated function in GetAvailNetworkPointer() failed... inspect error number" + error);
        }
        else
        {
            // It worked    
        }
        WLAN_AVAILABLE_NETWORKS_LIST TempNetworkList = new WLAN_AVAILABLE_NETWORKS_LIST(_ppAvailNetworkList);
        WlanFreeMemory(pGuid);
        CloseClientHandle(handle);
        return TempNetworkList;
    }

and the NUINT test that confirms there are RSSI values.

        [Test]
    public void GetAvailNetworkReturnsRSSI()
    {
        WiFiApi.WLAN_AVAILABLE_NETWORKS_LIST networklist = WiFiApi.GetAvailNetworkList();
        for (int i = 0; i < networklist.NumberOfNetworks; i++)
        {
            string SSIDstr = new string(networklist.Available_Network[i].SSID.SSID);
            Console.Write("Network " + i + "    ");
            Console.Write(SSIDstr);
            Console.Write(" RSSI = " + networklist.Available_Network[i].wlanSignalQuality);
            Console.Write(" dbM = " + ((int)(networklist.Available_Network[i].wlanSignalQuality/2)-100));
            Console.WriteLine(" ");
            if (0 != networklist.Available_Network[i].SSID.SSID_Length)
            {
                Assert.LessOrEqual((int)networklist.Available_Network[i].wlanSignalQuality, 100);
                Assert.Greater((int)networklist.Available_Network[i].wlanSignalQuality, 0);
            }
        }
    }