Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions wled00/cfg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,17 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
multiWiFi[n].staticIP = nIP;
multiWiFi[n].staticGW = nGW;
multiWiFi[n].staticSN = nSN;
#ifdef WLED_ENABLE_WPA_ENTERPRISE
byte encType = WIFI_ENCRYPTION_TYPE_PSK;
char anonIdent[65] = "";
char ident[65] = "";
CJSON(encType, wifi[F("enc_type")]);
getStringFromJson(anonIdent, wifi["e_anon_ident"], 65);
getStringFromJson(ident, wifi["e_ident"], 65);
multiWiFi[n].encryptionType = encType;
strlcpy(multiWiFi[n].enterpriseAnonIdentity, anonIdent, 65);
strlcpy(multiWiFi[n].enterpriseIdentity, ident, 65);
#endif
if (++n >= WLED_MAX_WIFI_COUNT) break;
}
}
Expand Down Expand Up @@ -870,6 +881,13 @@ void serializeConfig(JsonObject root) {
wifi_gw.add(multiWiFi[n].staticGW[i]);
wifi_sn.add(multiWiFi[n].staticSN[i]);
}
#ifdef WLED_ENABLE_WPA_ENTERPRISE
wifi[F("enc_type")] = multiWiFi[n].encryptionType;
if (multiWiFi[n].encryptionType == WIFI_ENCRYPTION_TYPE_ENTERPRISE) {
wifi[F("e_anon_ident")] = multiWiFi[n].enterpriseAnonIdentity;
wifi[F("e_ident")] = multiWiFi[n].enterpriseIdentity;
}
#endif
}

JsonArray dns = nw.createNestedArray(F("dns"));
Expand Down
6 changes: 6 additions & 0 deletions wled00/const.h
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,12 @@ static_assert(WLED_MAX_BUSSES <= 32, "WLED_MAX_BUSSES exceeds hard limit");
#define USERMOD_ID_BRIGHTNESS_FOLLOW_SUN 57 //Usermod "usermod_v2_brightness_follow_sun.h"
#define USERMOD_ID_USER_FX 58 //Usermod "user_fx"

//Wifi encryption type
#ifdef WLED_ENABLE_WPA_ENTERPRISE
#define WIFI_ENCRYPTION_TYPE_PSK 0 //None/WPA/WPA2
#define WIFI_ENCRYPTION_TYPE_ENTERPRISE 1 //WPA/WPA2-Enterprise
#endif

//Access point behavior
#define AP_BEHAVIOR_BOOT_NO_CONN 0 //Open AP when no connection after boot
#define AP_BEHAVIOR_NO_CONN 1 //Open when no connection (either after boot or if connection is lost)
Expand Down
23 changes: 22 additions & 1 deletion wled00/data/settings_wifi.htm
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,24 @@
gId("wifi_add").style.display = (i<maxNetworks) ? "inline":"none";
gId("wifi_rem").style.display = (i>1) ? "inline":"none";
}
function addWiFi(ssid="",pass="",bssid="",ip=0,gw=0,sn=0x00ffffff) { // little endian
function addWiFi(ssid="",pass="",bssid="",ip=0,gw=0,sn=0x00ffffff,type=-1,anon="",ident="") { // little endian
var i = gId("wifi_entries").childNodes.length;
if (i >= maxNetworks) return;
var encryptionTypeField = "";
if (type >=0 && type < 2) {
encryptionTypeField = `WiFi encryption type:<br>
<select id="ET${i}" name="ET${i}" onchange="E(${i})">
<option value="0"${(type==0) ? ' selected':''}>None/WPA/WPA2</option>
<option value="1"${(type==1) ? ' selected':''}>WPA/WPA2-Enterprise</option>
</select><br>
<div id="IDS${i}" style="${(type==0) ? 'display:none;':''}">
Anonymous identity:<br><input type="text" id="EA${i}" name="EA${i}" maxlength="64" value="${anon}"><br>
Identity:<br><input type="text" id="EI${i}" name="EI${i}" maxlength="64" value="${ident}"><br>
</div>`;
}
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>0?"required":""}><br>
${encryptionTypeField}
Network password:<br><input type="password" name="PW${i}" maxlength="64" value="${pass}"><br>
BSSID (optional):<br><input type="text" id="BS${i}" name="BS${i}" maxlength="12" value="${bssid}"><br>
Static IP (leave at 0.0.0.0 for DHCP)${i==0?"<br>Also used by Ethernet":""}:<br>
Expand Down Expand Up @@ -185,6 +198,14 @@
rC++;
gId('+').style.display = gId("rml").childElementCount < 10 ? 'inline' : 'none'; // can't append to list anymore, hide button
}
function E(i) {
const select = gId("ET"+i);
if (select.value === "0") {
gId("IDS"+i).style.display = "none";
} else {
gId("IDS"+i).style.display = "";
}
}

</script>
</head>
Expand Down
13 changes: 13 additions & 0 deletions wled00/fcn_declare.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,26 @@ typedef struct WiFiConfig {
IPAddress staticIP;
IPAddress staticGW;
IPAddress staticSN;
#ifdef WLED_ENABLE_WPA_ENTERPRISE
byte encryptionType;
char enterpriseAnonIdentity[65];
char enterpriseIdentity[65];
WiFiConfig(const char *ssid="", const char *pass="", uint32_t ip=0, uint32_t gw=0, uint32_t subnet=0x00FFFFFF // little endian
, byte enc_type=WIFI_ENCRYPTION_TYPE_PSK, const char *ent_anon="", const char *ent_iden="")
#else
WiFiConfig(const char *ssid="", const char *pass="", uint32_t ip=0, uint32_t gw=0, uint32_t subnet=0x00FFFFFF) // little endian
#endif
: staticIP(ip)
, staticGW(gw)
, staticSN(subnet)
{
strncpy(clientSSID, ssid, 32); clientSSID[32] = 0;
strncpy(clientPass, pass, 64); clientPass[64] = 0;
#ifdef WLED_ENABLE_WPA_ENTERPRISE
encryptionType = enc_type;
strncpy(enterpriseAnonIdentity, ent_anon, 64); enterpriseAnonIdentity[64] = 0;
strncpy(enterpriseIdentity, ent_iden, 64); enterpriseIdentity[64] = 0;
#endif
memset(bssid, 0, sizeof(bssid));
}
} wifi_config;
Expand Down
35 changes: 34 additions & 1 deletion wled00/set.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,18 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
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
#ifdef WLED_ENABLE_WPA_ENTERPRISE
char et[4] = "ET"; et[2] = 48+n; et[3] = 0; //WiFi encryption type
char ea[4] = "EA"; ea[2] = 48+n; ea[3] = 0; //enterprise anonymous identity
char ei[4] = "EI"; ei[2] = 48+n; ei[3] = 0; //enterprise identity
#endif
if (request->hasArg(cs)) {
if (n >= multiWiFi.size()) multiWiFi.emplace_back(); // expand vector by one
char oldSSID[33]; strcpy(oldSSID, multiWiFi[n].clientSSID);
char oldPass[65]; strcpy(oldPass, multiWiFi[n].clientPass);

strlcpy(multiWiFi[n].clientSSID, request->arg(cs).c_str(), 33);
if (strlen(oldSSID) == 0 || !strncmp(multiWiFi[n].clientSSID, oldSSID, 32)) {
if (strlen(oldSSID) == 0 || strncmp(multiWiFi[n].clientSSID, oldSSID, 32) != 0) {
forceReconnect = true;
}
if (!isAsterisksOnly(request->arg(pw).c_str(), 65)) {
Expand All @@ -49,6 +54,34 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
multiWiFi[n].staticGW[i] = request->arg(gw).toInt();
multiWiFi[n].staticSN[i] = request->arg(sn).toInt();
}

#ifdef WLED_ENABLE_WPA_ENTERPRISE
byte oldType = multiWiFi[n].encryptionType;
char oldAnon[65]; strcpy(oldAnon, multiWiFi[n].enterpriseAnonIdentity);
char oldIden[65]; strcpy(oldIden, multiWiFi[n].enterpriseIdentity);
if (request->hasArg(et) && request->hasArg(ea) && request->hasArg(ei)) {
multiWiFi[n].encryptionType = request->arg(et).toInt();
strlcpy(multiWiFi[n].enterpriseAnonIdentity, request->arg(ea).c_str(), 65);
strlcpy(multiWiFi[n].enterpriseIdentity, request->arg(ei).c_str(), 65);
} else {
// No enterprise settings provided, default to PSK
multiWiFi[n].encryptionType = WIFI_ENCRYPTION_TYPE_PSK;
}

if (multiWiFi[n].encryptionType == WIFI_ENCRYPTION_TYPE_PSK) {
// PSK - Clear the anonymous identity and identity fields
multiWiFi[n].enterpriseAnonIdentity[0] = '\0';
multiWiFi[n].enterpriseIdentity[0] = '\0';
}
forceReconnect |= oldType != multiWiFi[n].encryptionType;
if (strncmp(multiWiFi[n].enterpriseAnonIdentity, oldAnon, 64) != 0) {
forceReconnect = true;
}
if (strncmp(multiWiFi[n].enterpriseIdentity, oldIden, 64) != 0) {
forceReconnect = true;
}
#endif

cnt++;
}
}
Expand Down
32 changes: 32 additions & 0 deletions wled00/wled.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -689,7 +689,39 @@ void WLED::initConnection()
// convert the "serverDescription" into a valid DNS hostname (alphanumeric)
char hostname[25];
prepareHostname(hostname);

#ifdef WLED_ENABLE_WPA_ENTERPRISE
if (multiWiFi[selectedWiFi].encryptionType == WIFI_ENCRYPTION_TYPE_PSK) {
DEBUG_PRINTLN(F("Using PSK"));
#ifdef ESP8266
wifi_station_set_wpa2_enterprise_auth(0);
wifi_station_clear_enterprise_ca_cert();
wifi_station_clear_enterprise_cert_key();
wifi_station_clear_enterprise_identity();
wifi_station_clear_enterprise_username();
wifi_station_clear_enterprise_password();
#endif
WiFi.begin(multiWiFi[selectedWiFi].clientSSID, multiWiFi[selectedWiFi].clientPass);
} else { // WIFI_ENCRYPTION_TYPE_ENTERPRISE
DEBUG_PRINTF_P(PSTR("Using WPA2_AUTH_PEAP (Anon: %s, Ident: %s)\n"), multiWiFi[selectedWiFi].enterpriseAnonIdentity, multiWiFi[selectedWiFi].enterpriseIdentity);
#ifdef ESP8266
struct station_config sta_conf;
os_memset(&sta_conf, 0, sizeof(sta_conf));
os_memcpy(sta_conf.ssid, multiWiFi[selectedWiFi].clientSSID, 32);
os_memcpy(sta_conf.password, multiWiFi[selectedWiFi].clientPass, 64);
wifi_station_set_config(&sta_conf);
wifi_station_set_wpa2_enterprise_auth(1);
wifi_station_set_enterprise_identity((u8*)(void*)multiWiFi[selectedWiFi].enterpriseAnonIdentity, os_strlen(multiWiFi[selectedWiFi].enterpriseAnonIdentity));
wifi_station_set_enterprise_username((u8*)(void*)multiWiFi[selectedWiFi].enterpriseIdentity, os_strlen(multiWiFi[selectedWiFi].enterpriseIdentity));
wifi_station_set_enterprise_password((u8*)(void*)multiWiFi[selectedWiFi].clientPass, os_strlen(multiWiFi[selectedWiFi].clientPass));
wifi_station_connect();
#else
WiFi.begin(multiWiFi[selectedWiFi].clientSSID, WPA2_AUTH_PEAP, multiWiFi[selectedWiFi].enterpriseAnonIdentity, multiWiFi[selectedWiFi].enterpriseIdentity, multiWiFi[selectedWiFi].clientPass);
#endif
}
#else // WLED_ENABLE_WPA_ENTERPRISE
WiFi.begin(multiWiFi[selectedWiFi].clientSSID, multiWiFi[selectedWiFi].clientPass); // no harm if called multiple times
#endif // WLED_ENABLE_WPA_ENTERPRISE

#ifdef ARDUINO_ARCH_ESP32
WiFi.setTxPower(wifi_power_t(txPower));
Expand Down
3 changes: 3 additions & 0 deletions wled00/wled.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@
#include <Arduino.h>
#ifdef ESP8266
#include <ESP8266WiFi.h>
#ifdef WLED_ENABLE_WPA_ENTERPRISE
#include "wpa2_enterprise.h"
#endif
#include <ESP8266mDNS.h>
#include <ESPAsyncTCP.h>
#include <LittleFS.h>
Expand Down
13 changes: 13 additions & 0 deletions wled00/xml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,13 +198,26 @@ void getSettingsJS(byte subPage, Print& settingsScript)
memset(fpass,'*',l);
char bssid[13];
fillMAC2Str(bssid, multiWiFi[n].bssid);
#ifdef WLED_ENABLE_WPA_ENTERPRISE
settingsScript.printf_P(PSTR("addWiFi(\"%s\",\"%s\",\"%s\",0x%X,0x%X,0x%X,\"%u\",\"%s\",\"%s\");"),
multiWiFi[n].clientSSID,
fpass,
bssid,
(uint32_t) multiWiFi[n].staticIP, // explicit cast required as this is a struct
(uint32_t) multiWiFi[n].staticGW,
(uint32_t) multiWiFi[n].staticSN,
multiWiFi[n].encryptionType,
multiWiFi[n].enterpriseAnonIdentity,
multiWiFi[n].enterpriseIdentity);
#else
settingsScript.printf_P(PSTR("addWiFi(\"%s\",\"%s\",\"%s\",0x%X,0x%X,0x%X);"),
multiWiFi[n].clientSSID,
fpass,
bssid,
(uint32_t) multiWiFi[n].staticIP, // explicit cast required as this is a struct
(uint32_t) multiWiFi[n].staticGW,
(uint32_t) multiWiFi[n].staticSN);
#endif
}

printSetFormValue(settingsScript,PSTR("D0"),dnsAddress[0]);
Expand Down