mirror of
https://github.com/wled/WLED.git
synced 2025-04-24 06:47:18 +00:00
Implement multiple WiFi
- similar to #3705 - solves #2845, #2974, #852, #1228
This commit is contained in:
parent
5dd8f0a0b7
commit
bfb217c203
102
wled00/cfg.cpp
102
wled00/cfg.cpp
@ -40,21 +40,39 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
||||
linked_remote[12] = '\0';
|
||||
#endif
|
||||
|
||||
JsonObject nw_ins_0 = nw["ins"][0];
|
||||
getStringFromJson(clientSSID, nw_ins_0[F("ssid")], 33);
|
||||
//int nw_ins_0_pskl = nw_ins_0[F("pskl")];
|
||||
//The WiFi PSK is normally not contained in the regular file for security reasons.
|
||||
//If it is present however, we will use it
|
||||
getStringFromJson(clientPass, nw_ins_0["psk"], 65);
|
||||
size_t n = 0;
|
||||
JsonArray nw_ins = nw["ins"];
|
||||
if (!nw_ins.isNull()) {
|
||||
// as password are stored separately in wsec.json when reading configuration vector resize happens there, but for dynamic config we need to resize if necessary
|
||||
if (nw_ins.size() > 1 && nw_ins.size() > multiWiFi.size()) multiWiFi.resize(nw_ins.size()); // resize constructs objects while resizing
|
||||
for (JsonObject wifi : nw_ins) {
|
||||
JsonArray ip = wifi["ip"];
|
||||
JsonArray gw = wifi["gw"];
|
||||
JsonArray sn = wifi["sn"];
|
||||
char ssid[33] = "";
|
||||
char pass[65] = "";
|
||||
IPAddress nIP = (uint32_t)0U, nGW = (uint32_t)0U, nSN = (uint32_t)0x00FFFFFF; // little endian
|
||||
getStringFromJson(ssid, wifi[F("ssid")], 33);
|
||||
getStringFromJson(pass, wifi["psk"], 65); // password is not normally present but if it is, use it
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
CJSON(nIP[i], ip[i]);
|
||||
CJSON(nGW[i], gw[i]);
|
||||
CJSON(nSN[i], sn[i]);
|
||||
}
|
||||
if (strlen(ssid) > 0) strlcpy(multiWiFi[n].clientSSID, ssid, 33); // this will keep old SSID intact if not present in JSON
|
||||
if (strlen(pass) > 0) strlcpy(multiWiFi[n].clientPass, pass, 65); // this will keep old password intact if not present in JSON
|
||||
multiWiFi[n].staticIP = nIP;
|
||||
multiWiFi[n].staticGW = nGW;
|
||||
multiWiFi[n].staticSN = nSN;
|
||||
if (++n >= WLED_MAX_WIFI_COUNT) break;
|
||||
}
|
||||
}
|
||||
|
||||
JsonArray nw_ins_0_ip = nw_ins_0["ip"];
|
||||
JsonArray nw_ins_0_gw = nw_ins_0["gw"];
|
||||
JsonArray nw_ins_0_sn = nw_ins_0["sn"];
|
||||
|
||||
for (byte i = 0; i < 4; i++) {
|
||||
CJSON(staticIP[i], nw_ins_0_ip[i]);
|
||||
CJSON(staticGateway[i], nw_ins_0_gw[i]);
|
||||
CJSON(staticSubnet[i], nw_ins_0_sn[i]);
|
||||
JsonArray dns = nw[F("dns")];
|
||||
if (!dns.isNull()) {
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
CJSON(dnsAddress[i], dns[i]);
|
||||
}
|
||||
}
|
||||
|
||||
JsonObject ap = doc["ap"];
|
||||
@ -212,7 +230,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
||||
JsonObject btn_obj = hw["btn"];
|
||||
bool pull = btn_obj[F("pull")] | (!disablePullUp); // if true, pullup is enabled
|
||||
disablePullUp = !pull;
|
||||
JsonArray hw_btn_ins = btn_obj[F("ins")];
|
||||
JsonArray hw_btn_ins = btn_obj["ins"];
|
||||
if (!hw_btn_ins.isNull()) {
|
||||
for (uint8_t b = 0; b < WLED_MAX_BUTTONS; b++) { // deallocate existing button pins
|
||||
pinManager.deallocatePin(btnPin[b], PinOwner::Button); // does nothing if trying to deallocate a pin with PinOwner != Button
|
||||
@ -433,7 +451,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
||||
if (e131Port == DDP_DEFAULT_PORT) e131Port = E131_DEFAULT_PORT; // prevent double DDP port allocation
|
||||
CJSON(e131Multicast, if_live[F("mc")]);
|
||||
|
||||
JsonObject if_live_dmx = if_live[F("dmx")];
|
||||
JsonObject if_live_dmx = if_live["dmx"];
|
||||
CJSON(e131Universe, if_live_dmx[F("uni")]);
|
||||
CJSON(e131SkipOutOfSequence, if_live_dmx[F("seqskip")]);
|
||||
CJSON(DMXAddress, if_live_dmx[F("addr")]);
|
||||
@ -665,19 +683,23 @@ void serializeConfig() {
|
||||
#endif
|
||||
|
||||
JsonArray nw_ins = nw.createNestedArray("ins");
|
||||
for (size_t n = 0; n < multiWiFi.size(); n++) {
|
||||
JsonObject wifi = nw_ins.createNestedObject();
|
||||
wifi[F("ssid")] = multiWiFi[n].clientSSID;
|
||||
wifi[F("pskl")] = strlen(multiWiFi[n].clientPass);
|
||||
JsonArray wifi_ip = wifi.createNestedArray("ip");
|
||||
JsonArray wifi_gw = wifi.createNestedArray("gw");
|
||||
JsonArray wifi_sn = wifi.createNestedArray("sn");
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
wifi_ip.add(multiWiFi[n].staticIP[i]);
|
||||
wifi_gw.add(multiWiFi[n].staticGW[i]);
|
||||
wifi_sn.add(multiWiFi[n].staticSN[i]);
|
||||
}
|
||||
}
|
||||
|
||||
JsonObject nw_ins_0 = nw_ins.createNestedObject();
|
||||
nw_ins_0[F("ssid")] = clientSSID;
|
||||
nw_ins_0[F("pskl")] = strlen(clientPass);
|
||||
|
||||
JsonArray nw_ins_0_ip = nw_ins_0.createNestedArray("ip");
|
||||
JsonArray nw_ins_0_gw = nw_ins_0.createNestedArray("gw");
|
||||
JsonArray nw_ins_0_sn = nw_ins_0.createNestedArray("sn");
|
||||
|
||||
for (byte i = 0; i < 4; i++) {
|
||||
nw_ins_0_ip.add(staticIP[i]);
|
||||
nw_ins_0_gw.add(staticGateway[i]);
|
||||
nw_ins_0_sn.add(staticSubnet[i]);
|
||||
JsonArray dns = nw.createNestedArray(F("dns"));
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
dns.add(dnsAddress[i]);
|
||||
}
|
||||
|
||||
JsonObject ap = root.createNestedObject("ap");
|
||||
@ -693,7 +715,7 @@ void serializeConfig() {
|
||||
ap_ip.add(2);
|
||||
ap_ip.add(1);
|
||||
|
||||
JsonObject wifi = root.createNestedObject("wifi");
|
||||
JsonObject wifi = root.createNestedObject(F("wifi"));
|
||||
wifi[F("sleep")] = !noWifiSleep;
|
||||
wifi[F("phy")] = force802_3g;
|
||||
|
||||
@ -721,7 +743,7 @@ void serializeConfig() {
|
||||
}
|
||||
#endif
|
||||
|
||||
JsonObject hw = root.createNestedObject("hw");
|
||||
JsonObject hw = root.createNestedObject(F("hw"));
|
||||
|
||||
JsonObject hw_led = hw.createNestedObject("led");
|
||||
hw_led[F("total")] = strip.getLengthTotal(); //provided for compatibility on downgrade and per-output ABL
|
||||
@ -1048,8 +1070,17 @@ bool deserializeConfigSec() {
|
||||
|
||||
JsonObject root = pDoc->as<JsonObject>();
|
||||
|
||||
JsonObject nw_ins_0 = root["nw"]["ins"][0];
|
||||
getStringFromJson(clientPass, nw_ins_0["psk"], 65);
|
||||
size_t n = 0;
|
||||
JsonArray nw_ins = root["nw"]["ins"];
|
||||
if (!nw_ins.isNull()) {
|
||||
if (nw_ins.size() > 1 && nw_ins.size() > multiWiFi.size()) multiWiFi.resize(nw_ins.size()); // resize constructs objects while resizing
|
||||
for (JsonObject wifi : nw_ins) {
|
||||
char pw[65] = "";
|
||||
getStringFromJson(pw, wifi["psk"], 65);
|
||||
strlcpy(multiWiFi[n].clientPass, pw, 65);
|
||||
if (++n >= WLED_MAX_WIFI_COUNT) break;
|
||||
}
|
||||
}
|
||||
|
||||
JsonObject ap = root["ap"];
|
||||
getStringFromJson(apPass, ap["psk"] , 65);
|
||||
@ -1088,9 +1119,10 @@ void serializeConfigSec() {
|
||||
JsonObject nw = root.createNestedObject("nw");
|
||||
|
||||
JsonArray nw_ins = nw.createNestedArray("ins");
|
||||
|
||||
JsonObject nw_ins_0 = nw_ins.createNestedObject();
|
||||
nw_ins_0["psk"] = clientPass;
|
||||
for (size_t i = 0; i < multiWiFi.size(); i++) {
|
||||
JsonObject wifi = nw_ins.createNestedObject();
|
||||
wifi[F("psk")] = multiWiFi[i].clientPass;
|
||||
}
|
||||
|
||||
JsonObject ap = root.createNestedObject("ap");
|
||||
ap["psk"] = apPass;
|
||||
|
@ -15,6 +15,10 @@
|
||||
#define DEFAULT_MDNS_NAME "x"
|
||||
|
||||
//increase if you need more
|
||||
#ifndef WLED_MAX_WIFI_COUNT
|
||||
#define WLED_MAX_WIFI_COUNT 3
|
||||
#endif
|
||||
|
||||
#ifndef WLED_MAX_USERMODS
|
||||
#ifdef ESP8266
|
||||
#define WLED_MAX_USERMODS 4
|
||||
|
@ -8,7 +8,7 @@
|
||||
var d = document;
|
||||
var loc = false, locip, locproto = "http:";
|
||||
var scanLoops = 0, preScanSSID = "";
|
||||
|
||||
var maxNetworks = 3;
|
||||
function gId(e) { return d.getElementById(e); }
|
||||
function cE(e) { return d.createElement(e); }
|
||||
function toggle(el){gId(el).classList.toggle("hide"); gId('No'+el).classList.toggle("hide");}
|
||||
@ -52,13 +52,13 @@
|
||||
}
|
||||
scanLoops = 0;
|
||||
|
||||
let cs = gId("CS");
|
||||
if (cs) {
|
||||
let cs = d.querySelectorAll("#wifi_entries input[type=text]#CS0");
|
||||
for (let input of (cs||[])) {
|
||||
let select = cE("select");
|
||||
select.setAttribute("id", "CS");
|
||||
select.setAttribute("name", "CS");
|
||||
select.setAttribute("onchange", "T()");
|
||||
preScanSSID = cs.value;
|
||||
select.id = input.id;
|
||||
select.name = input.name;
|
||||
select.setAttribute("onchange", "T(this)");
|
||||
preScanSSID = input.value;
|
||||
|
||||
for (let i = 0; i < select.children.length; i++) {
|
||||
select.removeChild(select.children[i]);
|
||||
@ -70,7 +70,7 @@
|
||||
option.setAttribute("value", networks[i].ssid);
|
||||
option.textContent = `${networks[i].ssid} (${networks[i].rssi} dBm)`;
|
||||
|
||||
if (networks[i].ssid === cs.value) {
|
||||
if (networks[i].ssid === input.value) {
|
||||
option.setAttribute("selected", "selected");
|
||||
}
|
||||
|
||||
@ -79,10 +79,10 @@
|
||||
const option = cE("option");
|
||||
|
||||
option.setAttribute("value", "!Cs");
|
||||
option.textContent = `Other network...`;
|
||||
option.textContent = "Other network...";
|
||||
select.appendChild(option);
|
||||
|
||||
cs.replaceWith(select);
|
||||
input.replaceWith(select);
|
||||
}
|
||||
|
||||
button.disabled = false;
|
||||
@ -90,17 +90,48 @@
|
||||
});
|
||||
}
|
||||
// replace WiFi select with custom SSID input field again
|
||||
function T() {
|
||||
let cs = gId("CS");
|
||||
function T(cs) {
|
||||
if (!cs || cs.value != "!Cs") return;
|
||||
let input = cE("input");
|
||||
input.type = "text";
|
||||
input.id = "CS";
|
||||
input.name ="CS";
|
||||
input.id = cs.id;
|
||||
input.name = cs.name;
|
||||
input.setAttribute("maxlength",32);
|
||||
input.value = preScanSSID;
|
||||
cs.replaceWith(input);
|
||||
}
|
||||
function resetWiFi(maxN = undefined) {
|
||||
if (maxN) maxNetworks = maxN;
|
||||
let entries = gId("wifi_entries").children
|
||||
for (let i = entries.length; i > 0; i--) entries[i-1].remove();
|
||||
btnWiFi(0);
|
||||
}
|
||||
function btnWiFi(i) {
|
||||
gId("wifi_add").style.display = (i<maxNetworks) ? "inline":"none";
|
||||
gId("wifi_rem").style.display = (i>1) ? "inline":"none";
|
||||
}
|
||||
function addWiFi(ssid="",pass="",ip=0,gw=0,sn=0x00ffffff) { // little endian
|
||||
var i = gId("wifi_entries").childNodes.length;
|
||||
if (i >= maxNetworks) return;
|
||||
var b = `<div id="net${i}"><hr class="sml">
|
||||
Network name (SSID${i==0?", empty to not connect":""}):<br><input type="text" id="CS${i}" name="CS${i}" maxlength="32" value="${ssid}" ${i>1?"required":""}><br>
|
||||
Network password:<br><input type="password" name="PW${i}" maxlength="64" value="${pass}"><br>
|
||||
Static IP (leave at 0.0.0.0 for DHCP)${i==0?"<br>Also used by Ethernet":""}:<br>
|
||||
<input name="IP${i}0" type="number" class="s" min="0" max="255" value="${ip&0xFF}" required>.<input name="IP${i}1" type="number" class="s" min="0" max="255" value="${(ip>>8)&0xFF}" required>.<input name="IP${i}2" type="number" class="s" min="0" max="255" value="${(ip>>16)&0xFF}" required>.<input name="IP${i}3" type="number" class="s" min="0" max="255" value="${(ip>>24)&0xFF}" required><br>
|
||||
Static gateway:<br>
|
||||
<input name="GW${i}0" type="number" class="s" min="0" max="255" value="${gw&0xFF}" required>.<input name="GW${i}1" type="number" class="s" min="0" max="255" value="${(gw>>8)&0xFF}" required>.<input name="GW${i}2" type="number" class="s" min="0" max="255" value="${(gw>>16)&0xFF}" required>.<input name="GW${i}3" type="number" class="s" min="0" max="255" value="${(gw>>24)&0xFF}" required><br>
|
||||
Static subnet mask:<br>
|
||||
<input name="SN${i}0" type="number" class="s" min="0" max="255" value="${sn&0xFF}" required>.<input name="SN${i}1" type="number" class="s" min="0" max="255" value="${(sn>>8)&0xFF}" required>.<input name="SN${i}2" type="number" class="s" min="0" max="255" value="${(sn>>16)&0xFF}" required>.<input name="SN${i}3" type="number" class="s" min="0" max="255" value="${(sn>>24)&0xFF}" required></div>`;
|
||||
gId("wifi_entries").insertAdjacentHTML("beforeend", b);
|
||||
btnWiFi(i+1);
|
||||
}
|
||||
function remWiFi() {
|
||||
const entries = gId("wifi_entries").children;
|
||||
const i = entries.length;
|
||||
if (i < 2) return;
|
||||
entries[i-1].remove();
|
||||
btnWiFi(i-1);
|
||||
}
|
||||
// https://www.educative.io/edpresso/how-to-dynamically-load-a-js-file-in-javascript
|
||||
function loadJS(FILE_URL, async = true) {
|
||||
let scE = cE("script");
|
||||
@ -158,24 +189,16 @@
|
||||
<h2>WiFi setup</h2>
|
||||
<h3>Connect to existing network</h3>
|
||||
<button type="button" id="scan" onclick="N()">Scan</button><br>
|
||||
Network name (SSID, empty to not connect):<br>
|
||||
<input type="text" id="CS" name="CS" maxlength="32"><br>
|
||||
Network password: <br> <input type="password" name="CP" maxlength="63"><br>
|
||||
Static IP (leave at 0.0.0.0 for DHCP):<br>
|
||||
<input name="I0" type="number" class="s" min="0" max="255" required> .
|
||||
<input name="I1" type="number" class="s" min="0" max="255" required> .
|
||||
<input name="I2" type="number" class="s" min="0" max="255" required> .
|
||||
<input name="I3" type="number" class="s" min="0" max="255" required><br>
|
||||
Static gateway:<br>
|
||||
<input name="G0" type="number" class="s" min="0" max="255" required> .
|
||||
<input name="G1" type="number" class="s" min="0" max="255" required> .
|
||||
<input name="G2" type="number" class="s" min="0" max="255" required> .
|
||||
<input name="G3" type="number" class="s" min="0" max="255" required><br>
|
||||
Static subnet mask:<br>
|
||||
<input name="S0" type="number" class="s" min="0" max="255" required> .
|
||||
<input name="S1" type="number" class="s" min="0" max="255" required> .
|
||||
<input name="S2" type="number" class="s" min="0" max="255" required> .
|
||||
<input name="S3" type="number" class="s" min="0" max="255" required><br>
|
||||
<div id="wifi">
|
||||
Wireless networks
|
||||
<div id="wifi_entries"></div>
|
||||
<hr class="sml">
|
||||
<button type="button" id="wifi_add" onclick="addWiFi()">+</button>
|
||||
<button type="button" id="wifi_rem" onclick="remWiFi()">-</button><br>
|
||||
</div>
|
||||
DNS server address:<br>
|
||||
<input name="D0" type="number" class="s" min="0" max="255" required>.<input name="D1" type="number" class="s" min="0" max="255" required>.<input name="D2" type="number" class="s" min="0" max="255" required>.<input name="D3" type="number" class="s" min="0" max="255" required><br>
|
||||
<br>
|
||||
mDNS address (leave empty for no mDNS):<br>
|
||||
http:// <input type="text" name="CM" maxlength="32"> .local<br>
|
||||
Client IP: <span class="sip"> Not connected </span> <br>
|
||||
|
@ -490,7 +490,7 @@ void prepareArtnetPollReply(ArtPollReply *reply) {
|
||||
// Node is DHCP capable
|
||||
// Node supports 15 bit Port-Address (Art-Net 3 or 4)
|
||||
// Node is able to switch between ArtNet and sACN
|
||||
reply->reply_status_2 = (staticIP[0] == 0) ? 0x1F : 0x1D;
|
||||
reply->reply_status_2 = (multiWiFi[0].staticIP[0] == 0) ? 0x1F : 0x1D;
|
||||
|
||||
// RDM is disabled
|
||||
// Output style is continuous
|
||||
|
@ -48,6 +48,21 @@ bool getJsonValue(const JsonVariant& element, DestType& destination, const Defau
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef struct WiFiConfig {
|
||||
char clientSSID[33];
|
||||
char clientPass[65];
|
||||
IPAddress staticIP;
|
||||
IPAddress staticGW;
|
||||
IPAddress staticSN;
|
||||
WiFiConfig(const char *ssid="", const char *pass="", uint32_t ip=0, uint32_t gw=0, uint32_t subnet=0x00FFFFFF) // little endian
|
||||
: staticIP(ip)
|
||||
, staticGW(gw)
|
||||
, staticSN(subnet)
|
||||
{
|
||||
strncpy(clientSSID, ssid, 32); clientSSID[32] = 0;
|
||||
strncpy(clientPass, pass, 64); clientPass[64] = 0;
|
||||
}
|
||||
} wifi_config;
|
||||
|
||||
//colors.cpp
|
||||
// similar to NeoPixelBus NeoGammaTableMethod but allows dynamic changes (superseded by NPB::NeoGammaDynamicTableMethod)
|
||||
|
@ -259,14 +259,14 @@ void parseWiFiCommand(char* rpcData) {
|
||||
|
||||
uint8_t ssidLen = rpcData[1];
|
||||
if (ssidLen > len -1 || ssidLen > 32) return;
|
||||
memset(clientSSID, 0, 32);
|
||||
memcpy(clientSSID, rpcData+2, ssidLen);
|
||||
memset(multiWiFi[0].clientSSID, 0, 32);
|
||||
memcpy(multiWiFi[0].clientSSID, rpcData+2, ssidLen);
|
||||
|
||||
memset(clientPass, 0, 64);
|
||||
memset(multiWiFi[0].clientPass, 0, 64);
|
||||
if (len > ssidLen +1) {
|
||||
uint8_t passLen = rpcData[2+ssidLen];
|
||||
memset(clientPass, 0, 64);
|
||||
memcpy(clientPass, rpcData+3+ssidLen, passLen);
|
||||
memset(multiWiFi[0].clientPass, 0, 64);
|
||||
memcpy(multiWiFi[0].clientPass, rpcData+3+ssidLen, passLen);
|
||||
}
|
||||
|
||||
sendImprovStateResponse(0x03); //provisioning
|
||||
|
@ -163,8 +163,8 @@ void WiFiEvent(WiFiEvent_t event)
|
||||
if (!apActive) {
|
||||
WiFi.disconnect(true);
|
||||
}
|
||||
if (staticIP != (uint32_t)0x00000000 && staticGateway != (uint32_t)0x00000000) {
|
||||
ETH.config(staticIP, staticGateway, staticSubnet, IPAddress(8, 8, 8, 8));
|
||||
if (multiWiFi[0].staticIP != (uint32_t)0x00000000 && multiWiFi[0].staticGW != (uint32_t)0x00000000) {
|
||||
ETH.config(multiWiFi[0].staticIP, multiWiFi[0].staticGW, multiWiFi[0].staticSN, dnsAddress);
|
||||
} else {
|
||||
ETH.config(INADDR_NONE, INADDR_NONE, INADDR_NONE);
|
||||
}
|
||||
|
@ -19,15 +19,40 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
//WIFI SETTINGS
|
||||
if (subPage == SUBPAGE_WIFI)
|
||||
{
|
||||
char oldSSID[sizeof(clientSSID)];
|
||||
char oldSSID[33];
|
||||
strlcpy(oldSSID, multiWiFi[0].clientSSID, 33);
|
||||
for (size_t n = 0; n < WLED_MAX_WIFI_COUNT; n++) {
|
||||
char cs[4] = "CS"; cs[2] = 48+n; cs[3] = 0; //client SSID
|
||||
char pw[4] = "PW"; pw[2] = 48+n; pw[3] = 0; //client password
|
||||
char ip[5] = "IP"; ip[2] = 48+n; ip[4] = 0; //IP address
|
||||
char gw[5] = "GW"; gw[2] = 48+n; gw[4] = 0; //GW address
|
||||
char sn[5] = "SN"; sn[2] = 48+n; sn[4] = 0; //subnet mask
|
||||
if (request->hasArg(cs)) {
|
||||
if (n >= multiWiFi.size()) multiWiFi.push_back(WiFiConfig());
|
||||
char oldSSID[33]; strcpy(oldSSID, multiWiFi[n].clientSSID);
|
||||
char oldPass[65]; strcpy(oldPass, multiWiFi[n].clientPass);
|
||||
if (!strncmp(request->arg(cs).c_str(), oldSSID, 32)) {
|
||||
strlcpy(multiWiFi[n].clientSSID, request->arg(cs).c_str(), 33);
|
||||
forceReconnect = true;
|
||||
}
|
||||
if (!isAsterisksOnly(request->arg(pw).c_str(), 65)) {
|
||||
strlcpy(multiWiFi[n].clientPass, request->arg(pw).c_str(), 65);
|
||||
forceReconnect = true;
|
||||
}
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
ip[3] = 48+i;
|
||||
gw[3] = 48+i;
|
||||
sn[3] = 48+i;
|
||||
multiWiFi[n].staticIP[i] = request->arg(ip).toInt();
|
||||
multiWiFi[n].staticGW[i] = request->arg(gw).toInt();
|
||||
multiWiFi[n].staticSN[i] = request->arg(sn).toInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(oldSSID, clientSSID);
|
||||
strlcpy(clientSSID,request->arg(F("CS")).c_str(), 33);
|
||||
if (!strcmp(oldSSID, clientSSID)) forceReconnect = true;
|
||||
|
||||
if (!isAsterisksOnly(request->arg(F("CP")).c_str(), 65)) {
|
||||
strlcpy(clientPass, request->arg(F("CP")).c_str(), 65);
|
||||
forceReconnect = true;
|
||||
if (request->hasArg(F("D0"))) {
|
||||
dnsAddress = IPAddress(request->arg(F("D0")).toInt(),request->arg(F("D1")).toInt(),request->arg(F("D2")).toInt(),request->arg(F("D3")).toInt());
|
||||
DEBUG_PRINTLN(dnsAddress);
|
||||
}
|
||||
|
||||
strlcpy(cmDNS, request->arg(F("CM")).c_str(), 33);
|
||||
@ -61,21 +86,6 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
ethernetType = request->arg(F("ETH")).toInt();
|
||||
WLED::instance().initEthernet();
|
||||
#endif
|
||||
|
||||
char k[3]; k[2] = 0;
|
||||
for (int i = 0; i<4; i++)
|
||||
{
|
||||
k[1] = i+48;//ascii 0,1,2,3
|
||||
|
||||
k[0] = 'I'; //static IP
|
||||
staticIP[i] = request->arg(k).toInt();
|
||||
|
||||
k[0] = 'G'; //gateway
|
||||
staticGateway[i] = request->arg(k).toInt();
|
||||
|
||||
k[0] = 'S'; //subnet
|
||||
staticSubnet[i] = request->arg(k).toInt();
|
||||
}
|
||||
}
|
||||
|
||||
//LED SETTINGS
|
||||
|
@ -424,6 +424,7 @@ void WLED::setup()
|
||||
escapedMac.toLowerCase();
|
||||
|
||||
WLED_SET_AP_SSID(); // otherwise it is empty on first boot until config is saved
|
||||
multiWiFi.push_back(WiFiConfig(CLIENT_SSID,CLIENT_PASS)); // initialise vector with default WiFi
|
||||
|
||||
DEBUG_PRINTLN(F("Reading config"));
|
||||
deserializeConfigFromFS();
|
||||
@ -445,7 +446,7 @@ void WLED::setup()
|
||||
usermods.setup();
|
||||
DEBUG_PRINT(F("heap ")); DEBUG_PRINTLN(ESP.getFreeHeap());
|
||||
|
||||
if (strcmp(clientSSID, DEFAULT_CLIENT_SSID) == 0)
|
||||
if (strcmp(multiWiFi[0].clientSSID, DEFAULT_CLIENT_SSID) == 0)
|
||||
showWelcomePage = true;
|
||||
WiFi.persistent(false);
|
||||
#ifdef WLED_USE_ETHERNET
|
||||
@ -719,8 +720,8 @@ void WLED::initConnection()
|
||||
WiFi.setPhyMode(force802_3g ? WIFI_PHY_MODE_11G : WIFI_PHY_MODE_11N);
|
||||
#endif
|
||||
|
||||
if (staticIP[0] != 0 && staticGateway[0] != 0) {
|
||||
WiFi.config(staticIP, staticGateway, staticSubnet, IPAddress(1, 1, 1, 1));
|
||||
if (multiWiFi[selectedWiFi].staticIP != 0U && multiWiFi[selectedWiFi].staticGW != 0U) {
|
||||
WiFi.config(multiWiFi[selectedWiFi].staticIP, multiWiFi[selectedWiFi].staticGW, multiWiFi[selectedWiFi].staticSN, dnsAddress);
|
||||
} else {
|
||||
WiFi.config(IPAddress((uint32_t)0), IPAddress((uint32_t)0), IPAddress((uint32_t)0));
|
||||
}
|
||||
@ -745,13 +746,13 @@ void WLED::initConnection()
|
||||
showWelcomePage = false;
|
||||
|
||||
DEBUG_PRINT(F("Connecting to "));
|
||||
DEBUG_PRINT(clientSSID);
|
||||
DEBUG_PRINT(multiWiFi[selectedWiFi].clientSSID);
|
||||
DEBUG_PRINTLN("...");
|
||||
|
||||
// convert the "serverDescription" into a valid DNS hostname (alphanumeric)
|
||||
char hostname[25];
|
||||
prepareHostname(hostname);
|
||||
WiFi.begin(clientSSID, clientPass);
|
||||
WiFi.begin(multiWiFi[selectedWiFi].clientSSID, multiWiFi[selectedWiFi].clientPass);
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
#if defined(LOLIN_WIFI_FIX) && (defined(ARDUINO_ARCH_ESP32C3) || defined(ARDUINO_ARCH_ESP32S2) || defined(ARDUINO_ARCH_ESP32S3))
|
||||
WiFi.setTxPower(WIFI_POWER_8_5dBm);
|
||||
@ -851,8 +852,9 @@ void WLED::handleConnection()
|
||||
if (now < 2000 && (!WLED_WIFI_CONFIGURED || apBehavior == AP_BEHAVIOR_ALWAYS))
|
||||
return;
|
||||
|
||||
if (lastReconnectAttempt == 0) {
|
||||
DEBUG_PRINTLN(F("lastReconnectAttempt == 0"));
|
||||
if (lastReconnectAttempt == 0 || forceReconnect) {
|
||||
DEBUG_PRINTLN(F("Initial connect or forced reconnect."));
|
||||
if (forceReconnect) selectedWiFi = 0;
|
||||
initConnection();
|
||||
return;
|
||||
}
|
||||
@ -915,6 +917,7 @@ void WLED::handleConnection()
|
||||
if (now - lastReconnectAttempt > ((stac) ? 300000 : 18000) && WLED_WIFI_CONFIGURED) {
|
||||
if (improvActive == 2) improvActive = 3;
|
||||
DEBUG_PRINTLN(F("Last reconnect too old."));
|
||||
if (++selectedWiFi >= multiWiFi.size()) selectedWiFi = 0;
|
||||
initConnection();
|
||||
}
|
||||
if (!apActive && now - lastReconnectAttempt > 12000 && (!wasConnected || apBehavior == AP_BEHAVIOR_NO_CONN)) {
|
||||
|
@ -304,22 +304,21 @@ WLED_GLOBAL int8_t irPin _INIT(IRPIN);
|
||||
WLED_GLOBAL char ntpServerName[33] _INIT("0.wled.pool.ntp.org"); // NTP server to use
|
||||
|
||||
// WiFi CONFIG (all these can be changed via web UI, no need to set them here)
|
||||
WLED_GLOBAL char clientSSID[33] _INIT(CLIENT_SSID);
|
||||
WLED_GLOBAL char clientPass[65] _INIT(CLIENT_PASS);
|
||||
WLED_GLOBAL char cmDNS[33] _INIT(MDNS_NAME); // mDNS address (*.local, replaced by wledXXXXXX if default is used)
|
||||
WLED_GLOBAL char apSSID[33] _INIT(""); // AP off by default (unless setup)
|
||||
WLED_GLOBAL byte apChannel _INIT(1); // 2.4GHz WiFi AP channel (1-13)
|
||||
WLED_GLOBAL byte apHide _INIT(0); // hidden AP SSID
|
||||
WLED_GLOBAL byte apBehavior _INIT(AP_BEHAVIOR_BOOT_NO_CONN); // access point opens when no connection after boot by default
|
||||
WLED_GLOBAL IPAddress staticIP _INIT_N((( 0, 0, 0, 0))); // static IP of ESP
|
||||
WLED_GLOBAL IPAddress staticGateway _INIT_N((( 0, 0, 0, 0))); // gateway (router) IP
|
||||
WLED_GLOBAL IPAddress staticSubnet _INIT_N(((255, 255, 255, 0))); // most common subnet in home networks
|
||||
WLED_GLOBAL uint8_t selectedWiFi _INIT(0);
|
||||
WLED_GLOBAL std::vector<WiFiConfig> multiWiFi;
|
||||
WLED_GLOBAL IPAddress dnsAddress _INIT_N((( 8, 8, 8, 8))); // Google's DNS
|
||||
WLED_GLOBAL char cmDNS[33] _INIT(MDNS_NAME); // mDNS address (*.local, replaced by wledXXXXXX if default is used)
|
||||
WLED_GLOBAL char apSSID[33] _INIT(""); // AP off by default (unless setup)
|
||||
WLED_GLOBAL byte apChannel _INIT(1); // 2.4GHz WiFi AP channel (1-13)
|
||||
WLED_GLOBAL byte apHide _INIT(0); // hidden AP SSID
|
||||
WLED_GLOBAL byte apBehavior _INIT(AP_BEHAVIOR_BOOT_NO_CONN); // access point opens when no connection after boot by default
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
WLED_GLOBAL bool noWifiSleep _INIT(true); // disabling modem sleep modes will increase heat output and power usage, but may help with connection issues
|
||||
WLED_GLOBAL bool noWifiSleep _INIT(true); // disabling modem sleep modes will increase heat output and power usage, but may help with connection issues
|
||||
#else
|
||||
WLED_GLOBAL bool noWifiSleep _INIT(false);
|
||||
#endif
|
||||
WLED_GLOBAL bool force802_3g _INIT(false);
|
||||
#define WLED_WIFI_CONFIGURED (strlen(multiWiFi[0].clientSSID) >= 1 && strcmp(multiWiFi[0].clientSSID, DEFAULT_CLIENT_SSID) != 0)
|
||||
|
||||
#ifdef WLED_USE_ETHERNET
|
||||
#ifdef WLED_ETH_DEFAULT // default ethernet board type if specified
|
||||
@ -833,7 +832,6 @@ WLED_GLOBAL volatile uint8_t jsonBufferLock _INIT(0);
|
||||
#else
|
||||
#define WLED_CONNECTED (WiFi.status() == WL_CONNECTED)
|
||||
#endif
|
||||
#define WLED_WIFI_CONFIGURED (strlen(clientSSID) >= 1 && strcmp(clientSSID, DEFAULT_CLIENT_SSID) != 0)
|
||||
|
||||
#ifndef WLED_AP_SSID_UNIQUE
|
||||
#define WLED_SET_AP_SSID() do { \
|
||||
|
@ -74,11 +74,11 @@ void loadSettingsFromEEPROM()
|
||||
int lastEEPROMversion = EEPROM.read(377); //last EEPROM version before update
|
||||
|
||||
|
||||
readStringFromEEPROM( 0, clientSSID, 32);
|
||||
readStringFromEEPROM( 32, clientPass, 64);
|
||||
readStringFromEEPROM( 96, cmDNS, 32);
|
||||
readStringFromEEPROM(128, apSSID, 32);
|
||||
readStringFromEEPROM(160, apPass, 64);
|
||||
readStringFromEEPROM( 0, multiWiFi[0].clientSSID, 32);
|
||||
readStringFromEEPROM( 32, multiWiFi[0].clientPass, 64);
|
||||
readStringFromEEPROM( 96, cmDNS, 32);
|
||||
readStringFromEEPROM(128, apSSID, 32);
|
||||
readStringFromEEPROM(160, apPass, 64);
|
||||
|
||||
nightlightDelayMinsDefault = EEPROM.read(224);
|
||||
nightlightDelayMins = nightlightDelayMinsDefault;
|
||||
|
@ -248,23 +248,34 @@ void getSettingsJS(byte subPage, char* dest)
|
||||
|
||||
if (subPage == SUBPAGE_WIFI)
|
||||
{
|
||||
sappends('s',SET_F("CS"),clientSSID);
|
||||
|
||||
byte l = strlen(clientPass);
|
||||
char fpass[l+1]; //fill password field with ***
|
||||
fpass[l] = 0;
|
||||
memset(fpass,'*',l);
|
||||
sappends('s',SET_F("CP"),fpass);
|
||||
|
||||
char k[3]; k[2] = 0; //IP addresses
|
||||
for (int i = 0; i<4; i++)
|
||||
{
|
||||
k[1] = 48+i; //ascii 0,1,2,3
|
||||
k[0] = 'I'; sappend('v',k,staticIP[i]);
|
||||
k[0] = 'G'; sappend('v',k,staticGateway[i]);
|
||||
k[0] = 'S'; sappend('v',k,staticSubnet[i]);
|
||||
char nS[10];
|
||||
size_t l;
|
||||
oappend(SET_F("resetWiFi("));
|
||||
oappend(itoa(WLED_MAX_WIFI_COUNT,nS,10));
|
||||
oappend(SET_F(");"));
|
||||
for (size_t n = 0; n < multiWiFi.size(); n++) {
|
||||
l = strlen(multiWiFi[n].clientPass);
|
||||
char fpass[l+1]; //fill password field with ***
|
||||
fpass[l] = 0;
|
||||
memset(fpass,'*',l);
|
||||
oappend(SET_F("addWiFi(\""));
|
||||
oappend(multiWiFi[n].clientSSID);
|
||||
oappend(SET_F("\",\""));
|
||||
oappend(fpass);
|
||||
oappend(SET_F("\",0x"));
|
||||
oappend(itoa(multiWiFi[n].staticIP,nS,16));
|
||||
oappend(SET_F(",0x"));
|
||||
oappend(itoa(multiWiFi[n].staticGW,nS,16));
|
||||
oappend(SET_F(",0x"));
|
||||
oappend(itoa(multiWiFi[n].staticSN,nS,16));
|
||||
oappend(SET_F(");"));
|
||||
}
|
||||
|
||||
sappend('v',SET_F("D0"),dnsAddress[0]);
|
||||
sappend('v',SET_F("D1"),dnsAddress[1]);
|
||||
sappend('v',SET_F("D2"),dnsAddress[2]);
|
||||
sappend('v',SET_F("D3"),dnsAddress[3]);
|
||||
|
||||
sappends('s',SET_F("CM"),cmDNS);
|
||||
sappend('i',SET_F("AB"),apBehavior);
|
||||
sappends('s',SET_F("AS"),apSSID);
|
||||
|
Loading…
x
Reference in New Issue
Block a user