SensESP 3.3.0
Universal Signal K sensor toolkit ESP32
Loading...
Searching...
No Matches
wifi_provisioner.h
Go to the documentation of this file.
1#ifndef SENSESP_NET_WIFI_PROVISIONER_H_
2#define SENSESP_NET_WIFI_PROVISIONER_H_
3
4#include <Arduino.h>
5#include <DNSServer.h>
6#include <WiFi.h>
7
8#include <memory>
9#include <vector>
10
16#include "sensesp_base_app.h"
17
18namespace sensesp {
19
20constexpr int kMaxNumClientConfigs = 3;
21
26 public:
27 AccessPointSettings(bool enabled = true, String ssid = "",
28 String password = "", int channel = 9,
29 bool hidden = false, bool captive_portal_enabled = true)
30 : enabled_{enabled},
31 ssid_{ssid},
32 password_{password},
33 channel_{channel},
34 hidden_{hidden},
35 captive_portal_enabled_{captive_portal_enabled} {
36 if (ssid_ == "") {
37 // If no SSID is provided, use the hostname as the SSID
39 }
40 };
41
43 String ssid_;
44 String password_;
46 bool hidden_;
48
49 static AccessPointSettings from_json(const JsonObject& json) {
50 AccessPointSettings settings;
51 settings.enabled_ = json["enabled"] | false;
52 settings.ssid_ = json["name"] | "";
53 settings.password_ = json["password"] | "";
54 settings.channel_ = json["channel"] | 1;
55 settings.hidden_ = json["hidden"] | false;
56 settings.captive_portal_enabled_ = json["captivePortalEnabled"] | true;
57 return settings;
58 }
59
60 void as_json(JsonObject& doc) {
61 doc["enabled"] = enabled_;
62 doc["name"] = ssid_;
63 doc["password"] = password_;
64 doc["channel"] = channel_;
65 doc["hidden"] = hidden_;
66 doc["captivePortalEnabled"] = captive_portal_enabled_;
67 }
68};
69
74 public:
75 ClientSSIDConfig(String ssid = "", String password = "", bool use_dhcp = true,
76 IPAddress ip = IPAddress(169, 254, 0, 1),
77 IPAddress netmask = IPAddress(255, 255, 255, 0),
78 IPAddress gateway = IPAddress(192, 168, 0, 1),
79 IPAddress dns_server = IPAddress(8, 8, 8, 8))
80 : ssid_{ssid},
81 password_{password},
82 use_dhcp_{use_dhcp},
83 ip_{ip},
84 netmask_{netmask},
85 gateway_{gateway},
86 dns_server_{dns_server} {};
87
88 String ssid_;
89 String password_;
91 IPAddress ip_;
92 IPAddress netmask_;
93 IPAddress gateway_;
94 IPAddress dns_server_;
95
96 static ClientSSIDConfig from_json(const JsonObject& json) {
97 ClientSSIDConfig config;
98 config.ssid_ = json["name"] | "";
99 config.password_ = json["password"] | "";
100 config.use_dhcp_ = json["useDHCP"] | true;
101 config.ip_.fromString(json["ipAddress"] | "169.254.0.1");
102 config.netmask_.fromString(json["netmask"] | "255.255.255.0");
103 config.gateway_.fromString(json["gateway"] | "192.168.0.1");
104 config.dns_server_.fromString(json["dnsServer"] | "8.8.8.8");
105 return config;
106 }
107
108 void as_json(JsonObject& doc) {
109 doc["name"] = ssid_;
110 doc["password"] = password_;
111 doc["useDHCP"] = use_dhcp_;
112 doc["ipAddress"] = ip_.toString();
113 doc["netmask"] = netmask_.toString();
114 doc["gateway"] = gateway_.toString();
115 doc["dnsServer"] = dns_server_.toString();
116 }
117};
118
123 public:
125 : ssid_{""}, rssi_{0}, encryption_{0}, bssid_{0}, channel_{0} {}
126 WiFiNetworkInfo(String ssid, int32_t rssi, uint8_t encryption, uint8_t* bssid,
127 int32_t channel)
128 : ssid_{ssid}, rssi_{rssi}, encryption_{encryption}, channel_{channel} {
129 if (bssid != nullptr) {
130 memcpy(bssid_, bssid, 6);
131 } else {
132 memset(bssid_, 0, 6);
133 }
134 }
135
136 String ssid_;
137 int32_t rssi_;
138 uint8_t encryption_;
139 uint8_t bssid_[6];
140 int32_t channel_;
141
142 void as_json(JsonObject& doc) {
143 doc["ssid"] = ssid_;
144 doc["rssi"] = rssi_;
145 doc["encryption"] = encryption_;
146 doc["channel"] = channel_;
147 // Zero-pad each byte so MAC addresses like 02:0A:... format
148 // correctly. The pre-refactor code used `String(byte, HEX)` which
149 // produces "A" instead of "0A" for single-digit hex values.
150 char bssid_str[18];
151 snprintf(bssid_str, sizeof(bssid_str),
152 "%02X:%02X:%02X:%02X:%02X:%02X", bssid_[0], bssid_[1],
153 bssid_[2], bssid_[3], bssid_[4], bssid_[5]);
154 doc["bssid"] = bssid_str;
155 }
156};
157
171 public Resettable,
172 public NetworkProvisioner,
173 public ValueProducer<WiFiState> {
174 public:
175 WiFiProvisioner(const String& config_path, const String& client_ssid = "",
176 const String& client_password = "",
177 const String& ap_ssid = "",
178 const String& ap_password = "");
179 ~WiFiProvisioner() override;
180
181 // -- Resettable --
182 void reset() override;
183
184 // -- FileSystemSaveable --
185 bool to_json(JsonObject& doc) override;
186 bool from_json(const JsonObject& config) override;
187
188 // -- NetworkProvisioner --
189 IPAddress local_ip() const override { return WiFi.localIP(); }
190 IPAddress gateway_ip() const override { return WiFi.gatewayIP(); }
191 String mac_address() const override { return WiFi.macAddress(); }
192 bool is_connected() const override {
193 return WiFi.isConnected() || WiFi.getMode() == WIFI_MODE_AP ||
194 WiFi.getMode() == WIFI_MODE_APSTA;
195 }
196
204
205 // -- WiFi-specific methods --
206 IPAddress soft_ap_ip() const { return WiFi.softAPIP(); }
208 return ap_settings_.captive_portal_enabled_;
209 }
210 String ssid() const { return WiFi.SSID(); }
211 int rssi() const { return WiFi.RSSI(); }
212
213 void start_wifi_scan();
214 int16_t get_wifi_scan_results(std::vector<WiFiNetworkInfo>& ssid_list);
215
216 protected:
217 void start_access_point();
219
221
222 bool client_enabled_ = false;
223 std::vector<ClientSSIDConfig> client_settings_;
224
225 std::unique_ptr<DNSServer> dns_server_;
226};
227
228inline const String ConfigSchema(const WiFiProvisioner& obj) { return "null"; }
229
230inline bool ConfigRequiresRestart(const WiFiProvisioner& obj) { return true; }
231
232} // namespace sensesp
233
234#endif // SENSESP_NET_WIFI_PROVISIONER_H_
Storage object for WiFi access point settings.
static AccessPointSettings from_json(const JsonObject &json)
AccessPointSettings(bool enabled=true, String ssid="", String password="", int channel=9, bool hidden=false, bool captive_portal_enabled=true)
void as_json(JsonObject &doc)
static ClientSSIDConfig from_json(const JsonObject &json)
void as_json(JsonObject &doc)
ClientSSIDConfig(String ssid="", String password="", bool use_dhcp=true, IPAddress ip=IPAddress(169, 254, 0, 1), IPAddress netmask=IPAddress(255, 255, 255, 0), IPAddress gateway=IPAddress(192, 168, 0, 1), IPAddress dns_server=IPAddress(8, 8, 8, 8))
FileSystemSaveable(const String &config_path)
Definition saveable.h:63
Transport-agnostic network provisioner interface.
Resettable(int priority=0)
static String get_hostname()
Get the current hostname.
WiFiNetworkInfo(String ssid, int32_t rssi, uint8_t encryption, uint8_t *bssid, int32_t channel)
void as_json(JsonObject &doc)
Manages the ESP's WiFi connection.
bool is_connected() const override
True iff the network interface is usable.
bool from_json(const JsonObject &config) override
String mac_address() const override
Hardware MAC address of the active interface.
IPAddress local_ip() const override
Current local IPv4 address. Returns IPAddress() if no link.
AccessPointSettings ap_settings_
std::vector< ClientSSIDConfig > client_settings_
ValueProducer< WiFiState > * get_wifi_state_producer()
IPAddress soft_ap_ip() const
int16_t get_wifi_scan_results(std::vector< WiFiNetworkInfo > &ssid_list)
IPAddress gateway_ip() const override
Default gateway IPv4 address. Returns IPAddress() if no link.
WiFiProvisioner(const String &config_path, const String &client_ssid="", const String &client_password="", const String &ap_ssid="", const String &ap_password="")
bool is_captive_portal_enabled() const
bool to_json(JsonObject &doc) override
std::unique_ptr< DNSServer > dns_server_
const String ConfigSchema(const SmartSwitchController &obj)
constexpr int kMaxNumClientConfigs
bool ConfigRequiresRestart(const HTTPServer &obj)