EmlaLockSafe
WifiConfigurationServer.h
Go to the documentation of this file.
1
5#pragma once
6
7#include "Configuration.h"
9
10#include <Arduino.h>
11#include <DNSServer.h>
12#include <Esp.h>
13#include <LiquidCrystal_PCF8574.h>
14#include <WiFi.h>
15#include <list>
16#include <mutex>
17
21#define CONFIGURATION_SSID "SafeSetup"
22
23namespace configuration {
24
29#pragma region Singelton
30protected:
35 static WifiConfigurationServer* instance = nullptr;
36 return &instance;
37 }
38
39public:
44 return *getInstance();
45 }
46
53 inline static void begin(LiquidCrystal_PCF8574& display) {
54 if (!*getInstance()) {
56 }
57 }
58#pragma endregion
59
60#pragma region Members
61protected:
65 DNSServer dnsServer;
66
67protected:
71 LiquidCrystal_PCF8574& display;
72
73protected:
77 std::mutex mtx;
78
79protected:
83 std::list<String> ssids;
84
85protected:
89 IPAddress IP;
90
91protected:
95 IPAddress netMsk;
96#pragma endregion
97
98private:
104 WifiConfigurationServer(LiquidCrystal_PCF8574& display)
107 , IP(10, 0, 0, 1)
108 , netMsk(255, 255, 255, 0) {
109 createAp();
111 server.begin(); // Web server start
113 }
114
115public:
119 void loop() {
120 dnsServer.processNextRequest(); // DNS
121 scanWiFi();
122 }
123
124protected:
128 void createAp() {
129 // open access point
130 WiFi.setAutoReconnect(false);
131 WiFi.persistent(false);
132 WiFi.disconnect();
133 WiFi.setHostname("EmlalockSafe");
134
135 // Setup Access Point
136 display.clear();
137 display.setCursor(0, 0);
138 display.print("Setting up WiFi");
139 Serial.println("Setting up WiFi");
140 if (!WiFi.softAP(CONFIGURATION_SSID)) {
141 display.clear();
142 display.setCursor(0, 0);
143 display.print("Error starting");
144 display.setCursor(0, 1);
145 display.print("Access Point ");
146 display.setCursor(0, 2);
148 Serial.print("Error starting Access Point ");
149 Serial.println(CONFIGURATION_SSID);
150 return;
151 }
152 delay(2000); // Without delay I've seen the IP address blank
153 WiFi.softAPConfig(IP, IP, netMsk);
154 dnsServer.setErrorReplyCode(DNSReplyCode::NoError);
155 dnsServer.start(53, "*", IP);
156 }
157
158protected:
163 // Setup Webserver
164 display.clear();
165 display.setCursor(0, 0);
166 display.print("Setting up Webserver");
167 Serial.println("Setting up Webserver");
168 delay(500);
169
170 addSpiffsFileToServer("/", "text/html", "/indexWifi.html");
171 // Captive Portal forwards
172 addSpiffsFileToServer("/generate_204", "text/html", "/indexWifi.html");
173 addSpiffsFileToServer("/favicon.ico", "text/html", "/indexWifi.html");
174 addSpiffsFileToServer("/fwlink", "text/html", "/indexWifi.html");
175
176 // Add file to webserver listing all visible SSIDs
177 server.on("/ssids", HTTP_GET, [this](AsyncWebServerRequest* request) {
178 std::unique_lock<std::mutex> lock(mtx);
179 String resp = "";
180 for (const auto& ssid : ssids) {
181 resp += ssid + "\r\n";
182 }
183 request->send(200, "text/plain", resp);
184 });
185
186 // Callback for if the modifications should be saved
187 server.on("/saveData", HTTP_GET, [this](AsyncWebServerRequest* request) {
188 Configuration::getSingleton().setWifiSettings(request->getParam("ssid")->value(), request->getParam("pwd")->value());
189 request->send(200, "text/plain", "Configuration Updated. Rebooting...");
190 delay(100);
191 ESP.restart();
192 });
193
194 // Callback if the a site is requested which does not exist
195 server.onNotFound([](AsyncWebServerRequest* request) {
196 // just always forward to the main page
197 AsyncWebServerResponse* response = request->beginResponse(302, "text/plain", "");
198 response->addHeader("Location", String("http://") + WiFi.softAPIP().toString());
199 request->send(response);
200 });
201 }
202
203protected:
208 // Update the LCD
209 display.clear();
210 display.setCursor(0, 0);
211 display.print("Connect to WiFi:");
212 display.setCursor(0, 1);
214 display.setCursor(0, 2);
215 display.print("Open in Browser:");
216 display.setCursor(0, 3);
217 display.print("http://");
218 display.print(IP);
219
220 Serial.println("\n");
221 Serial.println("Display: Connect to WiFi:");
222 Serial.print("Display: ");
223 Serial.println(CONFIGURATION_SSID);
224 Serial.println("Display: Open in Browser:");
225 Serial.print("Display: http://");
226 Serial.print(IP);
227 }
228
229protected:
233 void scanWiFi() {
234 // check the state scanning for wifis
235 int16_t scanState = WiFi.scanComplete();
236 if (scanState == -2) {
237 // not started yet, start a new scan
238 WiFi.scanNetworks(true);
239 }
240 else if (scanState >= 0) {
241 // scan completed
242 std::unique_lock<std::mutex> lock(mtx);
243 ssids.clear();
244 for (int i = 0; i < scanState; i++) {
245 ssids.push_back(WiFi.SSID(i));
246 }
247 WiFi.scanNetworks(true);
248 }
249 }
250};
251} // namespace configuration
#define CONFIGURATION_SSID
Name of the the temporary WiFi for the configuration.
Definition: WifiConfigurationServer.h:21
static Configuration & getSingleton()
Get the Singleton object.
Definition: Configuration.h:162
void setWifiSettings(const String &ssid, const String &pwd)
Set the Wifi Settings.
Definition: Configuration.h:368
Base class for configuring the controller over WiFi.
Definition: ConfigurationServerBase.h:16
void addSpiffsFileToServer(const char *path, String contentType, const char *filename=nullptr)
Adds the file from the SPIFFS with the filename to the webserver under the given path.
Definition: ConfigurationServerBase.h:43
AsyncWebServer server
The used asynchronous webserver.
Definition: ConfigurationServerBase.h:21
Class implementing the configuration of the WiFi.
Definition: WifiConfigurationServer.h:28
static WifiConfigurationServer ** getInstance()
Function providing the instance for the singleton.
Definition: WifiConfigurationServer.h:34
IPAddress netMsk
Network mask in Access Point mode.
Definition: WifiConfigurationServer.h:95
void createAp()
Create and configures the WiFi in AP mode.
Definition: WifiConfigurationServer.h:128
std::list< String > ssids
List with all found ssids.
Definition: WifiConfigurationServer.h:83
static void begin(LiquidCrystal_PCF8574 &display)
Create a new Configuration server.
Definition: WifiConfigurationServer.h:53
IPAddress IP
IP address in Access Point mode.
Definition: WifiConfigurationServer.h:89
void initialLcdMessage()
shows the ssid of the AP and the address to which the user should connect
Definition: WifiConfigurationServer.h:207
static WifiConfigurationServer * getSingletonPointer()
Get the Singleton object.
Definition: WifiConfigurationServer.h:43
LiquidCrystal_PCF8574 & display
Reference to the display.
Definition: WifiConfigurationServer.h:71
void loop()
Forward of the Arduino loop function.
Definition: WifiConfigurationServer.h:119
void configureWebserver()
adds the handlers for the different webpages
Definition: WifiConfigurationServer.h:162
std::mutex mtx
mutex for the protection of the data
Definition: WifiConfigurationServer.h:77
void scanWiFi()
scans the visible wifis and saves them into ssids. Should be continuously called during loop.
Definition: WifiConfigurationServer.h:233
DNSServer dnsServer
Instance of the DNS server in access point mode.
Definition: WifiConfigurationServer.h:65
WifiConfigurationServer(LiquidCrystal_PCF8574 &display)
Construct a new Configuration Server object.
Definition: WifiConfigurationServer.h:104
Definition: Configuration.h:16