#if defined(ESP32) # include // duvod resetu (https://github.com/espressif/arduino-esp32/issues/449) #endif #include "WiFiConfig.h" #include #include "embHTML.h" #include #include #ifndef USEDFS # if defined(ESP32) # ifdef USE_LITTLEFS # include # define USEDFS LITTLEFS # else # include # define USEDFS SPIFFS # endif # else # include # define USEDFS LittleFS # endif #endif #ifdef USE_WIFICONFIG_FSEDITOR # include # include #endif #if defined(ESP8266) // ESP8266 # define SETHOSTNAME(a) WiFi.hostname(a) #else // ESP32 # define SETHOSTNAME(a) WiFi.setHostname(a) #endif #ifdef DEBUG_ESP_PORT # define DEBUG_MSG(_1, ...) DEBUG_ESP_PORT.printf_P(PSTR(_1), ##__VA_ARGS__) #else # define DEBUG_MSG(...) #endif #if defined(ESP8266) extern "C" { # include "user_interface.h" } #else # include #endif #define DNS_PORT 53 extern char WiFiDeviceName[]; static const char CHECKED[] PROGMEM = "checked='checked'"; static bool _doReconfig = false; // TODO: mozna nejak elegantneji? Ale zase setrime RAM... static uint32_t ESP_getChipId(void) { #if defined(ESP8266) return ESP.getChipId(); #else uint32_t id = 0; for (int i = 0; i < 17; i = i + 8) { id |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i; } return id; #endif } IPAddress getOurIP(void) { IPAddress ipa; WiFiMode_t wm = WiFi.getMode(); switch (wm) { case WIFI_STA: ipa = WiFi.localIP(); break; case WIFI_AP: ipa = WiFi.softAPIP(); break; default: ipa = IPAddress(0, 0, 0, 0); // nelze urcit ip adresu (bud je AP + STA aktivni, nebo je vypnute WiFi) break; } return ipa; } uint8_t * getOurMAC(uint8_t *mac) { if (WIFIMODE_STA == svGetV(F("mode"), nullptr, F(WIFICFG_FILE))) return WiFi.macAddress(mac); else return WiFi.softAPmacAddress(mac); } WiFiConfigUsrParameter::WiFiConfigUsrParameter(const char *id, const char *label, const char *defaultValue, unsigned int length, storeparam_cb cb) { _next = NULL; _cb = cb; _id = id; _label = label; _length = length; _value = new char[length + 1]; for (unsigned int i = 0; i < length; i++) { _value[i] = 0; } if (defaultValue != NULL) { strncpy(_value, defaultValue, length); } } const char* WiFiConfigUsrParameter::getValue() { return _value; } const char* WiFiConfigUsrParameter::getID() { return _id; } const char* WiFiConfigUsrParameter::getLabel() { return _label; } int WiFiConfigUsrParameter::getValueLength() { return _length; } void WiFiConfigUsrParameter::setNext(WiFiConfigUsrParameter *n) { _next = n; } WiFiConfigUsrParameter *WiFiConfigUsrParameter::getNext() { return _next; } void WiFiConfigUsrParameter::setNewValue(const char *newval) { if (0 != strcmp(_value, newval)) _cb(newval); } WiFiConfigUsrParameter *WiFiConfig::_searchUsrParameter(const char *name) { WiFiConfigUsrParameter *ptr = _params; while (NULL != ptr) { if (0 == strcmp(name, ptr->getID())) break; ptr = ptr->getNext(); } return ptr; } void WiFiConfig::addParameter(WiFiConfigUsrParameter *p) { p->setNext(_params); _params = p; } String WiFiConfig::infoProcessor(const String & var) { if (var == F("SDK")) { #if defined(ESP8266) return ESP.getFullVersion(); #else // TODO return ESP.getSdkVersion(); #endif } else if (var == F("FS")) { #if defined(ESP8266) return String(ESP.getFlashChipRealSize() / 1024); #else // TODO return String(ESP.getFlashChipSize()); #endif } else if (var == F("SS")) { return String(ESP.getSketchSize() / 1024); } else if (var == F("FSS")) { return String(ESP.getFreeSketchSpace() / 1024); } else if (var == F("STAMAC")) { uint8_t mac[6]; uint8_t* macread = WiFi.macAddress(mac); char macaddress[20]; sprintf_P(macaddress, PSTR("%02x:%02x:%02x:%02x:%02x:%02x"), macread[0], macread[1], macread[2], macread[3], macread[4], macread[5]); return String(macaddress); } else if (var == F("APMAC")) { uint8_t mac[6]; char macaddress[20]; uint8_t *macread = WiFi.softAPmacAddress(mac); sprintf_P(macaddress, PSTR("%02x:%02x:%02x:%02x:%02x:%02x"), macread[0], macread[1], macread[2], macread[3], macread[4], macread[5]); return String(macaddress); } else if (var == F("ESPID")) { char buff[8]; sprintf_P(buff, PSTR("%06X"), ESP_getChipId()); return String(buff); } else if (var == F("FID")){ #if defined(ESP8266) char buff[10]; sprintf_P(buff, PSTR("%08X"), ESP.getFlashChipId()); return String(buff); #endif } return String(F("???")); } String WiFiConfig::apProcessor(const String &var) { if (var == F("USER")) { String result; if (_params) { WiFiConfigUsrParameter *up = _params; char buff[128]; result.reserve(1024); result = FPSTR(PAGE_PARAM_HDR); while (NULL != up) { sprintf_P(buff, PAGE_PARAM, up->getLabel(), up->getID(), up->getValueLength(), up->getValue()); result.concat(buff); up = up->getNext(); } } return result; } else if (var == F("SSID")) { String result = svGetV(F("ssid"), nullptr, F(WIFICFG_FILE)); strDecode(result); return result; } else if (var == F("PASS")) { String result = svGetV(F("pass"), nullptr, F(WIFICFG_FILE)); strDecode(result); return result; } else if (var == F("APMODE")) { String result; if (svGetV(F("mode"), nullptr, F(WIFICFG_FILE)) == WIFIMODE_AP) result = FPSTR(CHECKED); return result; } else if (var == F("APCHAN")) { String result; uint8_t chan = svGetV(F("channel"), nullptr, F(WIFICFG_FILE)); if ((chan < 1) || (chan > 13)) chan = 1; // neplatne cislo kanalu nahradime nejnizsim result = String(chan); return result; } else if (var == F("STATIC")) { String result; if (svGetV(F("ipmode"), nullptr, F(WIFICFG_FILE)) == IPCONFIG_STATIC) result = FPSTR(CHECKED); return result; } else if (var == F("IP")) { String result; result = _getIP(F("ip")).toString(); return result; } else if (var == F("MASK")) { String result; result = _getIP(F("mask")).toString(); return result; } else if (var == F("GATE")) { String result; result = _getIP(F("gate")).toString(); return result; } else if(var == F("DNS")) { String result; result = _getIP(F("dns")).toString(); return result; } return String(); } String WiFiConfig::rootProcessor(const String &var) { String content; if (var == "STATUS") { switch (_status) { #if defined(ESP8266) case STATION_IDLE: content = F("Klid"); break; case STATION_CONNECTING: content = F("Připojování"); break; case STATION_WRONG_PASSWORD: content = F("Špatné heslo"); break; case STATION_NO_AP_FOUND: content = F("AP nenalezen"); break; case STATION_CONNECT_FAIL: content = F("Připojení selhalo"); break; case STATION_GOT_IP: content = F("Získaná ip"); break; case 0xfe: content = F("Špatná konfigurace"); break; case 0xff: content = F("Vynucená konfigurace"); break; default: content = F("Neznámý"); break; #else case WL_IDLE_STATUS: content = F("Klid"); break; case WL_NO_SSID_AVAIL: content = F("AP nenalezen"); break; case WL_CONNECT_FAILED: content = F("Připojení selhalo"); break; case 0xfe: content = F("Špatná konfigurace"); break; case 0xff: content = F("Vynucená konfigurace"); break; default: content = F("Neznámý"); break; #endif } } else if (var == F("RESTORE")) { if (USEDFS.exists(F(WIFICFG_OLD_FILE))) { content = FPSTR(PAGE_RESTORE); } } return content; } void WiFiConfig::_handleRestore(AsyncWebServerRequest *request) { USEDFS.remove(F(WIFICFG_FILE)); USEDFS.rename(F(WIFICFG_OLD_FILE), F(WIFICFG_FILE)); request->onDisconnect([]() { _doReconfig = true; // aktivujeme novou konfiguraci a restartujeme ESP }); request->send_P(200, TEXTHTML, PAGE_SAVED); } void WiFiConfig::_handleNotFound(AsyncWebServerRequest *request) { DEBUG_MSG("Requested URI: %s\r\n", request->url().c_str()); if (request->url().endsWith(String(F("favicon.ico")))) { request->send_P(404, TEXTPLAIN, PSTR("Err")); } else { String redirect; redirect.reserve(256); redirect = F("http://"); redirect.concat(WiFi.softAPIP().toString()); redirect.concat(F("/index.htm")); DEBUG_MSG("Redirection to: %s\r\n", redirect.c_str()); request->redirect(redirect); } } void WiFiConfig::_handleReset(AsyncWebServerRequest *request) { request->onDisconnect([]() { ESP.restart(); }); request->send_P(200, TEXTHTML, PAGE_RESTART); } void WiFiConfig::_handleScan(AsyncWebServerRequest *request) { String json; int n = WiFi.scanComplete(); json.reserve(1024); json = F("{\"status\":"); json.concat(String(n)); json.concat(F(",\"ssids\":[")); if (n == WIFI_SCAN_FAILED) { WiFi.scanNetworks(true); } else if (n) { for (int i = 0; i < n; ++i) { if (i) json.concat(F(",")); json.concat(("{\"rssi\":")); json.concat(String(WiFi.RSSI(i))); json.concat(F(",\"ssid\":\"")); json.concat(WiFi.SSID(i)); json.concat(F("\",\"channel\":")); json.concat(String(WiFi.channel(i))); json.concat(F(",\"secure\":")); json.concat(String(WiFi.encryptionType(i))); json.concat(F("}")); } WiFi.scanDelete(); if (WiFi.scanComplete() == WIFI_SCAN_FAILED) { WiFi.scanNetworks(true); } } json.concat(F("]}")); request->send(200, FPSTR(TEXTJSON), json); } void WiFiConfig::_handleInfo(AsyncWebServerRequest *request) { request->send_P(200, TEXTHTML, PAGE_INFO, std::bind(&WiFiConfig::infoProcessor, this, std::placeholders::_1)); } void WiFiConfig::_handleRoot(AsyncWebServerRequest *request) { request->send_P(200, TEXTHTML, PAGE_CAPTIVEPORTALCATCH, std::bind(&WiFiConfig::rootProcessor, this, std::placeholders::_1)); _time = millis() + (_timeout * 1000); // spocitame si novy cas, kdy budeme modul restartovat } IPAddress WiFiConfig::_getIP(const String &from) { uint32_t ipa; int result; ipa = svGetV(from, &result, F(WIFICFG_FILE)); if (SV_OK != result) ipa = 0; return IPAddress(ipa); } void WiFiConfig::_handleDisplayAP(AsyncWebServerRequest *request) { request->send_P(200, TEXTHTML, PAGE_INDEX1, std::bind(&WiFiConfig::apProcessor, this, std::placeholders::_1)); _time = millis() + (360 * 1000); // spocitame si novy cas, kdy budeme modul restartovat (6 minut) } void WiFiConfig::_handleSetAP(AsyncWebServerRequest *request) { String str; str.reserve(128); str = request->arg(F("_s")); if (str.length() > 0) { uint8_t mode; if (USEDFS.exists(F(WIFICFG_OLD_FILE))) { USEDFS.remove(F(WIFICFG_OLD_FILE)); } USEDFS.rename(F(WIFICFG_FILE), F(WIFICFG_OLD_FILE)); strEncode(str); svSetV(F("ssid"), str, F(WIFICFG_FILE)); str = request->arg(F("_p")); strEncode(str); svSetV(F("pass"), str, F(WIFICFG_FILE)); str = request->arg(F("_a")); if (str.length() > 0) { mode = WIFIMODE_AP; // rezim AP str = request->arg(F("_ch")); // kanal AP svSetV(F("channel"), str.toInt(), F(WIFICFG_FILE)); } else mode = WIFIMODE_STA; // rezim STA svSetV(F("mode"), mode, F(WIFICFG_FILE)); str = request->arg(F("_st")); if (0 == str.length()) svSetV(F("ipmode"), IPCONFIG_DHCP, F(WIFICFG_FILE)); // mame DHCP dynamickou konfiguraci else { // staticka ip konfigurace IPAddress ipa; svSetV(F("ipmode"), IPCONFIG_STATIC, F(WIFICFG_FILE)); // mame statickou konfiguraci str = request->arg(F("_i")); ipa.fromString(str); svSetV(F("ip"), (uint32_t)ipa, F(WIFICFG_FILE)); str = request->arg(F("_m")); ipa.fromString(str); svSetV(F("mask"), (uint32_t)ipa, F(WIFICFG_FILE)); str = request->arg(F("_g")); ipa.fromString(str); svSetV(F("gw"), (uint32_t)ipa, F(WIFICFG_FILE)); str = request->arg(F("_d")); ipa.fromString(str); svSetV(F("dns"), (uint32_t)ipa, F(WIFICFG_FILE)); } // Uzivatelske parametry for (unsigned i = 0; i < request->args(); i++) { if (!request->argName(i).startsWith(F("_"))) { // vnitrni parametry WiFiConfig modulu zacinaji _, takze ty muzeme ignorovat WiFiConfigUsrParameter *up = _searchUsrParameter(request->argName(i).c_str()); if (NULL != up) up->setNewValue(request->arg(i).c_str()); } } } request->onDisconnect([]() { _doReconfig = true; // aktivujeme novou konfiguraci a restartujeme ESP }); request->send_P(200, TEXTHTML, PAGE_SAVED); } // Start WiFi v rezimu AP pro nastaveni modulu wificonfigresult_t WiFiConfig::_setupAP(wificonfig_cb cb) { String ssid = SETUP_SSID; WiFi.persistent(false); // chranime flash pred zbytecnymi prepisy dnsServer.reset(new DNSServer()); server = new AsyncWebServer(80); server->reset(); /* Soft AP network parameters */ IPAddress apIP(172, 217, 28, 1); IPAddress netMsk(255, 255, 255, 0); WiFi.disconnect(); // pro jistotu se odpojime // WiFi.mode(WIFI_AP); #if defined(ARDUINO_ARCH_ESP8266) WiFi.softAPConfig(apIP, apIP, netMsk); if (ssid.endsWith(F("?"))) { char lmac[16]; sprintf_P(lmac, PSTR("%06X"), ESP_getChipId()); ssid.replace(F("?"), String(lmac)); } WiFi.softAP(ssid.c_str(), NULL, SETUP_CHANNEL); WiFi.mode(WIFI_AP); delay(500); // dulezite - jinak se nevraci spravna IP adresa !!! (udajne od verze 2.3.0 uz neni nutne) #else // osetreni padu ESP32 - https://github.com/espressif/arduino-esp32/issues/2025 if (ssid.endsWith(F("?"))) { char lmac[16]; sprintf_P(lmac, PSTR("%06X"), ESP_getChipId()); ssid.replace(F("?"), String(lmac)); } WiFi.softAP(ssid.c_str(), NULL, SETUP_CHANNEL); delay(100); // kvuli ESP32 - cekame na start AP WiFi.softAPConfig(apIP, apIP, netMsk); #endif dnsServer->setErrorReplyCode(DNSReplyCode::NoError); dnsServer->start(DNS_PORT, "*", WiFi.softAPIP()); // spustime tzv. Captive portal - vsechny DNS dotazy jsou smerovany na nasi ip adresu if (cb) cb(WCS_CONFIGSTART); // signalizujeme start konfiguracniho serveru // Nastavime handlery weboveho serveru pro konfiguraci server->onNotFound(std::bind(&WiFiConfig::_handleNotFound, this, std::placeholders::_1)); server->on(PSTR("/config"), std::bind(&WiFiConfig::_handleDisplayAP, this, std::placeholders::_1)); server->on(PSTR("/scan"), std::bind(&WiFiConfig::_handleScan, this, std::placeholders::_1)); server->on(PSTR("/s"), std::bind(&WiFiConfig::_handleSetAP, this, std::placeholders::_1)); server->on(PSTR("/r"), std::bind(&WiFiConfig::_handleReset, this, std::placeholders::_1)); server->on(PSTR("/i"), std::bind(&WiFiConfig::_handleInfo, this, std::placeholders::_1)); server->on(PSTR("/o"), std::bind(&WiFiConfig::_handleRestore, this, std::placeholders::_1)); server->on(PSTR("/index.htm"), std::bind(&WiFiConfig::_handleRoot, this, std::placeholders::_1)); #ifdef USE_WIFICONFIG_OTAUPDATE server->on(PSTR("/u"), []() { server->send_P(200, TEXTHTML, PAGE_UPDATE); }); server->on(PSTR("/update"), HTTP_POST, []() { server->sendHeader(F("Connection"), F("close")); server->send(200, FPSTR(TEXTPLAIN), (Update.hasError()) ? F("FAIL") : F("OK")); ESP.restart(); }, []() { HTTPUpload& upload = server->upload(); if (upload.status == UPLOAD_FILE_START) { WiFiUDP::stopAll(); uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000; if (!Update.begin(maxSketchSpace)) { //start with max available size //Update.printError(Serial); } } else if (upload.status == UPLOAD_FILE_WRITE) { if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) { //Update.printError(Serial); } } else if (upload.status == UPLOAD_FILE_END) { if (Update.end(true)) { //true to set the size to the current progress //Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize); } else { //Update.printError(Serial); } } yield(); }); #endif #ifdef USE_WIFICONFIG_FSEDITOR #if 0 #if defined(ESP8266) server->addHandler(new SPIFFSEditor("admin", "nimda", USEDFS)); #else server->addHandler(new SPIFFSEditor(USEDFS, "admin", "nimda")); #endif #else #if defined(ESP8266) server->addHandler(new FSWebEditor("admin", "nimda")); #else server->addHandler(new FSWebEditor(USEDFS, "admin", "nimda")); #endif #endif #endif server->begin(); // startujeme webovy server // Asynchronne ziskame seznam okolnich AP prakticky okamzite po startu konfiguracniho AP int n = WiFi.scanComplete(); if (n == WIFI_SCAN_FAILED) { WiFi.scanNetworks(true); } while (1) { if (_doReconfig) { // mame aktivovat novou konfiguraci _prepareWifi(); ESP.restart(); } if (cb) cb(WCS_CONFIGWAIT); // volame uzivatelsky callback (napr. signalizace) dnsServer->processNextRequest(); yield(); // procesy uvnitr systemu ESP potrebuji take svuj cas if (_timeout) { if (millis() > _time) { DEBUG_MSG("AP timeout\r\n"); if (cb) cb(WCS_CONFIGTIMEOUT); // signalizujeme timeout break; // ukoncime cekani a vracime se } } } // tady by asi melo byt zastaveni weboveho a dns serveru... dnsServer->stop(); server->end(); return WCR_TIMEOUT; // nepripojeno, vyprsel timeout konfiguracniho AP } // Testovani, zda se modul pripojil k AP bool WiFiConfig::_testWifi(wificonfig_cb cb) { uint32_t startt = millis(); #if !defined(ESP8266) _prepareWifi(); // nakonfigurujeme ESP32 dle nastavenych parametru #endif DEBUG_MSG("Trying to connect.\r\n"); while ((millis() - startt) < WIFI_STA_CONNECT_TIMEOUT) { if (WL_CONNECTED == WiFi.status()) { DEBUG_MSG("Connected...\r\n"); if (cb) cb(WCS_CONNECTED); return true; // jsme pripojeni } yield(); if (cb) cb(WCS_CONNECTING); // signalizujeme pokracujici pokus o spojeni } DEBUG_MSG("Not connected!\r\n"); #if defined(ESP8266) _status = wifi_station_get_connect_status(); #else _status = WiFi.status(); #endif return false; // pripojeni se nezdarilo } wificonfigresult_t WiFiConfig::begin(int forceConfigure, wificonfig_cb cb) { wificonfigresult_t result = WCR_OK; // predpokladame, ze se pripojeni podari DEBUG_MSG("\r\n\r\n"); // oddeleni vypisu if (0 == forceConfigure) { DEBUG_MSG("Force config.\r\n"); _status = 0xff; result = _setupAP(cb); } else { #if defined(ESP8266) if (svGetV(F("mode"), nullptr, F(WIFICFG_FILE)) != WiFi.getMode()) { // neshoduje se rezim - musime spustit konfiguracni AP (poskozena konfigurace) DEBUG_MSG("Wrong config (%d, %d)\r\n", svGetV(F("mode"), nullptr, F(WIFICFG_FILE)), WiFi.getMode()); _status = 0xfe; result = _setupAP(cb); } else #endif { switch (svGetV(F("mode"), nullptr, F(WIFICFG_FILE))) { case WIFIMODE_STA: { DEBUG_MSG("STA mode.\r\n"); SETHOSTNAME(WiFiDeviceName); // nastavime jmeno zarizeni if (IPCONFIG_STATIC == svGetV(F("ipmode"), nullptr, F(WIFICFG_FILE))) { DEBUG_MSG("Static configuration SET.\r\n"); WiFi.config(IPAddress(svGetV(F("ip"), nullptr, F(WIFICFG_FILE))), IPAddress(svGetV(F("gw"), nullptr, F(WIFICFG_FILE))), IPAddress(svGetV(F("mask"), nullptr, F(WIFICFG_FILE))), IPAddress(svGetV(F("dns"), nullptr, F(WIFICFG_FILE)))); delay(100); } if (WC_DONT_RUN_CONFIGAP == _timeout) result = WCR_CONFIGAP_NOT_STARTED; // nemame spoustet konfiguracni AP - vracime se hned else { if (cb) cb(WCS_CONNECTSTART); // signalizujeme zacatek pokusu o pripojeni if (!_testWifi(cb)) { result = _setupAP(cb); // modul se nepripojil - startujeme AP rezim } } } break; case WIFIMODE_AP: DEBUG_MSG("AP mode.\r\n"); if (IPCONFIG_STATIC == svGetV(F("ipmode"), nullptr, F(WIFICFG_FILE))) { WiFi.softAPConfig(IPAddress(svGetV(F("ip"), nullptr, F(WIFICFG_FILE))), IPAddress(svGetV(F("gw"), nullptr, F(WIFICFG_FILE))), IPAddress(svGetV(F("mask"), nullptr, F(WIFICFG_FILE)))); } if (cb) cb(WCS_CONNECTED); // signalizujeme pripojeni (zde se nic jineho stejne nestane...) break; #if !defined(ESP8266) default: DEBUG_MSG("Wrong config (%d)\r\n", svGetV(F("mode"), nullptr, F(WIFICFG_FILE))); _status = 0xfe; result = _setupAP(cb); break; #endif } } } return result; // mame vyreseno } wificonfigresult_t WiFiConfig::begin(int forceConfigure, int timeout, wificonfig_cb cb = NULL) { if ((timeout > 0) && (40 > timeout)) timeout = 40; // timeout musi byt minimalne 40 sekund if ((0 == forceConfigure) && (WC_DONT_RUN_CONFIGAP == timeout)) timeout = 40; _timeout = timeout; if (_timeout > 0) _time = millis() + (_timeout * 1000); // spocitame si novy cas, kdy budeme modul restartovat return begin(forceConfigure, cb); // spustime WiFi } #if defined(ESP32) static const char INITTXT[] = "{}"; #endif void WiFiConfig::initConfig(const String &ssid, const String &pass, const int mode, const int ipcfg, const IPAddress &ip, const IPAddress &mask, const IPAddress &gw, const IPAddress &dns) { String es; DEBUG_MSG("initConfig %d\r\n", mode); if (!USEDFS.exists(F(WIFICFG_FILE))) { DEBUG_MSG("Create file...\r\n"); File f; f = USEDFS.open(F(WIFICFG_FILE), "w"); #if defined(ESP8266) f.write("{}"); #else f.write((const uint8_t *)INITTXT, strlen(INITTXT)); #endif f.close(); } es = ssid; strEncode(es); svSetV(F("ssid"), es, F(WIFICFG_FILE)); es = pass; strEncode(es); svSetV(F("pass"), es, F(WIFICFG_FILE)); svSetV(F("mode"), mode, F(WIFICFG_FILE)); svSetV(F("ipmode"), ipcfg, F(WIFICFG_FILE)); svSetV(F("channel"), 3, F(WIFICFG_FILE)); svSetV(F("ip"), (uint32_t)ip, F(WIFICFG_FILE)); svSetV(F("mask"), (uint32_t)mask, F(WIFICFG_FILE)); svSetV(F("gw"), (uint32_t)gw, F(WIFICFG_FILE)); svSetV(F("dns"), (uint32_t)dns, F(WIFICFG_FILE)); _prepareWifi(); // nastavime novou WiFi konfiguraci } void WiFiConfig::_prepareWifi(void) { DEBUG_MSG("Prepare wifi...\r\n"); WiFi.persistent(true); // chceme, aby si modul zapamatoval konfiguraci WiFi.disconnect(); // vsechno odpojime delay(100); String s = svGetV(F("ssid"), nullptr, F(WIFICFG_FILE)); strDecode(s); String pass = svGetV(F("pass"), nullptr, F(WIFICFG_FILE)); strDecode(pass); int mode = svGetV(F("mode"), nullptr, F(WIFICFG_FILE)); DEBUG_MSG("SSID %s, Pass %s, Mode %d\r\n", s.c_str(), pass.c_str(), mode); switch (mode) { case WIFIMODE_STA: { DEBUG_MSG("STA mode.\r\n"); #if defined(ESP8266) if (strlen(WiFiDeviceName)) { SETHOSTNAME(WiFiDeviceName); // nastavime jmeno zarizeni } #endif if (IPCONFIG_STATIC == svGetV(F("ipmode"), nullptr, F(WIFICFG_FILE))) { DEBUG_MSG("Static configuration.\r\n"); WiFi.config(IPAddress(svGetV(F("ip"), nullptr, F(WIFICFG_FILE))), IPAddress(svGetV(F("gw"), nullptr, F(WIFICFG_FILE))), IPAddress(svGetV(F("mask"), nullptr, F(WIFICFG_FILE))), IPAddress(svGetV(F("dns"), nullptr, F(WIFICFG_FILE)))); delay(100); } WiFi.mode(WIFI_STA); // startujeme WiFi v rezimu klienta WiFi.begin(s.c_str(), pass.c_str()); DEBUG_MSG("STA params: %s, %s\r\n", s.c_str(), pass.c_str()); #if !defined(ESP8266) if (strlen(WiFiDeviceName)) { SETHOSTNAME(WiFiDeviceName); // nastavime jmeno zarizeni } #endif #if defined(ESP8266) WiFi.setAutoConnect(true); WiFi.setAutoReconnect(true); // wifi_station_set_auto_connect(true); #else //esp_wifi_set_auto_connect(true); #endif delay(1000); } break; case WIFIMODE_AP:{ DEBUG_MSG("AP mode.\r\n"); if (s.endsWith(F("?"))) { char lmac[16]; sprintf_P(lmac, PSTR("%06X"), ESP_getChipId()); s.replace(F("?"), String(lmac)); } WiFi.mode(WIFI_AP); // startujeme AP int chan = svGetV(F("channel"), nullptr, F(WIFICFG_FILE)); if (pass.length()) { // je zadane heslo do AP WiFi.softAP(s.c_str(), pass.c_str(), chan); } else { // otevreny AP WiFi.softAP(s.c_str(), NULL, chan); } if (IPCONFIG_STATIC == svGetV(F("ipmode"), nullptr, F(WIFICFG_FILE))) { delay(100); // kvuli ESP32 - cekame na start AP WiFi.softAPConfig(IPAddress(svGetV(F("ip"), nullptr, F(WIFICFG_FILE))), IPAddress(svGetV(F("gw"), nullptr, F(WIFICFG_FILE))), IPAddress(svGetV(F("mask"), nullptr, F(WIFICFG_FILE)))); } break; } default: // jakykoliv neznamy rezim (mozna zavada na EEPROM???) DEBUG_MSG("Mode Error (%d)!!\r\n", (int)mode); break; } delay(1000); // cekame XX sekund na ulozeni atd... } // EOF