Skip to content

Commit 4a66f23

Browse files
authored
Improving WiFi AP sample (#349)
1 parent ce92975 commit 4a66f23

File tree

6 files changed

+159
-83
lines changed

6 files changed

+159
-83
lines changed

Diff for: samples/WiFiAP/Program.cs

+21-66
Original file line numberDiff line numberDiff line change
@@ -18,84 +18,39 @@ namespace WifiAP
1818
public class Program
1919
{
2020
// Start Simple WebServer
21-
static WebServer server = new WebServer();
21+
private static WebServer _server = new WebServer();
22+
private static bool _wifiApMode = false;
2223

2324
// Connected Station count
24-
static int connectedCount = 0;
25+
private static int _connectedCount = 0;
2526

2627
// GPIO pin used to put device into AP set-up mode
27-
const int SETUP_PIN = 5;
28+
private const int SetupPin = 5;
2829

2930
public static void Main()
3031
{
3132
Debug.WriteLine("Welcome to WiFI Soft AP world!");
3233

3334
var gpioController = new GpioController();
34-
GpioPin setupButton = gpioController.OpenPin(SETUP_PIN, PinMode.InputPullUp);
35+
GpioPin setupButton = gpioController.OpenPin(SetupPin, PinMode.InputPullUp);
3536

3637
// If Wireless station is not enabled then start Soft AP to allow Wireless configuration
3738
// or Button pressed
38-
if (!Wireless80211.IsEnabled() || (setupButton.Read() == PinValue.High))
39+
if (setupButton.Read() == PinValue.High)
3940
{
40-
41-
Wireless80211.Disable();
42-
if (WirelessAP.Setup() == false)
43-
{
44-
// Reboot device to Activate Access Point on restart
45-
Debug.WriteLine($"Setup Soft AP, Rebooting device");
46-
Power.RebootDevice();
47-
}
48-
49-
var dhcpserver = new DhcpServer
50-
{
51-
CaptivePortalUrl = $"http://{WirelessAP.SoftApIP}"
52-
};
53-
var dhcpInitResult = dhcpserver.Start(IPAddress.Parse(WirelessAP.SoftApIP), new IPAddress(new byte[] { 255, 255, 255, 0 }));
54-
if (!dhcpInitResult)
55-
{
56-
Debug.WriteLine($"Error initializing DHCP server.");
57-
}
58-
59-
Debug.WriteLine($"Running Soft AP, waiting for client to connect");
60-
Debug.WriteLine($"Soft AP IP address :{WirelessAP.GetIP()}");
61-
62-
// Link up Network event to show Stations connecting/disconnecting to Access point.
63-
//NetworkChange.NetworkAPStationChanged += NetworkChange_NetworkAPStationChanged;
64-
// Now that the normal Wifi is deactivated, that we have setup a static IP
65-
// We can start the Web server
66-
server.Start();
41+
WirelessAP.SetWifiAp();
42+
_wifiApMode = true;
6743
}
6844
else
6945
{
70-
Debug.WriteLine($"Running in normal mode, connecting to Access point");
71-
var conf = Wireless80211.GetConfiguration();
72-
73-
bool success;
74-
75-
// For devices like STM32, the password can't be read
76-
if (string.IsNullOrEmpty(conf.Password))
77-
{
78-
// In this case, we will let the automatic connection happen
79-
success = WifiNetworkHelper.Reconnect(requiresDateTime: true, token: new CancellationTokenSource(60000).Token);
80-
}
81-
else
82-
{
83-
// If we have access to the password, we will force the reconnection
84-
// This is mainly for ESP32 which will connect normaly like that.
85-
success = WifiNetworkHelper.ConnectDhcp(conf.Ssid, conf.Password, requiresDateTime: true, token: new CancellationTokenSource(60000).Token);
86-
}
87-
88-
if (success)
89-
{
90-
Debug.WriteLine($"Connection is {success}");
91-
Debug.WriteLine($"We have a valid date: {DateTime.UtcNow}");
92-
}
93-
else
94-
{
95-
Debug.WriteLine($"Something wrong happened, can't connect at all");
96-
}
46+
_wifiApMode = Wireless80211.ConnectOrSetAp();
9747
}
9848

49+
Console.WriteLine($"Connected with wifi credentials. IP Address: {(_wifiApMode ? WirelessAP.GetIP() : Wireless80211.GetCurrentIPAddress())}");
50+
if( _wifiApMode )
51+
{
52+
_server.Start();
53+
}
9954

10055
// Just wait for now
10156
// Here you would have the reset of your program using the client WiFI link
@@ -120,26 +75,26 @@ private static void NetworkChange_NetworkAPStationChanged(int NetworkIndex, Netw
12075
string macString = BitConverter.ToString(station.MacAddress);
12176
Debug.WriteLine($"Station mac {macString} Rssi:{station.Rssi} PhyMode:{station.PhyModes} ");
12277

123-
connectedCount++;
78+
_connectedCount++;
12479

12580
// Start web server when it connects otherwise the bind to network will fail as
12681
// no connected network. Start web server when first station connects
127-
if (connectedCount == 1)
82+
if (_connectedCount == 1)
12883
{
12984
// Wait for Station to be fully connected before starting web server
13085
// other you will get a Network error
13186
Thread.Sleep(2000);
132-
server.Start();
87+
_server.Start();
13388
}
13489
}
13590
else
13691
{
13792
// Station disconnected. When no more station connected then stop web server
138-
if (connectedCount > 0)
93+
if (_connectedCount > 0)
13994
{
140-
connectedCount--;
141-
if (connectedCount == 0)
142-
server.Stop();
95+
_connectedCount--;
96+
if (_connectedCount == 0)
97+
_server.Stop();
14398
}
14499
}
145100

Diff for: samples/WiFiAP/WebServer.cs

+6
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,12 @@ private void ProcessRequest(HttpListenerContext context)
8585

8686
string message = "<p>New settings saved.</p><p>Rebooting device to put into normal mode</p>";
8787

88+
bool res = Wireless80211.Configure(ssid, password);
89+
if (res)
90+
{
91+
message += $"<p>And your new IP address should be {Wireless80211.GetCurrentIPAddress()}.</p>";
92+
}
93+
8894
responseString = CreateMainPage(message);
8995

9096
OutPutResponse(response, responseString);

Diff for: samples/WiFiAP/WiFiAP.nfproj

+4-6
Original file line numberDiff line numberDiff line change
@@ -74,17 +74,15 @@
7474
<HintPath>packages\nanoFramework.System.Device.Gpio.1.1.38\lib\System.Device.Gpio.dll</HintPath>
7575
<Private>True</Private>
7676
</Reference>
77-
<Reference Include="System.Device.Wifi, Version=1.5.71.0, Culture=neutral, PublicKeyToken=c07d481e9758c731">
78-
<HintPath>packages\nanoFramework.System.Device.Wifi.1.5.71\lib\System.Device.Wifi.dll</HintPath>
79-
<Private>True</Private>
77+
<Reference Include="System.Device.Wifi">
78+
<HintPath>packages\nanoFramework.System.Device.Wifi.1.5.74\lib\System.Device.Wifi.dll</HintPath>
8079
</Reference>
8180
<Reference Include="System.IO.Streams, Version=1.1.52.0, Culture=neutral, PublicKeyToken=c07d481e9758c731">
8281
<HintPath>packages\nanoFramework.System.IO.Streams.1.1.52\lib\System.IO.Streams.dll</HintPath>
8382
<Private>True</Private>
8483
</Reference>
85-
<Reference Include="System.Net, Version=1.10.68.0, Culture=neutral, PublicKeyToken=c07d481e9758c731">
86-
<HintPath>packages\nanoFramework.System.Net.1.10.68\lib\System.Net.dll</HintPath>
87-
<Private>True</Private>
84+
<Reference Include="System.Net">
85+
<HintPath>packages\nanoFramework.System.Net.1.10.70\lib\System.Net.dll</HintPath>
8886
</Reference>
8987
<Reference Include="System.Net.Http, Version=1.5.118.0, Culture=neutral, PublicKeyToken=c07d481e9758c731">
9088
<HintPath>packages\nanoFramework.System.Net.Http.Server.1.5.118\lib\System.Net.Http.dll</HintPath>

Diff for: samples/WiFiAP/Wireless80211.cs

+75-6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
// See LICENSE file in the project root for full license information.
44
//
55

6+
using System;
7+
using System.Device.Wifi;
68
using System.Diagnostics;
79
using System.Net.NetworkInformation;
810
using System.Threading;
@@ -12,19 +14,62 @@ namespace WifiAP
1214
{
1315
class Wireless80211
1416
{
17+
/// <summary>
18+
/// Checks if the wireless 802.11 interface is enabled.
19+
/// </summary>
20+
/// <returns>
21+
/// Returns true if the wireless 802.11 interface is enabled (i.e., the SSID is not null or empty),
22+
/// otherwise returns false.
23+
/// </returns>
1524
public static bool IsEnabled()
1625
{
1726
Wireless80211Configuration wconf = GetConfiguration();
1827
return !string.IsNullOrEmpty(wconf.Ssid);
1928
}
2029

30+
/// <summary>
31+
/// Get current IP address. Only valid if successfully provisioned and connected
32+
/// </summary>
33+
/// <returns>IP address string</returns>
34+
public static string GetCurrentIPAddress()
35+
{
36+
NetworkInterface ni = NetworkInterface.GetAllNetworkInterfaces()[0];
37+
38+
// get first NI ( Wifi on ESP32 )
39+
return ni.IPv4Address.ToString();
40+
}
41+
42+
/// <summary>
43+
/// Coonnects to the Wifi or sets the Access Point mode.
44+
/// </summary>
45+
/// <returns>True if access point is setup.</returns>
46+
public static bool ConnectOrSetAp()
47+
{
48+
if (IsEnabled())
49+
{
50+
Debug.WriteLine("Wireless client activated");
51+
if (!WifiNetworkHelper.Reconnect(true, token: new CancellationTokenSource(30_000).Token))
52+
{
53+
WirelessAP.SetWifiAp();
54+
return true;
55+
}
56+
}
57+
else
58+
{
59+
WirelessAP.SetWifiAp();
60+
return true;
61+
}
62+
63+
return false;
64+
}
65+
2166
/// <summary>
2267
/// Disable the Wireless station interface.
2368
/// </summary>
2469
public static void Disable()
2570
{
2671
Wireless80211Configuration wconf = GetConfiguration();
27-
wconf.Options = Wireless80211Configuration.ConfigurationOptions.None;
72+
wconf.Options = Wireless80211Configuration.ConfigurationOptions.None | Wireless80211Configuration.ConfigurationOptions.SmartConfig;
2873
wconf.SaveConfiguration();
2974
}
3075

@@ -35,14 +80,38 @@ public static void Disable()
3580
/// <param name="password"></param>
3681
/// <returns></returns>
3782
public static bool Configure(string ssid, string password)
38-
{
39-
// And we have to force connect once here even for a short time
40-
var success = WifiNetworkHelper.ConnectDhcp(ssid, password, token: new CancellationTokenSource(10000).Token);
41-
Debug.WriteLine($"Connection is {success}");
83+
{
84+
// Make sure we are disconnected before we start connecting otherwise
85+
// ConnectDhcp will just return success instead of reconnecting.
86+
WifiAdapter wa = WifiAdapter.FindAllAdapters()[0];
87+
wa.Disconnect();
88+
89+
CancellationTokenSource cs = new(30_000);
90+
Console.WriteLine("ConnectDHCP");
91+
WifiNetworkHelper.Disconnect();
92+
93+
// Reconfigure properly the normal wifi
4294
Wireless80211Configuration wconf = GetConfiguration();
4395
wconf.Options = Wireless80211Configuration.ConfigurationOptions.AutoConnect | Wireless80211Configuration.ConfigurationOptions.Enable;
96+
wconf.Ssid = ssid;
97+
wconf.Password = password;
4498
wconf.SaveConfiguration();
45-
return true;
99+
100+
WifiNetworkHelper.Disconnect();
101+
bool success;
102+
103+
success = WifiNetworkHelper.ConnectDhcp(ssid, password, WifiReconnectionKind.Automatic, true, token: cs.Token);
104+
105+
if (!success)
106+
{
107+
wa.Disconnect();
108+
// Bug in network helper, we've most likely try to connect before, let's make it manual
109+
var res = wa.Connect(ssid, WifiReconnectionKind.Automatic, password);
110+
success = res.ConnectionStatus == WifiConnectionStatus.Success;
111+
Console.WriteLine($"Connected: {res.ConnectionStatus}");
112+
}
113+
114+
return success;
46115
}
47116

48117
/// <summary>

Diff for: samples/WiFiAP/WirelessAP.cs

+51-3
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,57 @@
33
// See LICENSE file in the project root for full license information.
44
//
55

6+
using System;
7+
using System.Net;
68
using System.Net.NetworkInformation;
9+
using Iot.Device.DhcpServer;
10+
using nanoFramework.Runtime.Native;
711

812
namespace WifiAP
913
{
14+
/// <summary>
15+
/// Provides methods and properties to manage a wireless access point.
16+
/// </summary>
1017
public static class WirelessAP
1118
{
12-
public const string SoftApIP = "192.168.4.1";
19+
/// <summary>
20+
/// Gets or sets the IP address of the Soft AP.
21+
/// </summary>
22+
public static string SoftApIP { get; set; } = "192.168.4.1";
23+
24+
/// <summary>
25+
/// Gets or sets the SSID of the Soft AP.
26+
/// </summary>
27+
public static string SoftApSsid { get; set; } = "MySuperSSID";
28+
29+
/// <summary>
30+
/// Sets the configuration for the wireless access point.
31+
/// </summary>
32+
public static void SetWifiAp()
33+
{
34+
Wireless80211.Disable();
35+
if (Setup() == false)
36+
{
37+
// Reboot device to Activate Access Point on restart
38+
Console.WriteLine($"Setup Soft AP, Rebooting device");
39+
Power.RebootDevice();
40+
}
41+
42+
var dhcpserver = new DhcpServer
43+
{
44+
CaptivePortalUrl = $"http://{SoftApIP}"
45+
};
46+
var dhcpInitResult = dhcpserver.Start(IPAddress.Parse(SoftApIP), new IPAddress(new byte[] { 255, 255, 255, 0 }));
47+
if (!dhcpInitResult)
48+
{
49+
Console.WriteLine($"Error initializing DHCP server.");
50+
// This happens after a very freshly flashed device
51+
Power.RebootDevice();
52+
}
53+
54+
Console.WriteLine($"Running Soft AP, waiting for client to connect");
55+
Console.WriteLine($"Soft AP IP address :{GetIP()}");
56+
}
1357

1458
/// <summary>
1559
/// Disable the Soft AP for next restart.
@@ -51,13 +95,13 @@ public static bool Setup()
5195
WirelessAPConfiguration.ConfigurationOptions.Enable;
5296

5397
// Set the SSID for Access Point. If not set will use default "nano_xxxxxx"
54-
//wapconf.Ssid = "MySsid";
98+
wapconf.Ssid = SoftApSsid;
5599

56100
// Maximum number of simultaneous connections, reserves memory for connections
57101
wapconf.MaxConnections = 1;
58102

59103
// To set-up Access point with no Authentication
60-
wapconf.Authentication = AuthenticationType.Open;
104+
wapconf.Authentication = System.Net.NetworkInformation.AuthenticationType.Open;
61105
wapconf.Password = "";
62106

63107
// To set up Access point with no Authentication. Password minimum 8 chars.
@@ -80,6 +124,10 @@ public static WirelessAPConfiguration GetConfiguration()
80124
return WirelessAPConfiguration.GetAllWirelessAPConfigurations()[ni.SpecificConfigId];
81125
}
82126

127+
/// <summary>
128+
/// Gets the network interface for the wireless access point.
129+
/// </summary>
130+
/// <returns>The network interface for the wireless access point.</returns>
83131
public static NetworkInterface GetInterface()
84132
{
85133
NetworkInterface[] Interfaces = NetworkInterface.GetAllNetworkInterfaces();

Diff for: samples/WiFiAP/packages.config

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
<package id="nanoFramework.Runtime.Native" version="1.6.12" targetFramework="netnano1.0" />
88
<package id="nanoFramework.System.Collections" version="1.5.31" targetFramework="netnano1.0" />
99
<package id="nanoFramework.System.Device.Gpio" version="1.1.38" targetFramework="netnano1.0" />
10-
<package id="nanoFramework.System.Device.Wifi" version="1.5.71" targetFramework="netnano1.0" />
10+
<package id="nanoFramework.System.Device.Wifi" version="1.5.74" targetFramework="netnano1.0" />
1111
<package id="nanoFramework.System.IO.Streams" version="1.1.52" targetFramework="netnano1.0" />
12-
<package id="nanoFramework.System.Net" version="1.10.68" targetFramework="netnano1.0" />
12+
<package id="nanoFramework.System.Net" version="1.10.70" targetFramework="netnano1.0" />
1313
<package id="nanoFramework.System.Net.Http.Server" version="1.5.118" targetFramework="netnano1.0" />
1414
<package id="nanoFramework.System.Text" version="1.2.54" targetFramework="netnano1.0" />
1515
<package id="nanoFramework.System.Threading" version="1.1.32" targetFramework="netnano1.0" />

0 commit comments

Comments
 (0)