Oh My Dog Oh My Dog - 3 months ago 115
C# Question

C# WPF how to connect a wifi with password

I use Managed Wifi API library and ok to connect a "HasProfile" wifi AP like this:

WlanClient client = new WlanClient();
foreach (var item in client.Interfaces)
{
ViewModel.CurrentWlan = item;
Wlan.WlanAvailableNetwork[] networks = item.GetAvailableNetworkList(0);
foreach (Wlan.WlanAvailableNetwork network in networks)
{
var name = Helpers.GetStringForSSID(network.dot11Ssid);
ConnectionModel model = new ConnectionModel
{
DisplayName = string.Format("{0} (signal {1})", name, network.wlanSignalQuality),
IsConnected = network.flags.HasFlag(Wlan.WlanAvailableNetworkFlags.Connected),
SSID = network.dot11Ssid.SSID,
SsidString = Convert.ToBase64String(network.dot11Ssid.SSID),
ProfileName = network.profileName,
Name = name
};

if (network.flags.HasFlag(Wlan.WlanAvailableNetworkFlags.HasProfile))
{
model.XmlProfile = item.GetProfileXml(model.ProfileName);
}

if (network.flags == Wlan.WlanAvailableNetworkFlags.HasProfile)
{
model.IsRemembered = true;
}

ViewModel.Connections.Add(model);
}
}


OK now, all the availible APs are in the ViewModel.Connections.
Then I can connect one of the AP that Has Profiles:

private void OnConnect_Handler(object sender, RoutedEventArgs e)
{
Button button = sender as Button;
ConnectionModel model = button.DataContext as ConnectionModel;

ViewModel.CurrentWlan.SetProfile(Wlan.WlanProfileFlags.AllUser, model.XmlProfile, true);
ViewModel.CurrentWlan.Connect(Wlan.WlanConnectionMode.Profile, Wlan.Dot11BssType.Any, model.ProfileName);
}


and it's worked!
then I found a problem that is, such code only can connect those APs Has Profile, if I want to connect to a AP without profile(I think that means 'AP never connected'), I should use the following code:

string profileName = model.ProfileName;
string mac = "1008B1CD976F";
string key = "IsThisPasswordField?";
string profile = string.Format("<?xml version=\"1.0\"?><WLANProfile xmlns=\"http://www.microsoft.com/networking/WLAN/profile/v1\"><name>{0}</name><SSIDConfig><SSID><hex>{1}</hex><name>{0}</name></SSID></SSIDConfig><connectionType>ESS</connectionType><MSM><security><authEncryption><authentication>open</authentication><encryption>WEP</encryption><useOneX>false</useOneX></authEncryption><sharedKey><keyType>networkKey</keyType><protected>false</protected><keyMaterial>{2}</keyMaterial></sharedKey><keyIndex>0</keyIndex></security></MSM></WLANProfile>",
profileName, mac, key);

ViewModel.CurrentWlan.SetProfile(Wlan.WlanProfileFlags.AllUser, profile, true);
ViewModel.CurrentWlan.Connect(Wlan.WlanConnectionMode.Profile, Wlan.Dot11BssType.Any, profileName);


But I tried serveral times always failed because:

(1) I don't know what the XML content is, why can't just input password then Connect(ssid, password)? is it because WIFI programming doesn't go like this?
(2) If must set a profile, how to input the right things such as:

string mac = "1008B1CD976F";
string key = "IsThisPasswordField?";


how to know this 'mac', and how to encrypt this key(if it's the AP's password)?

EDIT: here's the Managed Wifi API site. But there's no documentation.

Answer

First: The hex-string, you want to insert into the profile is not the mac of the accesspoint, but the hex-string of the ssid. The profile xml is missleading here. I had the same problem, until I converted the hex-string back of a known profile. It was the ssid ;-)

You can just convert the ssid to it's hex representation by so:

string ssid = "YourSSID";
byte[] ssidBytes = Text.Encoding.Default.GetBytes(ssid);
string ssidHex = BitConverter.ToString(ssidBytes);
ssidHex = ssidHex.Replace("-", "");

Second: Because of a wrong hex-string of your ssid, your connection approach with the clear text password did not work either. So just use the hex-representation of the ssid and you can connect with the password in clear text, as you tried before.