Krisz
Krisz

Reputation: 743

How to connect to wifi network by bssid

I would like to connect to wifi and select AP based on BSSID. Wifi profile exists for SSID on Windows. There are multiple AP with the same SSID.

Found example code of ManagedWifi on CodePlex.

I have added an overloading function of connect and all extra prototype, that needed based on this description.

The function running without error but not connecting to specified BSSID. Anyone has any idea what I missed?

public void Connect(string Bssid, string Ssid)
{
    byte[] desBssid = Bssid.Split(':').Select(x => Convert.ToByte(x, 16)).ToArray();

    Wlan.NDIS_OBJECT_HEADER ndoh;
    ndoh.Type = Wlan.NDIS_OBJECT_TYPE_DEFAULT;
    ndoh.Revision = Wlan.DOT11_BSSID_LIST_REVISION_1;
    ndoh.Size = (ushort)System.Runtime.InteropServices.Marshal.SizeOf(typeof(Wlan.DOT11_BSSID_LIST));

    Wlan.DOT11_BSSID_LIST desBssidList = new Wlan.DOT11_BSSID_LIST();
    desBssidList.Header = ndoh;
    desBssidList.uNumOfEntries = 1;
    desBssidList.uTotalNumOfEntries = 1;
    Wlan.DOT11_MAC_ADDRESS bssid = new Wlan.DOT11_MAC_ADDRESS();
    bssid.Dot11MacAddress = desBssid;
    desBssidList.BSSIDs = new Wlan.DOT11_MAC_ADDRESS[1];
    desBssidList.BSSIDs[0] = bssid;

    IntPtr desBssidListPtr = Marshal.AllocHGlobal(Marshal.SizeOf(desBssidList));
    Marshal.StructureToPtr(desBssidList, desBssidListPtr, false);


    Wlan.DOT11_SSID dot11Ssid = new Wlan.DOT11_SSID();
    dot11Ssid.ucSSID =  Ssid; 
    dot11Ssid.uSSIDLength = (uint)dot11Ssid.ucSSID.Length;

    IntPtr dot11SsidPtr = Marshal.AllocHGlobal(Marshal.SizeOf(dot11Ssid));
    Marshal.StructureToPtr(dot11Ssid, dot11SsidPtr, false);


    Wlan.WlanConnectionParameters connectionParams = new Wlan.WlanConnectionParameters();
    connectionParams.wlanConnectionMode = Wlan.WlanConnectionMode.DiscoveryUnsecure;
    connectionParams.profile = null;
    connectionParams.dot11SsidPtr = dot11SsidPtr;
    connectionParams.dot11BssType = Wlan.Dot11BssType.Infrastructure;
    connectionParams.flags = 0;
    connectionParams.desiredBssidListPtr = desBssidListPtr;
    Connect(connectionParams);
}

The log about failing connection:

Message              : WLAN AutoConfig service failed to connect to a wireless network.

                       Network Adapter: Intel(R) Dual Band Wireless-AC 7260
                       Interface GUID: {b081a2ec-8010-4c13-be59-251a69dd12ae}
                       Connection Mode: Connection to an unsecure network without a profile
                       Profile Name: <ssid of APs>
                       SSID: <ssid of APs>
                       BSS Type: Infrastructure
                       Failure Reason:The specific network is not available.
                       RSSI: 255

Id                   : 8002
Version              : 0
Qualifiers           :
Level                : 2
Task                 : 24010
Opcode               : 191
Keywords             : -9223372036317903360
RecordId             : 1151
ProviderName         : Microsoft-Windows-WLAN-AutoConfig
ProviderId           : 9580d7dd-0379-4658-9870-d5be7d52d6de
LogName              : Microsoft-Windows-WLAN-AutoConfig/Operational
ProcessId            : 4000
ThreadId             : 564
MachineName          : <machine name>
UserId               : S-1-5-18
TimeCreated          : 22/06/2019 11:30:41
ActivityId           :
RelatedActivityId    :
ContainerLog         : Microsoft-Windows-WLAN-AutoConfig/Operational
MatchedQueryIds      : {}
Bookmark             : System.Diagnostics.Eventing.Reader.EventBookmark
LevelDisplayName     : Error
OpcodeDisplayName    : Failure
TaskDisplayName      : AcmConnection
KeywordsDisplayNames : {}
Properties           : {System.Diagnostics.Eventing.Reader.EventProperty, System.Diagnostics.Eventing.Reader.EventProperty, System.Diagnostics.Eventing.Reader.EventProperty,
                       System.Diagnostics.Eventing.Reader.EventProperty...}

Upvotes: 0

Views: 3087

Answers (1)

Krisz
Krisz

Reputation: 743

Castorix had right. Profile based connection mode still can be used, when mac being specified.

See modified code:

public void Connect(string Bssid, string Ssid, string Pwd)
{
    byte[] desBssid = Bssid.Split(':').Select(x => Convert.ToByte(x, 16)).ToArray();

    Wlan.NDIS_OBJECT_HEADER ndoh;
    ndoh.Type = Wlan.NDIS_OBJECT_TYPE_DEFAULT;
    ndoh.Revision = Wlan.DOT11_BSSID_LIST_REVISION_1;
    ndoh.Size = (ushort)System.Runtime.InteropServices.Marshal.SizeOf(typeof(Wlan.DOT11_BSSID_LIST));

    Wlan.DOT11_BSSID_LIST desBssidList = new Wlan.DOT11_BSSID_LIST();
    desBssidList.Header = ndoh;
    desBssidList.uNumOfEntries = 1;
    desBssidList.uTotalNumOfEntries = 1;
    Wlan.DOT11_MAC_ADDRESS bssid = new Wlan.DOT11_MAC_ADDRESS();
    bssid.Dot11MacAddress = desBssid;
    desBssidList.BSSIDs = new Wlan.DOT11_MAC_ADDRESS[1];
    desBssidList.BSSIDs[0] = bssid;

    IntPtr desBssidListPtr = Marshal.AllocHGlobal(Marshal.SizeOf(desBssidList));
    Marshal.StructureToPtr(desBssidList, desBssidListPtr, false);


    Wlan.DOT11_SSID dot11Ssid = new Wlan.DOT11_SSID();
    dot11Ssid.ucSSID =  Ssid; 
    dot11Ssid.uSSIDLength = (uint)dot11Ssid.ucSSID.Length;

    IntPtr dot11SsidPtr = Marshal.AllocHGlobal(Marshal.SizeOf(dot11Ssid));
    Marshal.StructureToPtr(dot11Ssid, dot11SsidPtr, false);

    string profileXml = string.Format("<?xml version=\"1.0\"?><WLANProfile xmlns=\"http://www.microsoft.com/networking/WLAN/profile/v1\"><name>{0}</name><SSIDConfig><SSID><name>{0}</name></SSID></SSIDConfig><connectionType>ESS</connectionType><connectionMode>auto</connectionMode><MSM><security><authEncryption><authentication>WPA2PSK</authentication><encryption>AES</encryption><useOneX>false</useOneX></authEncryption><sharedKey><keyType>passPhrase</keyType><protected>false</protected><keyMaterial>{1}</keyMaterial></sharedKey></security></MSM></WLANProfile>", Ssid, Pwd);
    SetProfile(Wlan.WlanProfileFlags.AllUser, profileXml, true);

    Wlan.WlanConnectionParameters connectionParams = new Wlan.WlanConnectionParameters();
    connectionParams.wlanConnectionMode = Wlan.WlanConnectionMode.Profile;
    connectionParams.profile = Ssid;
    connectionParams.dot11SsidPtr = dot11SsidPtr;
    connectionParams.dot11BssType = Wlan.Dot11BssType.Any;
    connectionParams.flags = 0;
    connectionParams.desiredBssidListPtr = desBssidListPtr;
    Connect(connectionParams);

}

Upvotes: 1

Related Questions