-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathWiFiConfigManager.cpp
More file actions
191 lines (158 loc) · 5.84 KB
/
Copy pathWiFiConfigManager.cpp
File metadata and controls
191 lines (158 loc) · 5.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
#include "WiFiConfigManager.h"
#include <FreeRTOS.h>
#include <task.h>
#include <WiFi.h> // Include WiFi library for network operations
#include <LittleFS.h>
#include <ArduinoJson.h>
WiFiConfigManager::WiFiConfigManager(const String& configFilePath)
: configFilePath(configFilePath) {}
WiFiConfigManager::~WiFiConfigManager() {
stopSSIDScan();
}
void WiFiConfigManager::startSSIDScan(const std::function<void(const String&)>& onSSIDFound) {
if (scanning) {
return; // Scan already running
}
scanning = true;
// Create a FreeRTOS task for scanning SSIDs
xTaskCreate(
scanTask, // Task function
"SSIDScanTask", // Task name
4096, // Stack size
new std::pair<WiFiConfigManager*, std::function<void(const String&)>>(this, onSSIDFound), // Pass the instance and callback as a parameter
1, // Task priority
&scanTaskHandle // Task handle
);
}
void WiFiConfigManager::stopSSIDScan() {
if (scanning && scanTaskHandle != nullptr) {
scanning = false;
vTaskDelete(scanTaskHandle); // Delete the FreeRTOS task
scanTaskHandle = nullptr;
}
}
void WiFiConfigManager::scanTask(void* parameter) {
// Retrieve the callback function passed as a parameter
auto param = static_cast<std::pair<WiFiConfigManager*, std::function<void(const String&)>>*>(parameter);
WiFiConfigManager* instance = param->first;
auto onSSIDFound = ¶m->second;
// Perform the WiFi scan
while (WiFi.scanNetworks() == -1) {
vTaskDelay(pdMS_TO_TICKS(1000)); // Wait for WiFi hardware to initialize
}
while (true) {
// Check if scanning was canceled
if (!instance->scanning) {
delete param; // Clean up the parameter
vTaskDelete(nullptr); // End the task
return;
}
// Get the number of networks found
int numNetworks = WiFi.scanNetworks();
// Iterate through all found networks
for (int i = 0; i < numNetworks; i++) {
// Check again in case scanning was stopped during iteration
if (!instance->scanning) {
WiFi.scanDelete(); // Clean up scan results
delete param; // Clean up the parameter
vTaskDelete(nullptr); // End the task
return;
}
// Call the callback with each SSID found
(*onSSIDFound)(WiFi.SSID(i));
}
// Delete the scan results to free memory
WiFi.scanDelete();
// Wait before rescanning
vTaskDelay(pdMS_TO_TICKS(5000));
}
}
void WiFiConfigManager::saveNetworkProperties(const NetworkProperties& properties) {
File file = LittleFS.open(configFilePath, "w");
if (!file) {
return; // Failed to open file
}
// Create a JSON document with appropriate capacity
JsonDocument doc;
// Populate the JSON document
doc["ssid"] = properties.ssid;
doc["password"] = properties.password;
doc["ip"] = properties.ip;
doc["mask"] = properties.mask;
doc["router"] = properties.router;
doc["dns"] = properties.dns;
doc["dhcp"] = properties.dhcp;
// Serialize the JSON document to the file
if (serializeJson(doc, file) == 0) {
// Handle serialization error (optional)
}
file.close();
}
WiFiConfigManager::NetworkProperties WiFiConfigManager::loadNetworkProperties() {
NetworkProperties properties;
File file = LittleFS.open(configFilePath, "r");
if (!file) {
return properties; // Failed to open file
}
// Create a JSON document
JsonDocument doc;
// Parse the JSON file
DeserializationError error = deserializeJson(doc, file);
file.close();
if (error) {
// Return default properties if parsing fails
return properties;
}
// Extract values from the JSON document
properties.ssid = doc["ssid"] | ""; // Default to empty string if not found
properties.password = doc["password"] | "";
properties.ip = doc["ip"] | "";
properties.mask = doc["mask"] | "";
properties.router = doc["router"] | "";
properties.dns = doc["dns"] | "";
properties.dhcp = doc["dhcp"] | true; // Default to true if not found
return properties;
}
void WiFiConfigManager::startNetwork() {
NetworkProperties properties = loadNetworkProperties();
if (properties.dhcp) {
WiFi.begin(properties.ssid.c_str(), properties.password.c_str());
} else {
WiFi.config(
IPAddress().fromString(properties.ip),
IPAddress().fromString(properties.dns),
IPAddress().fromString(properties.router),
IPAddress().fromString(properties.mask)
);
WiFi.begin(properties.ssid.c_str(), properties.password.c_str());
}
}
void WiFiConfigManager::stopNetwork() {
WiFi.disconnect();
}
bool WiFiConfigManager::isConnected() {
return WiFi.status() == WL_CONNECTED;
}
WiFiConfigManager::ConnectionInfo WiFiConfigManager::getConnectionInfo() {
ConnectionInfo info;
// Only fill in data if we're connected
if (isConnected()) {
info.ip = WiFi.localIP().toString();
info.subnet = WiFi.subnetMask().toString();
info.gateway = WiFi.gatewayIP().toString();
info.dns = WiFi.dnsIP().toString();
info.ssid = WiFi.SSID();
info.rssi = WiFi.RSSI();
info.macAddress = WiFi.macAddress();
} else {
// Fill with empty values or "Not Connected"
info.ip = "Not Connected";
info.subnet = "Not Connected";
info.gateway = "Not Connected";
info.dns = "Not Connected";
info.ssid = "Not Connected";
info.rssi = 0;
info.macAddress = WiFi.macAddress(); // MAC is available even when disconnected
}
return info;
}