Prechádzať zdrojové kódy

Version 6.2.3; Another version of wifimanager

platenspeler 5 rokov pred
rodič
commit
ca1e745edc
91 zmenil súbory, kde vykonal 6997 pridanie a 7682 odobranie
  1. 1 1
      .pio/build/project.checksum
  2. 103 191
      .vscode/c_cpp_properties.json
  3. 6 6
      .vscode/extensions.json
  4. 4 4
      .vscode/launch.json
  5. 10 2
      CHANGELOG.md
  6. 4 3
      TODO.md
  7. 0 6
      lib/ESP32WebServer/README.md
  8. 0 72
      lib/ESP32WebServer/examples/esp32webserver1/esp32webserver1.ino
  9. 0 145
      lib/ESP32WebServer/examples/esp32webserver2/esp32webserver2.ino
  10. 0 36
      lib/ESP32WebServer/keywords.txt
  11. 0 9
      lib/ESP32WebServer/library.properties
  12. 0 537
      lib/ESP32WebServer/src/ESP32WebServer.cpp
  13. 0 192
      lib/ESP32WebServer/src/ESP32WebServer.h
  14. 0 607
      lib/ESP32WebServer/src/Parsing.cpp
  15. 0 19
      lib/ESP32WebServer/src/detail/RequestHandler.h
  16. 0 153
      lib/ESP32WebServer/src/detail/RequestHandlersImpl.h
  17. 0 70
      lib/WiFiEsp/CHANGES.txt
  18. 0 675
      lib/WiFiEsp/LICENSE
  19. 0 102
      lib/WiFiEsp/README.md
  20. 0 94
      lib/WiFiEsp/examples/ConnectWPA/ConnectWPA.ino
  21. 0 109
      lib/WiFiEsp/examples/ScanNetworks/ScanNetworks.ino
  22. 0 154
      lib/WiFiEsp/examples/UdpNTPClient/UdpNTPClient.ino
  23. 0 109
      lib/WiFiEsp/examples/UdpSendReceive/UdpSendReceive.ino
  24. 0 106
      lib/WiFiEsp/examples/WebClient/WebClient.ino
  25. 0 121
      lib/WiFiEsp/examples/WebClientRepeating/WebClientRepeating.ino
  26. 0 106
      lib/WiFiEsp/examples/WebClientSSL/WebClientSSL.ino
  27. 0 136
      lib/WiFiEsp/examples/WebServer/WebServer.ino
  28. 0 128
      lib/WiFiEsp/examples/WebServerAP/WebServerAP.ino
  29. 0 142
      lib/WiFiEsp/examples/WebServerLed/WebServerLed.ino
  30. 0 59
      lib/WiFiEsp/keywords.txt
  31. 0 9
      lib/WiFiEsp/library.properties
  32. 0 233
      lib/WiFiEsp/src/WiFiEsp.cpp
  33. 0 274
      lib/WiFiEsp/src/WiFiEsp.h
  34. 0 290
      lib/WiFiEsp/src/WiFiEspClient.cpp
  35. 0 144
      lib/WiFiEsp/src/WiFiEspClient.h
  36. 0 99
      lib/WiFiEsp/src/WiFiEspServer.cpp
  37. 0 63
      lib/WiFiEsp/src/WiFiEspServer.h
  38. 0 193
      lib/WiFiEsp/src/WiFiEspUdp.cpp
  39. 0 97
      lib/WiFiEsp/src/WiFiEspUdp.h
  40. 0 1127
      lib/WiFiEsp/src/utility/EspDrv.cpp
  41. 0 340
      lib/WiFiEsp/src/utility/EspDrv.h
  42. 0 105
      lib/WiFiEsp/src/utility/RingBuffer.cpp
  43. 0 47
      lib/WiFiEsp/src/utility/RingBuffer.h
  44. 0 49
      lib/WiFiEsp/src/utility/debug.h
  45. 0 142
      lib/WiFiEsp/test/BasicTest/BasicTest.ino
  46. 0 184
      lib/WiFiEsp/test/ClientTest/ClientTest.ino
  47. 0 48
      lib/WiFiEsp/test/EspDebug/EspDebug.ino
  48. 0 58
      lib/WiFiEsp/test/RingBufferTest/RingBufferTest.ino
  49. 12 0
      lib/WiFiManager-development/.github/CONTRIBUTING.md
  50. 56 0
      lib/WiFiManager-development/.github/ISSUE_TEMPLATE.md
  51. 1 0
      lib/WiFiManager-development/.gitignore
  52. 53 0
      lib/WiFiManager-development/.travis.yml
  53. 3 2
      lib/WiFiManager-development/LICENSE
  54. 552 0
      lib/WiFiManager-development/README.md
  55. 2906 0
      lib/WiFiManager-development/WiFiManager.cpp
  56. 549 0
      lib/WiFiManager-development/WiFiManager.h
  57. 134 0
      lib/WiFiManager-development/examples/Advanced/Advanced.ino
  58. 175 0
      lib/WiFiManager-development/examples/AutoConnect/AutoConnectWithFSParameters/AutoConnectWithFSParameters.ino
  59. 172 0
      lib/WiFiManager-development/examples/AutoConnect/AutoConnectWithFSParametersAndCustomIP/AutoConnectWithFSParametersAndCustomIP.ino
  60. 71 0
      lib/WiFiManager-development/examples/AutoConnect/AutoConnectWithFeedbackLED/AutoConnectWithFeedbackLED.ino
  61. 41 0
      lib/WiFiManager-development/examples/Basic/Basic.ino
  62. 328 0
      lib/WiFiManager-development/examples/DEV/OnDemandConfigPortal/OnDemandConfigPortal.ino
  63. 27 0
      lib/WiFiManager-development/examples/NonBlocking/AutoConnectNonBlocking/AutoConnectNonBlocking.ino
  64. 36 0
      lib/WiFiManager-development/examples/NonBlocking/AutoConnectNonBlockingwParams/AutoConnectNonBlockingwParams.ino
  65. 64 0
      lib/WiFiManager-development/examples/NonBlocking/OnDemandNonBlocking/onDemandNonBlocking.ino
  66. 42 0
      lib/WiFiManager-development/examples/Old_examples/AutoConnectWithFeedback/AutoConnectWithFeedback.ino
  67. 43 0
      lib/WiFiManager-development/examples/Old_examples/AutoConnectWithReset/AutoConnectWithReset.ino
  68. 71 0
      lib/WiFiManager-development/examples/Old_examples/AutoConnectWithStaticIP/AutoConnectWithStaticIP.ino
  69. 38 0
      lib/WiFiManager-development/examples/Old_examples/AutoConnectWithTimeout/AutoConnectWithTimeout.ino
  70. 47 0
      lib/WiFiManager-development/examples/OnDemand/OnDemandConfigPortal/OnDemandConfigPortal.ino
  71. 51 0
      lib/WiFiManager-development/examples/OnDemand/OnDemandWebPortal/onDemandWebPortal.ino
  72. 141 0
      lib/WiFiManager-development/examples/ParamsChildClass/ParamsChildClass.ino
  73. 320 0
      lib/WiFiManager-development/extras/WiFiManager.template.html
  74. 60 0
      lib/WiFiManager-development/extras/parse.js
  75. BIN
      lib/WiFiManager-development/extras/png_signal_strength_master.png
  76. 12 0
      lib/WiFiManager-development/extras/template.h
  77. 182 0
      lib/WiFiManager-development/extras/test.html
  78. 39 0
      lib/WiFiManager-development/keywords.txt
  79. 29 0
      lib/WiFiManager-development/library.json
  80. 9 0
      lib/WiFiManager-development/library.properties
  81. 362 0
      lib/WiFiManager-development/strings_en.h
  82. 60 0
      lib/WiFiManager-development/travis/common.sh
  83. 45 2
      platformio.ini
  84. 22 12
      src/ESP-sc-gway.ino
  85. 37 11
      src/_WiFi.ino
  86. 3 3
      src/_loraFiles.ino
  87. 15 11
      src/_oLED.ino
  88. 1 0
      src/_txRx.ino
  89. 14 21
      src/_udpSemtech.ino
  90. 16 8
      src/_wwwServer.ino
  91. 30 16
      src/configGway.h

+ 1 - 1
.pio/build/project.checksum

@@ -1 +1 @@
-3616b51affcfbc45b70bb13d7dea0c39ee351582
+dd850d5f37b6c882dbfe1ea13bf194912e0a824a

+ 103 - 191
.vscode/c_cpp_properties.json

@@ -8,102 +8,52 @@
             "includePath": [
                 "d:/sourceTree/ESP-1ch-Gateway/include",
                 "d:/sourceTree/ESP-1ch-Gateway/src",
-                "d:/sourceTree/ESP-1ch-Gateway/lib/Time",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/DNSServer/src",
-                "d:/sourceTree/ESP-1ch-Gateway/lib/esp32-http-update/src",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/HTTPClient/src",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/WiFiClientSecure/src",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/SPIFFS/src",
-                "d:/sourceTree/ESP-1ch-Gateway/lib/ESP8266_Oled_Driver_for_SSD1306_display",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/Wire/src",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/SPI/src",
-                "d:/sourceTree/ESP-1ch-Gateway/lib/ArduinoJson/src",
-                "d:/sourceTree/ESP-1ch-Gateway/lib/aes",
                 "d:/sourceTree/ESP-1ch-Gateway/lib/LoRaCode",
                 "d:/sourceTree/ESP-1ch-Gateway/lib/gBase64",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/ArduinoOTA/src",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/Update/src",
-                "d:/sourceTree/ESP-1ch-Gateway/lib/Streaming/src",
+                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WebServer/src",
                 "d:/sourceTree/ESP-1ch-Gateway/lib/TinyGPSPlus-1.0.2b/src",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/ESPmDNS/src",
+                "d:/sourceTree/ESP-1ch-Gateway/lib/ArduinoJson/src",
+                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266httpUpdate/src",
+                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266HTTPClient/src",
+                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/DNSServer/src",
+                "d:/sourceTree/ESP-1ch-Gateway/lib/ESP8266_Oled_Driver_for_SSD1306_display",
+                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/SPI",
+                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/Wire",
+                "d:/sourceTree/ESP-1ch-Gateway/lib/esp32-http-update/src",
+                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/ArduinoOTA",
+                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266mDNS/src",
+                "d:/sourceTree/ESP-1ch-Gateway/lib/Streaming/src",
+                "d:/sourceTree/ESP-1ch-Gateway/lib/Time",
+                "d:/sourceTree/ESP-1ch-Gateway/lib/aes",
                 "d:/sourceTree/ESP-1ch-Gateway/lib/ESP32WebServer/src",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/WiFi/src",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/FS/src",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/config",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/app_trace",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/app_update",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/asio",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/bootloader_support",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/bt",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/coap",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/console",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/driver",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp-tls",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp32",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp_adc_cal",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp_event",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp_http_client",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp_http_server",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp_https_ota",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp_ringbuf",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/ethernet",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/expat",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/fatfs",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/freemodbus",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/freertos",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/heap",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/idf_test",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/jsmn",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/json",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/libsodium",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/log",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/lwip",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/mbedtls",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/mdns",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/micro-ecc",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/mqtt",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/newlib",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/nghttp",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/nvs_flash",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/openssl",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/protobuf-c",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/protocomm",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/pthread",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/sdmmc",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/smartconfig_ack",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/soc",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/spi_flash",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/spiffs",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/tcp_transport",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/tcpip_adapter",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/ulp",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/vfs",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/wear_levelling",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/wifi_provisioning",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/wpa_supplicant",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/xtensa-debug-module",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp-face",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp32-camera",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/fb_gfx",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/cores/esp32",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/variants/heltec_wifi_lora_32",
+                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WiFi/src",
+                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/tools/sdk/include",
+                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/tools/sdk/libc/xtensa-lx106-elf/include",
+                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/cores/esp8266",
+                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/tools/sdk/lwip2/include",
+                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/variants/d1_mini",
                 "d:/sourceTree/ESP-1ch-Gateway/lib/ESP8266_and_ESP32_Oled_Driver_for_SSD1306_display/src",
                 "d:/sourceTree/ESP-1ch-Gateway/lib/WiFiEsp/src",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/AsyncUDP/src",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/AzureIoT/src",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/BLE/src",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/BluetoothSerial/src",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/EEPROM/src",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/ESP32/src",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/FFat/src",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/HTTPUpdate/src",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/NetBIOS/src",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/Preferences/src",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/SD/src",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/SD_MMC/src",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/SimpleBLE/src",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/Ticker/src",
-                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/WebServer/src",
+                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/EEPROM",
+                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266AVRISP/src",
+                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266HTTPUpdateServer/src",
+                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266LLMNR",
+                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266NetBIOS",
+                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266SSDP",
+                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266SdFat/src",
+                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WiFiMesh/src",
+                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/Ethernet/src",
+                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/GDBStub/src",
+                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/Hash/src",
+                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/LittleFS/src",
+                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/SD/src",
+                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/SDFS/src",
+                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/SPISlave/src",
+                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/Servo/src",
+                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/SoftwareSerial/src",
+                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/TFT_Touch_Shield_V2",
+                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/Ticker/src",
+                "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/esp8266/src",
                 "C:/Users/maarten/.platformio/packages/tool-unity",
                 ""
             ],
@@ -112,124 +62,86 @@
                 "path": [
                     "d:/sourceTree/ESP-1ch-Gateway/include",
                     "d:/sourceTree/ESP-1ch-Gateway/src",
-                    "d:/sourceTree/ESP-1ch-Gateway/lib/Time",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/DNSServer/src",
-                    "d:/sourceTree/ESP-1ch-Gateway/lib/esp32-http-update/src",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/HTTPClient/src",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/WiFiClientSecure/src",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/SPIFFS/src",
-                    "d:/sourceTree/ESP-1ch-Gateway/lib/ESP8266_Oled_Driver_for_SSD1306_display",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/Wire/src",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/SPI/src",
-                    "d:/sourceTree/ESP-1ch-Gateway/lib/ArduinoJson/src",
-                    "d:/sourceTree/ESP-1ch-Gateway/lib/aes",
                     "d:/sourceTree/ESP-1ch-Gateway/lib/LoRaCode",
                     "d:/sourceTree/ESP-1ch-Gateway/lib/gBase64",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/ArduinoOTA/src",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/Update/src",
-                    "d:/sourceTree/ESP-1ch-Gateway/lib/Streaming/src",
+                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WebServer/src",
                     "d:/sourceTree/ESP-1ch-Gateway/lib/TinyGPSPlus-1.0.2b/src",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/ESPmDNS/src",
+                    "d:/sourceTree/ESP-1ch-Gateway/lib/ArduinoJson/src",
+                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266httpUpdate/src",
+                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266HTTPClient/src",
+                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/DNSServer/src",
+                    "d:/sourceTree/ESP-1ch-Gateway/lib/ESP8266_Oled_Driver_for_SSD1306_display",
+                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/SPI",
+                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/Wire",
+                    "d:/sourceTree/ESP-1ch-Gateway/lib/esp32-http-update/src",
+                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/ArduinoOTA",
+                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266mDNS/src",
+                    "d:/sourceTree/ESP-1ch-Gateway/lib/Streaming/src",
+                    "d:/sourceTree/ESP-1ch-Gateway/lib/Time",
+                    "d:/sourceTree/ESP-1ch-Gateway/lib/aes",
                     "d:/sourceTree/ESP-1ch-Gateway/lib/ESP32WebServer/src",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/WiFi/src",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/FS/src",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/config",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/app_trace",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/app_update",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/asio",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/bootloader_support",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/bt",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/coap",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/console",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/driver",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp-tls",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp32",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp_adc_cal",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp_event",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp_http_client",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp_http_server",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp_https_ota",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp_ringbuf",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/ethernet",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/expat",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/fatfs",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/freemodbus",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/freertos",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/heap",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/idf_test",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/jsmn",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/json",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/libsodium",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/log",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/lwip",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/mbedtls",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/mdns",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/micro-ecc",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/mqtt",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/newlib",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/nghttp",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/nvs_flash",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/openssl",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/protobuf-c",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/protocomm",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/pthread",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/sdmmc",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/smartconfig_ack",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/soc",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/spi_flash",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/spiffs",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/tcp_transport",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/tcpip_adapter",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/ulp",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/vfs",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/wear_levelling",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/wifi_provisioning",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/wpa_supplicant",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/xtensa-debug-module",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp-face",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp32-camera",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/fb_gfx",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/cores/esp32",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/variants/heltec_wifi_lora_32",
+                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WiFi/src",
+                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/tools/sdk/include",
+                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/tools/sdk/libc/xtensa-lx106-elf/include",
+                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/cores/esp8266",
+                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/tools/sdk/lwip2/include",
+                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/variants/d1_mini",
                     "d:/sourceTree/ESP-1ch-Gateway/lib/ESP8266_and_ESP32_Oled_Driver_for_SSD1306_display/src",
                     "d:/sourceTree/ESP-1ch-Gateway/lib/WiFiEsp/src",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/AsyncUDP/src",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/AzureIoT/src",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/BLE/src",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/BluetoothSerial/src",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/EEPROM/src",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/ESP32/src",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/FFat/src",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/HTTPUpdate/src",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/NetBIOS/src",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/Preferences/src",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/SD/src",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/SD_MMC/src",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/SimpleBLE/src",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/Ticker/src",
-                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif32/libraries/WebServer/src",
+                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/EEPROM",
+                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266AVRISP/src",
+                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266HTTPUpdateServer/src",
+                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266LLMNR",
+                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266NetBIOS",
+                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266SSDP",
+                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266SdFat/src",
+                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/ESP8266WiFiMesh/src",
+                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/Ethernet/src",
+                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/GDBStub/src",
+                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/Hash/src",
+                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/LittleFS/src",
+                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/SD/src",
+                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/SDFS/src",
+                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/SPISlave/src",
+                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/Servo/src",
+                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/SoftwareSerial/src",
+                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/TFT_Touch_Shield_V2",
+                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/Ticker/src",
+                    "C:/Users/maarten/.platformio/packages/framework-arduinoespressif8266/libraries/esp8266/src",
                     "C:/Users/maarten/.platformio/packages/tool-unity",
                     ""
                 ]
             },
             "defines": [
-                "PLATFORMIO=40101",
-                "ARDUINO_HELTEC_WIFI_LORA_32",
-                "ESP32",
-                "ESP_PLATFORM",
-                "F_CPU=240000000L",
-                "HAVE_CONFIG_H",
-                "MBEDTLS_CONFIG_FILE=\"mbedtls/esp_config.h\"",
+                "PLATFORMIO=40202",
+                "ESP8266",
+                "ARDUINO_ARCH_ESP8266",
+                "ARDUINO_ESP8266_WEMOS_D1MINI",
+                "_WIFIMANAGER=1",
+                "OLED=0",
+                "F_CPU=80000000L",
+                "__ets__",
+                "ICACHE_FLASH",
                 "ARDUINO=10805",
-                "ARDUINO_ARCH_ESP32",
-                "ARDUINO_VARIANT=\"heltec_wifi_lora_32\"",
-                "ARDUINO_BOARD=\"Heltec WiFi LoRa 32\"",
+                "ARDUINO_BOARD=\"PLATFORMIO_D1_MINI\"",
+                "FLASHMODE_QIO",
+                "LWIP_OPEN_SRC",
+                "NONOSDK22x_190703=1",
+                "TCP_MSS=536",
+                "LWIP_FEATURES=1",
+                "LWIP_IPV6=0",
+                "VTABLES_IN_FLASH",
                 ""
             ],
             "intelliSenseMode": "clang-x64",
             "cStandard": "c99",
             "cppStandard": "c++11",
-            "compilerPath": "\"C:/Users/maarten/.platformio/packages/toolchain-xtensa32/bin/xtensa-esp32-elf-gcc.exe\" -mlongcalls"
+            "compilerPath": "C:/Users/maarten/.platformio/packages/toolchain-xtensa/bin/xtensa-lx106-elf-gcc.exe",
+            "compilerArgs": [
+                "-mlongcalls",
+                "-mtext-section-literals",
+                ""
+            ]
         }
     ],
     "version": 4

+ 6 - 6
.vscode/extensions.json

@@ -1,7 +1,7 @@
 {
-	// See http://go.microsoft.com/fwlink/?LinkId=827846
-	// for the documentation about the extensions.json format
-	"recommendations": [
-		"platformio.platformio-ide"
-	]
-}
+    // See http://go.microsoft.com/fwlink/?LinkId=827846
+    // for the documentation about the extensions.json format
+    "recommendations": [
+        "platformio.platformio-ide"
+    ]
+}

+ 4 - 4
.vscode/launch.json

@@ -12,8 +12,8 @@
             "type": "platformio-debug",
             "request": "launch",
             "name": "PIO Debug",
-            "executable": "d:/sourceTree/ESP-1ch-Gateway/.pio/build/Gateway_59/firmware.elf",
-            "toolchainBinDir": "C:/Users/maarten/.platformio/packages/toolchain-xtensa32/bin",
+            "executable": "d:/sourceTree/ESP-1ch-Gateway/.pio/build/Gateway_21/firmware.elf",
+            "toolchainBinDir": "C:/Users/maarten/.platformio/packages/toolchain-xtensa/bin",
             "preLaunchTask": {
                 "type": "PlatformIO",
                 "task": "Pre-Debug"
@@ -24,8 +24,8 @@
             "type": "platformio-debug",
             "request": "launch",
             "name": "PIO Debug (skip Pre-Debug)",
-            "executable": "d:/sourceTree/ESP-1ch-Gateway/.pio/build/Gateway_59/firmware.elf",
-            "toolchainBinDir": "C:/Users/maarten/.platformio/packages/toolchain-xtensa32/bin",
+            "executable": "d:/sourceTree/ESP-1ch-Gateway/.pio/build/Gateway_21/firmware.elf",
+            "toolchainBinDir": "C:/Users/maarten/.platformio/packages/toolchain-xtensa/bin",
             "internalConsoleOptions": "openOnSessionStart"
         }
     ]

+ 10 - 2
CHANGELOG.md

@@ -1,6 +1,6 @@
 # Single Channel LoRaWAN Gateway
 
-Version 6.2.0, January 24, 2020 
+Version 6.2.0, January 29, 2020 
 Author: M. Westenberg (mw12554@hotmail.com)  
 Copyright: M. Westenberg (mw12554@hotmail.com)  
 
@@ -16,7 +16,12 @@ Maintained by Maarten Westenberg (mw12554@hotmail.com)
 
 # Release Notes
 
-features release 6.2.1 (February 2, 2020)
+Features release 6.2.3 (February 23, 2020)
+- Lots of bugs and documentation fixes
+- Added customizable #define statements through platformio.ini file (Read!!!)
+- Changed the WiFiManager code to better support both architectures: ESP8266 and ESP32\
+
+Features release 6.2.1 (February 2, 2020)
 - PlatformIO support
 
 Features release 6.2.0 (January 29, 2020)
@@ -25,6 +30,9 @@ Features release 6.2.0 (January 29, 2020)
 - Change delays for GPS and other internal sensors, and repair internal 
   sensors to make sure we do not miss sensor messages
 - Changed the MONITOR part to a circular buffer to save time when filling buffer
+- Statistics log redefined
+- Removed variables never used (PackaIO)
+
 
 Features release 6.1.8 (January 21, 2020)
 - Repair wifimanager compile for ESP8266, and make it work for ESP8266

+ 4 - 3
TODO.md

@@ -1,6 +1,6 @@
 # Single Channel LoRaWAN Gateway
 
-Last Updated: January 29, 2020	  
+Last Updated: February 23, 2020	  
 Author: M. Westenberg (mw12554@hotmail.com)  
 Copyright: M. Westenberg (mw12554@hotmail.com)  
 
@@ -16,16 +16,17 @@ Maintained by Maarten Westenberg (mw12554@hotmail.com)
 
 # ToDo Functions
 
-Features not in release 6.1.8
+Features not in release 6.2.3
 
 
-- Frequency: Support for eu433 frequencies
+- Frequency: Support for eu433 frequencies (Standard)
 - Testing and timing of downlink functions (need quiet area)
 - Get HOP frequency functions to work on three frequencies
 - Security: Enable passwords for GUI access and WiFi upload (may not be necessary for normal home router use)
 - Enable remote updating through GUI
 - Support FSK (May not be necessary)
 - Support for other Mode A and B of LoRa devices
+- Support for 3G/4G/5G devices
 
 
 

+ 0 - 6
lib/ESP32WebServer/README.md

@@ -1,6 +0,0 @@
-visit IOTSHARING.COM for more
-# esp32_webserver
-
-This is for Arduino esp8266 I modified to adapt with esp32
-
-Just put it in Arduino/libraries folder and run examples

+ 0 - 72
lib/ESP32WebServer/examples/esp32webserver1/esp32webserver1.ino

@@ -1,72 +0,0 @@
-#include <WiFiClient.h>
-#include <ESP32WebServer.h>
-#include <WiFi.h>
-#include <ESPmDNS.h>
-
-const char* ssid = "mieu mieu 01";
-const char* password = "09471919479";
-
-ESP32WebServer server(80);
-
-const int led = 13;
-
-void handleRoot() {
-  digitalWrite(led, 1);
-  server.send(200, "text/plain", "hello from ESP32!");
-  digitalWrite(led, 0);
-}
-
-void handleNotFound(){
-  digitalWrite(led, 1);
-  String message = "File Not Found\n\n";
-  message += "URI: ";
-  message += server.uri();
-  message += "\nMethod: ";
-  message += (server.method() == HTTP_GET)?"GET":"POST";
-  message += "\nArguments: ";
-  message += server.args();
-  message += "\n";
-  for (uint8_t i=0; i<server.args(); i++){
-    message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
-  }
-  server.send(404, "text/plain", message);
-  digitalWrite(led, 0);
-}
-
-void setup(void){
-  pinMode(led, OUTPUT);
-  digitalWrite(led, 0);
-  Serial.begin(115200);
-  WiFi.begin(ssid, password);
-  Serial.println("");
-
-  // Wait for connection
-  while (WiFi.status() != WL_CONNECTED) {
-    delay(500);
-    Serial.print(".");
-  }
-  Serial.println("");
-  Serial.print("Connected to ");
-  Serial.println(ssid);
-  Serial.print("IP address: ");
-  Serial.println(WiFi.localIP());
-
-  if (MDNS.begin("esp32")) {
-    Serial.println("MDNS responder started");
-  }
-
-  server.on("/", handleRoot);
-
-  server.on("/inline", [](){
-    server.send(200, "text/plain", "this works as well");
-  });
-
-  server.onNotFound(handleNotFound);
-
-  server.begin();
-  Serial.println("HTTP server started");
-}
-
-void loop(void){
-  server.handleClient();
-}

+ 0 - 145
lib/ESP32WebServer/examples/esp32webserver2/esp32webserver2.ino

@@ -1,145 +0,0 @@
-/*
- * Copyright (c) 2015, Majenko Technologies
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice, this
- *   list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice, this
- *   list of conditions and the following disclaimer in the documentation and/or
- *   other materials provided with the distribution.
- *
- * * Neither the name of Majenko Technologies nor the names of its
- *   contributors may be used to endorse or promote products derived from
- *   this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <WiFiClient.h>
-#include <ESP32WebServer.h>
-#include <WiFi.h>
-#include <ESPmDNS.h>
-
-const char* ssid = "mieu mieu 01";
-const char* password = "09471919479";
-
-ESP32WebServer server ( 80 );
-
-const int led = 13;
-
-void handleRoot() {
-  digitalWrite ( led, 1 );
-  char temp[400];
-  int sec = millis() / 1000;
-  int min = sec / 60;
-  int hr = min / 60;
-
-  snprintf ( temp, 400,
-
-"<html>\
-  <head>\
-    <meta http-equiv='refresh' content='5'/>\
-    <title>ESP32 Demo</title>\
-    <style>\
-      body { background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Color: #000088; }\
-    </style>\
-  </head>\
-  <body>\
-    <h1>Hello from ESP32!</h1>\
-    <p>Uptime: %02d:%02d:%02d</p>\
-    <img src=\"/test.svg\" />\
-  </body>\
-</html>",
-
-    hr, min % 60, sec % 60
-  );
-  server.send ( 200, "text/html", temp );
-  digitalWrite ( led, 0 );
-}
-
-void handleNotFound() {
-  digitalWrite ( led, 1 );
-  String message = "File Not Found\n\n";
-  message += "URI: ";
-  message += server.uri();
-  message += "\nMethod: ";
-  message += ( server.method() == HTTP_GET ) ? "GET" : "POST";
-  message += "\nArguments: ";
-  message += server.args();
-  message += "\n";
-
-  for ( uint8_t i = 0; i < server.args(); i++ ) {
-    message += " " + server.argName ( i ) + ": " + server.arg ( i ) + "\n";
-  }
-
-  server.send ( 404, "text/plain", message );
-  digitalWrite ( led, 0 );
-}
-
-void setup ( void ) {
-  pinMode ( led, OUTPUT );
-  digitalWrite ( led, 0 );
-  Serial.begin ( 115200 );
-  WiFi.begin ( ssid, password );
-  Serial.println ( "" );
-
-  // Wait for connection
-  while ( WiFi.status() != WL_CONNECTED ) {
-    delay ( 500 );
-    Serial.print ( "." );
-  }
-
-  Serial.println ( "" );
-  Serial.print ( "Connected to " );
-  Serial.println ( ssid );
-  Serial.print ( "IP address: " );
-  Serial.println ( WiFi.localIP() );
-
-  if ( MDNS.begin ( "esp32" ) ) {
-    Serial.println ( "MDNS responder started" );
-  }
-
-  server.on ( "/", handleRoot );
-  server.on ( "/test.svg", drawGraph );
-  server.on ( "/inline", []() {
-    server.send ( 200, "text/plain", "this works as well" );
-  } );
-  server.onNotFound ( handleNotFound );
-  server.begin();
-  Serial.println ( "HTTP server started" );
-}
-
-void loop ( void ) {
-  server.handleClient();
-}
-
-void drawGraph() {
-  String out = "";
-  char temp[100];
-  out += "<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" width=\"400\" height=\"150\">\n";
-  out += "<rect width=\"400\" height=\"150\" fill=\"rgb(250, 230, 210)\" stroke-width=\"1\" stroke=\"rgb(0, 0, 0)\" />\n";
-  out += "<g stroke=\"black\">\n";
-  int y = rand() % 130;
-  for (int x = 10; x < 390; x+= 10) {
-    int y2 = rand() % 130;
-    sprintf(temp, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" stroke-width=\"1\" />\n", x, 140 - y, x + 10, 140 - y2);
-    out += temp;
-    y = y2;
-  }
-  out += "</g>\n</svg>\n";
-
-  server.send ( 200, "image/svg+xml", out);
-}

+ 0 - 36
lib/ESP32WebServer/keywords.txt

@@ -1,36 +0,0 @@
-#######################################
-# Syntax Coloring Map For Ultrasound
-#######################################
-
-#######################################
-# Datatypes (KEYWORD1)
-#######################################
-
-ESP32WebServer	KEYWORD1
-HTTPMethod	KEYWORD1
-
-#######################################
-# Methods and Functions (KEYWORD2)
-#######################################
-
-begin	KEYWORD2
-handleClient	KEYWORD2
-on	KEYWORD2
-addHandler	KEYWORD2
-uri	KEYWORD2
-method	KEYWORD2
-client	KEYWORD2
-send	KEYWORD2
-arg	KEYWORD2
-argName	KEYWORD2
-args	KEYWORD2
-hasArg	KEYWORD2
-onNotFound	KEYWORD2
-
-#######################################
-# Constants (LITERAL1)
-#######################################
-
-HTTP_GET	LITERAL1
-HTTP_POST	LITERAL1
-HTTP_ANY	LITERAL1

+ 0 - 9
lib/ESP32WebServer/library.properties

@@ -1,9 +0,0 @@
-name=ESP32WebServer
-version=1.0
-author=Ivan Grokhotkov
-maintainer=Ivan Grokhtkov <ivan@ESP32.com>
-sentence=Simple web server library
-paragraph=The library supports HTTP GET and POST requests, provides argument parsing, handles one client at a time.
-category=Communication
-url=
-architectures=ESP32

+ 0 - 537
lib/ESP32WebServer/src/ESP32WebServer.cpp

@@ -1,537 +0,0 @@
-/*
-  ESP32WebServer.cpp - Dead simple web-server.
-  Supports only one simultaneous client, knows how to handle GET and POST.
-
-  Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-  Modified 8 May 2015 by Hristo Gochkov (proper post and file upload handling)
-*/
-
-
-#include <Arduino.h>
-#include <libb64/cencode.h>
-#include "WiFiServer.h"
-#include "WiFiClient.h"
-#include "ESP32WebServer.h"
-#include "FS.h"
-#include "detail/RequestHandlersImpl.h"
-
-//#define DEBUG_ESP_HTTP_SERVER
-#ifdef DEBUG_ESP_PORT
-#define DEBUG_OUTPUT DEBUG_ESP_PORT
-#else
-#define DEBUG_OUTPUT Serial
-#endif
-
-const char * AUTHORIZATION_HEADER = "Authorization";
-
-ESP32WebServer::ESP32WebServer(IPAddress addr, int port)
-: _server(addr, port)
-, _currentMethod(HTTP_ANY)
-, _currentVersion(0)
-, _currentStatus(HC_NONE)
-, _statusChange(0)
-, _currentHandler(0)
-, _firstHandler(0)
-, _lastHandler(0)
-, _currentArgCount(0)
-, _currentArgs(0)
-, _headerKeysCount(0)
-, _currentHeaders(0)
-, _contentLength(0)
-, _chunked(false)
-{
-}
-
-ESP32WebServer::ESP32WebServer(int port)
-: _server(port)
-, _currentMethod(HTTP_ANY)
-, _currentVersion(0)
-, _currentStatus(HC_NONE)
-, _statusChange(0)
-, _currentHandler(0)
-, _firstHandler(0)
-, _lastHandler(0)
-, _currentArgCount(0)
-, _currentArgs(0)
-, _headerKeysCount(0)
-, _currentHeaders(0)
-, _contentLength(0)
-, _chunked(false)
-{
-}
-
-ESP32WebServer::~ESP32WebServer() {
-  if (_currentHeaders)
-    delete[]_currentHeaders;
-  _headerKeysCount = 0;
-  RequestHandler* handler = _firstHandler;
-  while (handler) {
-    RequestHandler* next = handler->next();
-    delete handler;
-    handler = next;
-  }
-  close();
-}
-
-void ESP32WebServer::begin() {
-  _currentStatus = HC_NONE;
-  _server.begin();
-  if(!_headerKeysCount)
-    collectHeaders(0, 0);
-}
-
-bool ESP32WebServer::authenticate(const char * username, const char * password){
-  if(hasHeader(AUTHORIZATION_HEADER)){
-    String authReq = header(AUTHORIZATION_HEADER);
-    if(authReq.startsWith("Basic")){
-      authReq = authReq.substring(6);
-      authReq.trim();
-      char toencodeLen = strlen(username)+strlen(password)+1;
-      char *toencode = new char[toencodeLen + 1];
-      if(toencode == NULL){
-        authReq = String();
-        return false;
-      }
-      char *encoded = new char[base64_encode_expected_len(toencodeLen)+1];
-      if(encoded == NULL){
-        authReq = String();
-        delete[] toencode;
-        return false;
-      }
-      sprintf(toencode, "%s:%s", username, password);
-      if(base64_encode_chars(toencode, toencodeLen, encoded) > 0 && authReq.equals(encoded)){
-        authReq = String();
-        delete[] toencode;
-        delete[] encoded;
-        return true;
-      }
-      delete[] toencode;
-      delete[] encoded;
-    }
-    authReq = String();
-  }
-  return false;
-}
-
-void ESP32WebServer::requestAuthentication(){
-  sendHeader("WWW-Authenticate", "Basic realm=\"Login Required\"");
-  send(401);
-}
-
-void ESP32WebServer::on(const String &uri, ESP32WebServer::THandlerFunction handler) {
-  on(uri, HTTP_ANY, handler);
-}
-
-void ESP32WebServer::on(const String &uri, HTTPMethod method, ESP32WebServer::THandlerFunction fn) {
-  on(uri, method, fn, _fileUploadHandler);
-}
-
-void ESP32WebServer::on(const String &uri, HTTPMethod method, ESP32WebServer::THandlerFunction fn, ESP32WebServer::THandlerFunction ufn) {
-  _addRequestHandler(new FunctionRequestHandler(fn, ufn, uri, method));
-}
-
-void ESP32WebServer::addHandler(RequestHandler* handler) {
-    _addRequestHandler(handler);
-}
-
-void ESP32WebServer::_addRequestHandler(RequestHandler* handler) {
-    if (!_lastHandler) {
-      _firstHandler = handler;
-      _lastHandler = handler;
-    }
-    else {
-      _lastHandler->next(handler);
-      _lastHandler = handler;
-    }
-}
-
-void ESP32WebServer::serveStatic(const char* uri, FS& fs, const char* path, const char* cache_header) {
-    _addRequestHandler(new StaticRequestHandler(fs, path, uri, cache_header));
-}
-
-void ESP32WebServer::handleClient() {
-  if (_currentStatus == HC_NONE) {
-    WiFiClient client = _server.available();
-    if (!client) {
-      return;
-    }
-
-#ifdef DEBUG_ESP_HTTP_SERVER
-    log_e("New client");
-#endif
-
-    _currentClient = client;
-    _currentStatus = HC_WAIT_READ;
-    _statusChange = millis();
-  }
-
-  if (!_currentClient.connected()) {
-    _currentClient = WiFiClient();
-    _currentStatus = HC_NONE;
-    return;
-  }
-
-  // Wait for data from client to become available
-  if (_currentStatus == HC_WAIT_READ) {
-    if (!_currentClient.available()) {
-      if (millis() - _statusChange > HTTP_MAX_DATA_WAIT) {
-        _currentClient = WiFiClient();
-        _currentStatus = HC_NONE;
-      }
-      yield();
-      return;
-    }
-
-    if (!_parseRequest(_currentClient)) {
-      _currentClient = WiFiClient();
-      _currentStatus = HC_NONE;
-      return;
-    }
-    _currentClient.setTimeout(HTTP_MAX_SEND_WAIT);
-    _contentLength = CONTENT_LENGTH_NOT_SET;
-    _handleRequest();
-
-    if (!_currentClient.connected()) {
-      _currentClient = WiFiClient();
-      _currentStatus = HC_NONE;
-      return;
-    } else {
-      _currentStatus = HC_WAIT_CLOSE;
-      _statusChange = millis();
-      return;
-    }
-  }
-
-  if (_currentStatus == HC_WAIT_CLOSE) {
-    if (millis() - _statusChange > HTTP_MAX_CLOSE_WAIT) {
-      _currentClient = WiFiClient();
-      _currentStatus = HC_NONE;
-    } else {
-      yield();
-      return;
-    }
-  }
-}
-
-void ESP32WebServer::close() {
-  _server.end();
-}
-
-void ESP32WebServer::stop() {
-  close();
-}
-
-void ESP32WebServer::sendHeader(const String& name, const String& value, bool first) {
-  String headerLine = name;
-  headerLine += ": ";
-  headerLine += value;
-  headerLine += "\r\n";
-
-  if (first) {
-    _responseHeaders = headerLine + _responseHeaders;
-  }
-  else {
-    _responseHeaders += headerLine;
-  }
-}
-
-void ESP32WebServer::setContentLength(size_t contentLength) {
-    _contentLength = contentLength;
-}
-
-void ESP32WebServer::_prepareHeader(String& response, int code, const char* content_type, size_t contentLength) {
-    response = "HTTP/1."+String(_currentVersion)+" ";
-    response += String(code);
-    response += " ";
-    response += _responseCodeToString(code);
-    response += "\r\n";
-
-    if (!content_type)
-        content_type = "text/html";
-
-    sendHeader("Content-Type", content_type, true);
-    if (_contentLength == CONTENT_LENGTH_NOT_SET) {
-        sendHeader("Content-Length", String(contentLength));
-    } else if (_contentLength != CONTENT_LENGTH_UNKNOWN) {
-        sendHeader("Content-Length", String(_contentLength));
-    } else if(_contentLength == CONTENT_LENGTH_UNKNOWN && _currentVersion){ //HTTP/1.1 or above client
-      //let's do chunked
-      _chunked = true;
-      sendHeader("Accept-Ranges","none");
-      sendHeader("Transfer-Encoding","chunked");
-    }
-    sendHeader("Connection", "close");
-
-    response += _responseHeaders;
-    response += "\r\n";
-    _responseHeaders = String();
-}
-
-void ESP32WebServer::send(int code, const char* content_type, const String& content) {
-    String header;
-    // Can we asume the following?
-    //if(code == 200 && content.length() == 0 && _contentLength == CONTENT_LENGTH_NOT_SET)
-    //  _contentLength = CONTENT_LENGTH_UNKNOWN;
-    _prepareHeader(header, code, content_type, content.length());
-    _currentClient.write(header.c_str(), header.length());
-    if(content.length())
-      sendContent(content);
-}
-
-void ESP32WebServer::send_P(int code, PGM_P content_type, PGM_P content) {
-    size_t contentLength = 0;
-
-    if (content != NULL) {
-        contentLength = strlen_P(content);
-    }
-
-    String header;
-    char type[64];
-    memccpy_P((void*)type, (PGM_VOID_P)content_type, 0, sizeof(type));
-    _prepareHeader(header, code, (const char* )type, contentLength);
-    _currentClient.write(header.c_str(), header.length());
-    sendContent_P(content);
-}
-
-void ESP32WebServer::send_P(int code, PGM_P content_type, PGM_P content, size_t contentLength) {
-    String header;
-    char type[64];
-    memccpy_P((void*)type, (PGM_VOID_P)content_type, 0, sizeof(type));
-    _prepareHeader(header, code, (const char* )type, contentLength);
-    sendContent(header);
-    sendContent_P(content, contentLength);
-}
-
-void ESP32WebServer::send(int code, char* content_type, const String& content) {
-  send(code, (const char*)content_type, content);
-}
-
-void ESP32WebServer::send(int code, const String& content_type, const String& content) {
-  send(code, (const char*)content_type.c_str(), content);
-}
-
-void ESP32WebServer::sendContent(const String& content) {
-  const char * footer = "\r\n";
-  size_t len = content.length();
-  if(_chunked) {
-    char * chunkSize = (char *)malloc(11);
-    if(chunkSize){
-      sprintf(chunkSize, "%x%s", len, footer);
-      _currentClient.write(chunkSize, strlen(chunkSize));
-      free(chunkSize);
-    }
-  }
-  _currentClient.write(content.c_str(), len);
-  if(_chunked){
-    _currentClient.write(footer, 2);
-  }
-}
-
-void ESP32WebServer::sendContent_P(PGM_P content) {
-  sendContent_P(content, strlen_P(content));
-}
-
-void ESP32WebServer::sendContent_P(PGM_P content, size_t size) {
-  const char * footer = "\r\n";
-  if(_chunked) {
-    char * chunkSize = (char *)malloc(11);
-    if(chunkSize){
-      sprintf(chunkSize, "%x%s", size, footer);
-      _currentClient.write(chunkSize, strlen(chunkSize));
-      free(chunkSize);
-    }
-  }
-  size_t chunkSize = 20;
-  int idx = 0;
-  while(size != 0){
-      if(size < chunkSize){
-        _currentClient.write(&content[idx], size);
-        size = 0;
-      } else {
-        _currentClient.write(&content[idx], chunkSize);
-        size -= chunkSize;
-        idx += chunkSize;
-      }
-    yield();
-  }
-  if(_chunked){
-    _currentClient.write(footer, 2);
-  }
-}
-
-
-String ESP32WebServer::arg(String name) {
-  for (int i = 0; i < _currentArgCount; ++i) {
-    if ( _currentArgs[i].key == name )
-      return _currentArgs[i].value;
-  }
-  return String();
-}
-
-String ESP32WebServer::arg(int i) {
-  if (i < _currentArgCount)
-    return _currentArgs[i].value;
-  return String();
-}
-
-String ESP32WebServer::argName(int i) {
-  if (i < _currentArgCount)
-    return _currentArgs[i].key;
-  return String();
-}
-
-int ESP32WebServer::args() {
-  return _currentArgCount;
-}
-
-bool ESP32WebServer::hasArg(String  name) {
-  for (int i = 0; i < _currentArgCount; ++i) {
-    if (_currentArgs[i].key == name)
-      return true;
-  }
-  return false;
-}
-
-
-String ESP32WebServer::header(String name) {
-  for (int i = 0; i < _headerKeysCount; ++i) {
-    if (_currentHeaders[i].key.equalsIgnoreCase(name))
-      return _currentHeaders[i].value;
-  }
-  return String();
-}
-
-void ESP32WebServer::collectHeaders(const char* headerKeys[], const size_t headerKeysCount) {
-  _headerKeysCount = headerKeysCount + 1;
-  if (_currentHeaders)
-     delete[]_currentHeaders;
-  _currentHeaders = new RequestArgument[_headerKeysCount];
-  _currentHeaders[0].key = AUTHORIZATION_HEADER;
-  for (int i = 1; i < _headerKeysCount; i++){
-    _currentHeaders[i].key = headerKeys[i-1];
-  }
-}
-
-String ESP32WebServer::header(int i) {
-  if (i < _headerKeysCount)
-    return _currentHeaders[i].value;
-  return String();
-}
-
-String ESP32WebServer::headerName(int i) {
-  if (i < _headerKeysCount)
-    return _currentHeaders[i].key;
-  return String();
-}
-
-int ESP32WebServer::headers() {
-  return _headerKeysCount;
-}
-
-bool ESP32WebServer::hasHeader(String name) {
-  for (int i = 0; i < _headerKeysCount; ++i) {
-    if ((_currentHeaders[i].key.equalsIgnoreCase(name)) &&  (_currentHeaders[i].value.length() > 0))
-      return true;
-  }
-  return false;
-}
-
-String ESP32WebServer::hostHeader() {
-  return _hostHeader;
-}
-
-void ESP32WebServer::onFileUpload(THandlerFunction fn) {
-  _fileUploadHandler = fn;
-}
-
-void ESP32WebServer::onNotFound(THandlerFunction fn) {
-  _notFoundHandler = fn;
-}
-
-void ESP32WebServer::_handleRequest() {
-  bool handled = false;
-  if (!_currentHandler){
-#ifdef DEBUG_ESP_HTTP_SERVER
-    DEBUG_OUTPUT.println("request handler not found");
-#endif
-  }
-  else {
-    handled = _currentHandler->handle(*this, _currentMethod, _currentUri);
-#ifdef DEBUG_ESP_HTTP_SERVER
-    if (!handled) {
-      DEBUG_OUTPUT.println("request handler failed to handle request");
-    }
-#endif
-  }
-
-  if (!handled) {
-    if(_notFoundHandler) {
-      _notFoundHandler();
-    }
-    else {
-      send(404, "text/plain", String("Not found: ") + _currentUri);
-    }
-  }
-
-  _currentUri = String();
-}
-
-String ESP32WebServer::_responseCodeToString(int code) {
-  switch (code) {
-    case 100: return F("Continue");
-    case 101: return F("Switching Protocols");
-    case 200: return F("OK");
-    case 201: return F("Created");
-    case 202: return F("Accepted");
-    case 203: return F("Non-Authoritative Information");
-    case 204: return F("No Content");
-    case 205: return F("Reset Content");
-    case 206: return F("Partial Content");
-    case 300: return F("Multiple Choices");
-    case 301: return F("Moved Permanently");
-    case 302: return F("Found");
-    case 303: return F("See Other");
-    case 304: return F("Not Modified");
-    case 305: return F("Use Proxy");
-    case 307: return F("Temporary Redirect");
-    case 400: return F("Bad Request");
-    case 401: return F("Unauthorized");
-    case 402: return F("Payment Required");
-    case 403: return F("Forbidden");
-    case 404: return F("Not Found");
-    case 405: return F("Method Not Allowed");
-    case 406: return F("Not Acceptable");
-    case 407: return F("Proxy Authentication Required");
-    case 408: return F("Request Time-out");
-    case 409: return F("Conflict");
-    case 410: return F("Gone");
-    case 411: return F("Length Required");
-    case 412: return F("Precondition Failed");
-    case 413: return F("Request Entity Too Large");
-    case 414: return F("Request-URI Too Large");
-    case 415: return F("Unsupported Media Type");
-    case 416: return F("Requested range not satisfiable");
-    case 417: return F("Expectation Failed");
-    case 500: return F("Internal Server Error");
-    case 501: return F("Not Implemented");
-    case 502: return F("Bad Gateway");
-    case 503: return F("Service Unavailable");
-    case 504: return F("Gateway Time-out");
-    case 505: return F("HTTP Version not supported");
-    default:  return "";
-  }
-}

+ 0 - 192
lib/ESP32WebServer/src/ESP32WebServer.h

@@ -1,192 +0,0 @@
-/*
-  ESP32WebServer.h - Dead simple web-server.
-  Supports only one simultaneous client, knows how to handle GET and POST.
-
-  Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-  Modified 8 May 2015 by Hristo Gochkov (proper post and file upload handling)
-*/
-
-
-#ifndef ESP32WEBSERVER_H
-#define ESP32WEBSERVER_H
-
-#include <functional>
-#include <WiFi.h>
-
-enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS };
-enum HTTPUploadStatus { UPLOAD_FILE_START, UPLOAD_FILE_WRITE, UPLOAD_FILE_END,
-                        UPLOAD_FILE_ABORTED };
-enum HTTPClientStatus { HC_NONE, HC_WAIT_READ, HC_WAIT_CLOSE };
-
-#define HTTP_DOWNLOAD_UNIT_SIZE 1460
-#define HTTP_UPLOAD_BUFLEN 2048
-#define HTTP_MAX_DATA_WAIT 1000 //ms to wait for the client to send the request
-#define HTTP_MAX_POST_WAIT 1000 //ms to wait for POST data to arrive
-#define HTTP_MAX_SEND_WAIT 5000 //ms to wait for data chunk to be ACKed
-#define HTTP_MAX_CLOSE_WAIT 2000 //ms to wait for the client to close the connection
-
-#define CONTENT_LENGTH_UNKNOWN ((size_t) -1)
-#define CONTENT_LENGTH_NOT_SET ((size_t) -2)
-
-class ESP32WebServer;
-
-typedef struct {
-  HTTPUploadStatus status;
-  String  filename;
-  String  name;
-  String  type;
-  size_t  totalSize;    // file size
-  size_t  currentSize;  // size of data currently in buf
-  uint8_t buf[HTTP_UPLOAD_BUFLEN];
-} HTTPUpload;
-
-#include "detail/RequestHandler.h"
-
-namespace fs {
-class FS;
-}
-
-class ESP32WebServer
-{
-public:
-  ESP32WebServer(IPAddress addr, int port = 80);
-  ESP32WebServer(int port = 80);
-  ~ESP32WebServer();
-
-  void begin();
-  void handleClient();
-
-  void close();
-  void stop();
-
-  bool authenticate(const char * username, const char * password);
-  void requestAuthentication();
-
-  typedef std::function<void(void)> THandlerFunction;
-  void on(const String &uri, THandlerFunction handler);
-  void on(const String &uri, HTTPMethod method, THandlerFunction fn);
-  void on(const String &uri, HTTPMethod method, THandlerFunction fn, THandlerFunction ufn);
-  void addHandler(RequestHandler* handler);
-  void serveStatic(const char* uri, fs::FS& fs, const char* path, const char* cache_header = NULL );
-  void onNotFound(THandlerFunction fn);  //called when handler is not assigned
-  void onFileUpload(THandlerFunction fn); //handle file uploads
-
-  String uri() { return _currentUri; }
-  HTTPMethod method() { return _currentMethod; }
-  WiFiClient client() { return _currentClient; }
-  HTTPUpload& upload() { return _currentUpload; }
-
-  String arg(String name);        // get request argument value by name
-  String arg(int i);              // get request argument value by number
-  String argName(int i);          // get request argument name by number
-  int args();                     // get arguments count
-  bool hasArg(String name);       // check if argument exists
-  void collectHeaders(const char* headerKeys[], const size_t headerKeysCount); // set the request headers to collect
-  String header(String name);      // get request header value by name
-  String header(int i);              // get request header value by number
-  String headerName(int i);          // get request header name by number
-  int headers();                     // get header count
-  bool hasHeader(String name);       // check if header exists
-
-  String hostHeader();            // get request host header if available or empty String if not
-
-  // send response to the client
-  // code - HTTP response code, can be 200 or 404
-  // content_type - HTTP content type, like "text/plain" or "image/png"
-  // content - actual content body
-  void send(int code, const char* content_type = NULL, const String& content = String(""));
-  void send(int code, char* content_type, const String& content);
-  void send(int code, const String& content_type, const String& content);
-  void send_P(int code, PGM_P content_type, PGM_P content);
-  void send_P(int code, PGM_P content_type, PGM_P content, size_t contentLength);
-
-  void setContentLength(size_t contentLength);
-  void sendHeader(const String& name, const String& value, bool first = false);
-  void sendContent(const String& content);
-  void sendContent_P(PGM_P content);
-  void sendContent_P(PGM_P content, size_t size);
-
-  static String urlDecode(const String& text);
-
-template<typename T> size_t streamFile(T &file, const String& contentType){
-  setContentLength(file.size());
-  if (String(file.name()).endsWith(".gz") &&
-      contentType != "application/x-gzip" &&
-      contentType != "application/octet-stream"){
-    sendHeader("Content-Encoding", "gzip");
-  }
-  send(200, contentType, "");
-  uint8_t buf[20];
-  size_t fsize = 0;
-  while(file.available()){
-      int got = file.read(buf, 20);
-      _currentClient.write(buf, got);
-      fsize += got;
-      yield();
-  }
-  return fsize;
-}
-
-protected:
-  void _addRequestHandler(RequestHandler* handler);
-  void _handleRequest();
-  bool _parseRequest(WiFiClient& client);
-  void _parseArguments(String data);
-  static String _responseCodeToString(int code);
-  bool _parseForm(WiFiClient& client, String boundary, uint32_t len);
-  bool _parseFormUploadAborted();
-  void _uploadWriteByte(uint8_t b);
-  uint8_t _uploadReadByte(WiFiClient& client);
-  void _prepareHeader(String& response, int code, const char* content_type, size_t contentLength);
-  bool _collectHeader(const char* headerName, const char* headerValue);
-
-  struct RequestArgument {
-    String key;
-    String value;
-  };
-
-  WiFiServer  _server;
-
-  WiFiClient  _currentClient;
-  HTTPMethod  _currentMethod;
-  String      _currentUri;
-  uint8_t     _currentVersion;
-  HTTPClientStatus _currentStatus;
-  unsigned long _statusChange;
-
-  RequestHandler*  _currentHandler;
-  RequestHandler*  _firstHandler;
-  RequestHandler*  _lastHandler;
-  THandlerFunction _notFoundHandler;
-  THandlerFunction _fileUploadHandler;
-
-  int              _currentArgCount;
-  RequestArgument* _currentArgs;
-  HTTPUpload       _currentUpload;
-
-  int              _headerKeysCount;
-  RequestArgument* _currentHeaders;
-  size_t           _contentLength;
-  String           _responseHeaders;
-
-  String           _hostHeader;
-  bool             _chunked;
-
-};
-
-
-#endif //ESP32WEBSERVER_H

+ 0 - 607
lib/ESP32WebServer/src/Parsing.cpp

@@ -1,607 +0,0 @@
-/*
-  Parsing.cpp - HTTP request parsing.
-
-  Copyright (c) 2015 Ivan Grokhotkov. All rights reserved.
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-  Modified 8 May 2015 by Hristo Gochkov (proper post and file upload handling)
-*/
-
-#include <Arduino.h>
-#include "WiFiServer.h"
-#include "WiFiClient.h"
-#include "ESP32WebServer.h"
-
-//#define DEBUG_ESP_HTTP_SERVER
-#ifdef DEBUG_ESP_PORT
-#define DEBUG_OUTPUT DEBUG_ESP_PORT
-#else
-#define DEBUG_OUTPUT Serial
-#endif
-
-static char* readBytesWithTimeout(WiFiClient& client, size_t maxLength, size_t& dataLength, int timeout_ms)
-{
-  char *buf = nullptr;
-  dataLength = 0;
-  while (dataLength < maxLength) {
-    int tries = timeout_ms;
-    size_t newLength;
-    while (!(newLength = client.available()) && tries--) delay(1);
-    if (!newLength) {
-      break;
-    }
-    if (!buf) {
-      buf = (char *) malloc(newLength + 1);
-      if (!buf) {
-        return nullptr;
-      }
-    }
-    else {
-      char* newBuf = (char *) realloc(buf, dataLength + newLength + 1);
-      if (!newBuf) {
-        free(buf);
-        return nullptr;
-      }
-      buf = newBuf;
-    }
-    client.readBytes(buf + dataLength, newLength);
-    dataLength += newLength;
-    buf[dataLength] = '\0';
-  }
-  return buf;
-}
-
-bool ESP32WebServer::_parseRequest(WiFiClient& client) {
-  // Read the first line of HTTP request
-  String req = client.readStringUntil('\r');
-  client.readStringUntil('\n');
-  //reset header value
-  for (int i = 0; i < _headerKeysCount; ++i) {
-    _currentHeaders[i].value =String();
-   }
-
-  // First line of HTTP request looks like "GET /path HTTP/1.1"
-  // Retrieve the "/path" part by finding the spaces
-  int addr_start = req.indexOf(' ');
-  int addr_end = req.indexOf(' ', addr_start + 1);
-  if (addr_start == -1 || addr_end == -1) {
-#ifdef DEBUG_ESP_HTTP_SERVER
-    DEBUG_OUTPUT.print("Invalid request: ");
-    DEBUG_OUTPUT.println(req);
-#endif
-    return false;
-  }
-
-  String methodStr = req.substring(0, addr_start);
-  String url = req.substring(addr_start + 1, addr_end);
-  String versionEnd = req.substring(addr_end + 8);
-  _currentVersion = atoi(versionEnd.c_str());
-  String searchStr = "";
-  int hasSearch = url.indexOf('?');
-  if (hasSearch != -1){
-    searchStr = urlDecode(url.substring(hasSearch + 1));
-    url = url.substring(0, hasSearch);
-  }
-  _currentUri = url;
-  _chunked = false;
-
-  HTTPMethod method = HTTP_GET;
-  if (methodStr == "POST") {
-    method = HTTP_POST;
-  } else if (methodStr == "DELETE") {
-    method = HTTP_DELETE;
-  } else if (methodStr == "OPTIONS") {
-    method = HTTP_OPTIONS;
-  } else if (methodStr == "PUT") {
-    method = HTTP_PUT;
-  } else if (methodStr == "PATCH") {
-    method = HTTP_PATCH;
-  }
-  _currentMethod = method;
-
-#ifdef DEBUG_ESP_HTTP_SERVER
-  DEBUG_OUTPUT.print("method: ");
-  DEBUG_OUTPUT.print(methodStr);
-  DEBUG_OUTPUT.print(" url: ");
-  DEBUG_OUTPUT.print(url);
-  DEBUG_OUTPUT.print(" search: ");
-  DEBUG_OUTPUT.println(searchStr);
-#endif
-
-  //attach handler
-  RequestHandler* handler;
-  for (handler = _firstHandler; handler; handler = handler->next()) {
-    if (handler->canHandle(_currentMethod, _currentUri))
-      break;
-  }
-  _currentHandler = handler;
-
-  String formData;
-  // below is needed only when POST type request
-  if (method == HTTP_POST || method == HTTP_PUT || method == HTTP_PATCH || method == HTTP_DELETE){
-    String boundaryStr;
-    String headerName;
-    String headerValue;
-    bool isForm = false;
-    bool isEncoded = false;
-    uint32_t contentLength = 0;
-    //parse headers
-    while(1){
-      req = client.readStringUntil('\r');
-      client.readStringUntil('\n');
-      if (req == "") break;//no moar headers
-      int headerDiv = req.indexOf(':');
-      if (headerDiv == -1){
-        break;
-      }
-      headerName = req.substring(0, headerDiv);
-      headerValue = req.substring(headerDiv + 1);
-      headerValue.trim();
-       _collectHeader(headerName.c_str(),headerValue.c_str());
-
-      #ifdef DEBUG_ESP_HTTP_SERVER
-      DEBUG_OUTPUT.print("headerName: ");
-      DEBUG_OUTPUT.println(headerName);
-      DEBUG_OUTPUT.print("headerValue: ");
-      DEBUG_OUTPUT.println(headerValue);
-      #endif
-
-      if (headerName.equalsIgnoreCase("Content-Type")){
-        if (headerValue.startsWith("text/plain")){
-          isForm = false;
-        } else if (headerValue.startsWith("application/x-www-form-urlencoded")){
-          isForm = false;
-          isEncoded = true;
-        } else if (headerValue.startsWith("multipart/")){
-          boundaryStr = headerValue.substring(headerValue.indexOf('=')+1);
-          isForm = true;
-        }
-      } else if (headerName.equalsIgnoreCase("Content-Length")){
-        contentLength = headerValue.toInt();
-      } else if (headerName.equalsIgnoreCase("Host")){
-        _hostHeader = headerValue;
-      }
-    }
-
-    if (!isForm){
-      size_t plainLength;
-      char* plainBuf = readBytesWithTimeout(client, contentLength, plainLength, HTTP_MAX_POST_WAIT);
-      if (plainLength < contentLength) {
-      	free(plainBuf);
-      	return false;
-      }
-      if (contentLength > 0) {
-        if (searchStr != "") searchStr += '&';
-        if(isEncoded){
-          //url encoded form
-          String decoded = urlDecode(plainBuf);
-          size_t decodedLen = decoded.length();
-          memcpy(plainBuf, decoded.c_str(), decodedLen);
-          plainBuf[decodedLen] = 0;
-          searchStr += plainBuf;
-        }
-        _parseArguments(searchStr);
-        if(!isEncoded){
-          //plain post json or other data
-          RequestArgument& arg = _currentArgs[_currentArgCount++];
-          arg.key = "plain";
-          arg.value = String(plainBuf);
-        }
-
-  #ifdef DEBUG_ESP_HTTP_SERVER
-        DEBUG_OUTPUT.print("Plain: ");
-        DEBUG_OUTPUT.println(plainBuf);
-  #endif
-        free(plainBuf);
-      }
-    }
-
-    if (isForm){
-      _parseArguments(searchStr);
-      if (!_parseForm(client, boundaryStr, contentLength)) {
-        return false;
-      }
-    }
-  } else {
-    String headerName;
-    String headerValue;
-    //parse headers
-    while(1){
-      req = client.readStringUntil('\r');
-      client.readStringUntil('\n');
-      if (req == "") break;//no moar headers
-      int headerDiv = req.indexOf(':');
-      if (headerDiv == -1){
-        break;
-      }
-      headerName = req.substring(0, headerDiv);
-      headerValue = req.substring(headerDiv + 2);
-      _collectHeader(headerName.c_str(),headerValue.c_str());
-
-	  #ifdef DEBUG_ESP_HTTP_SERVER
-	  DEBUG_OUTPUT.print("headerName: ");
-	  DEBUG_OUTPUT.println(headerName);
-	  DEBUG_OUTPUT.print("headerValue: ");
-	  DEBUG_OUTPUT.println(headerValue);
-	  #endif
-
-	  if (headerName.equalsIgnoreCase("Host")){
-        _hostHeader = headerValue;
-      }
-    }
-    _parseArguments(searchStr);
-  }
-  client.flush();
-
-#ifdef DEBUG_ESP_HTTP_SERVER
-  DEBUG_OUTPUT.print("Request: ");
-  DEBUG_OUTPUT.println(url);
-  DEBUG_OUTPUT.print(" Arguments: ");
-  DEBUG_OUTPUT.println(searchStr);
-#endif
-
-  return true;
-}
-
-bool ESP32WebServer::_collectHeader(const char* headerName, const char* headerValue) {
-  for (int i = 0; i < _headerKeysCount; i++) {
-    if (_currentHeaders[i].key.equalsIgnoreCase(headerName)) {
-            _currentHeaders[i].value=headerValue;
-            return true;
-        }
-  }
-  return false;
-}
-
-void ESP32WebServer::_parseArguments(String data) {
-#ifdef DEBUG_ESP_HTTP_SERVER
-  DEBUG_OUTPUT.print("args: ");
-  DEBUG_OUTPUT.println(data);
-#endif
-  if (_currentArgs)
-    delete[] _currentArgs;
-  _currentArgs = 0;
-  if (data.length() == 0) {
-    _currentArgCount = 0;
-    _currentArgs = new RequestArgument[1];
-    return;
-  }
-  _currentArgCount = 1;
-
-  for (int i = 0; i < (int)data.length(); ) {
-    i = data.indexOf('&', i);
-    if (i == -1)
-      break;
-    ++i;
-    ++_currentArgCount;
-  }
-#ifdef DEBUG_ESP_HTTP_SERVER
-  DEBUG_OUTPUT.print("args count: ");
-  DEBUG_OUTPUT.println(_currentArgCount);
-#endif
-
-  _currentArgs = new RequestArgument[_currentArgCount+1];
-  int pos = 0;
-  int iarg;
-  for (iarg = 0; iarg < _currentArgCount;) {
-    int equal_sign_index = data.indexOf('=', pos);
-    int next_arg_index = data.indexOf('&', pos);
-#ifdef DEBUG_ESP_HTTP_SERVER
-    DEBUG_OUTPUT.print("pos ");
-    DEBUG_OUTPUT.print(pos);
-    DEBUG_OUTPUT.print("=@ ");
-    DEBUG_OUTPUT.print(equal_sign_index);
-    DEBUG_OUTPUT.print(" &@ ");
-    DEBUG_OUTPUT.println(next_arg_index);
-#endif
-    if ((equal_sign_index == -1) || ((equal_sign_index > next_arg_index) && (next_arg_index != -1))) {
-#ifdef DEBUG_ESP_HTTP_SERVER
-      DEBUG_OUTPUT.print("arg missing value: ");
-      DEBUG_OUTPUT.println(iarg);
-#endif
-      if (next_arg_index == -1)
-        break;
-      pos = next_arg_index + 1;
-      continue;
-    }
-    RequestArgument& arg = _currentArgs[iarg];
-    arg.key = data.substring(pos, equal_sign_index);
-	arg.value = data.substring(equal_sign_index + 1, next_arg_index);
-#ifdef DEBUG_ESP_HTTP_SERVER
-    DEBUG_OUTPUT.print("arg ");
-    DEBUG_OUTPUT.print(iarg);
-    DEBUG_OUTPUT.print(" key: ");
-    DEBUG_OUTPUT.print(arg.key);
-    DEBUG_OUTPUT.print(" value: ");
-    DEBUG_OUTPUT.println(arg.value);
-#endif
-    ++iarg;
-    if (next_arg_index == -1)
-      break;
-    pos = next_arg_index + 1;
-  }
-  _currentArgCount = iarg;
-#ifdef DEBUG_ESP_HTTP_SERVER
-  DEBUG_OUTPUT.print("args count: ");
-  DEBUG_OUTPUT.println(_currentArgCount);
-#endif
-
-}
-
-void ESP32WebServer::_uploadWriteByte(uint8_t b){
-  if (_currentUpload.currentSize == HTTP_UPLOAD_BUFLEN){
-    if(_currentHandler && _currentHandler->canUpload(_currentUri))
-      _currentHandler->upload(*this, _currentUri, _currentUpload);
-    _currentUpload.totalSize += _currentUpload.currentSize;
-    _currentUpload.currentSize = 0;
-  }
-  _currentUpload.buf[_currentUpload.currentSize++] = b;
-}
-
-uint8_t ESP32WebServer::_uploadReadByte(WiFiClient& client){
-  int res = client.read();
-  if(res == -1){
-    while(!client.available() && client.connected())
-      yield();
-    res = client.read();
-  }
-  return (uint8_t)res;
-}
-
-bool ESP32WebServer::_parseForm(WiFiClient& client, String boundary, uint32_t len){
-  (void) len;
-#ifdef DEBUG_ESP_HTTP_SERVER
-  DEBUG_OUTPUT.print("Parse Form: Boundary: ");
-  DEBUG_OUTPUT.print(boundary);
-  DEBUG_OUTPUT.print(" Length: ");
-  DEBUG_OUTPUT.println(len);
-#endif
-  String line;
-  int retry = 0;
-  do {
-    line = client.readStringUntil('\r');
-    ++retry;
-  } while (line.length() == 0 && retry < 3);
-
-  client.readStringUntil('\n');
-  //start reading the form
-  if (line == ("--"+boundary)){
-    RequestArgument* postArgs = new RequestArgument[32];
-    int postArgsLen = 0;
-    while(1){
-      String argName;
-      String argValue;
-      String argType;
-      String argFilename;
-      bool argIsFile = false;
-
-      line = client.readStringUntil('\r');
-      client.readStringUntil('\n');
-      if (line.length() > 19 && line.substring(0, 19).equalsIgnoreCase("Content-Disposition")){
-        int nameStart = line.indexOf('=');
-        if (nameStart != -1){
-          argName = line.substring(nameStart+2);
-          nameStart = argName.indexOf('=');
-          if (nameStart == -1){
-            argName = argName.substring(0, argName.length() - 1);
-          } else {
-            argFilename = argName.substring(nameStart+2, argName.length() - 1);
-            argName = argName.substring(0, argName.indexOf('"'));
-            argIsFile = true;
-#ifdef DEBUG_ESP_HTTP_SERVER
-            DEBUG_OUTPUT.print("PostArg FileName: ");
-            DEBUG_OUTPUT.println(argFilename);
-#endif
-            //use GET to set the filename if uploading using blob
-            if (argFilename == "blob" && hasArg("filename")) argFilename = arg("filename");
-          }
-#ifdef DEBUG_ESP_HTTP_SERVER
-          DEBUG_OUTPUT.print("PostArg Name: ");
-          DEBUG_OUTPUT.println(argName);
-#endif
-          argType = "text/plain";
-          line = client.readStringUntil('\r');
-          client.readStringUntil('\n');
-          if (line.length() > 12 && line.substring(0, 12).equalsIgnoreCase("Content-Type")){
-            argType = line.substring(line.indexOf(':')+2);
-            //skip next line
-            client.readStringUntil('\r');
-            client.readStringUntil('\n');
-          }
-#ifdef DEBUG_ESP_HTTP_SERVER
-          DEBUG_OUTPUT.print("PostArg Type: ");
-          DEBUG_OUTPUT.println(argType);
-#endif
-          if (!argIsFile){
-            while(1){
-              line = client.readStringUntil('\r');
-              client.readStringUntil('\n');
-              if (line.startsWith("--"+boundary)) break;
-              if (argValue.length() > 0) argValue += "\n";
-              argValue += line;
-            }
-#ifdef DEBUG_ESP_HTTP_SERVER
-            DEBUG_OUTPUT.print("PostArg Value: ");
-            DEBUG_OUTPUT.println(argValue);
-            DEBUG_OUTPUT.println();
-#endif
-
-            RequestArgument& arg = postArgs[postArgsLen++];
-            arg.key = argName;
-            arg.value = argValue;
-
-            if (line == ("--"+boundary+"--")){
-#ifdef DEBUG_ESP_HTTP_SERVER
-              DEBUG_OUTPUT.println("Done Parsing POST");
-#endif
-              break;
-            }
-          } else {
-            _currentUpload.status = UPLOAD_FILE_START;
-            _currentUpload.name = argName;
-            _currentUpload.filename = argFilename;
-            _currentUpload.type = argType;
-            _currentUpload.totalSize = 0;
-            _currentUpload.currentSize = 0;
-#ifdef DEBUG_ESP_HTTP_SERVER
-            DEBUG_OUTPUT.print("Start File: ");
-            DEBUG_OUTPUT.print(_currentUpload.filename);
-            DEBUG_OUTPUT.print(" Type: ");
-            DEBUG_OUTPUT.println(_currentUpload.type);
-#endif
-            if(_currentHandler && _currentHandler->canUpload(_currentUri))
-              _currentHandler->upload(*this, _currentUri, _currentUpload);
-            _currentUpload.status = UPLOAD_FILE_WRITE;
-            uint8_t argByte = _uploadReadByte(client);
-readfile:
-            while(argByte != 0x0D){
-              if (!client.connected()) return _parseFormUploadAborted();
-              _uploadWriteByte(argByte);
-              argByte = _uploadReadByte(client);
-            }
-
-            argByte = _uploadReadByte(client);
-            if (!client.connected()) return _parseFormUploadAborted();
-            if (argByte == 0x0A){
-              argByte = _uploadReadByte(client);
-              if (!client.connected()) return _parseFormUploadAborted();
-              if ((char)argByte != '-'){
-                //continue reading the file
-                _uploadWriteByte(0x0D);
-                _uploadWriteByte(0x0A);
-                goto readfile;
-              } else {
-                argByte = _uploadReadByte(client);
-                if (!client.connected()) return _parseFormUploadAborted();
-                if ((char)argByte != '-'){
-                  //continue reading the file
-                  _uploadWriteByte(0x0D);
-                  _uploadWriteByte(0x0A);
-                  _uploadWriteByte((uint8_t)('-'));
-                  goto readfile;
-                }
-              }
-
-              uint8_t endBuf[boundary.length()];
-              client.readBytes(endBuf, boundary.length());
-
-              if (strstr((const char*)endBuf, boundary.c_str()) != NULL){
-                if(_currentHandler && _currentHandler->canUpload(_currentUri))
-                  _currentHandler->upload(*this, _currentUri, _currentUpload);
-                _currentUpload.totalSize += _currentUpload.currentSize;
-                _currentUpload.status = UPLOAD_FILE_END;
-                if(_currentHandler && _currentHandler->canUpload(_currentUri))
-                  _currentHandler->upload(*this, _currentUri, _currentUpload);
-#ifdef DEBUG_ESP_HTTP_SERVER
-                DEBUG_OUTPUT.print("End File: ");
-                DEBUG_OUTPUT.print(_currentUpload.filename);
-                DEBUG_OUTPUT.print(" Type: ");
-                DEBUG_OUTPUT.print(_currentUpload.type);
-                DEBUG_OUTPUT.print(" Size: ");
-                DEBUG_OUTPUT.println(_currentUpload.totalSize);
-#endif
-                line = client.readStringUntil(0x0D);
-                client.readStringUntil(0x0A);
-                if (line == "--"){
-#ifdef DEBUG_ESP_HTTP_SERVER
-                  DEBUG_OUTPUT.println("Done Parsing POST");
-#endif
-                  break;
-                }
-                continue;
-              } else {
-                _uploadWriteByte(0x0D);
-                _uploadWriteByte(0x0A);
-                _uploadWriteByte((uint8_t)('-'));
-                _uploadWriteByte((uint8_t)('-'));
-                uint32_t i = 0;
-                while(i < boundary.length()){
-                  _uploadWriteByte(endBuf[i++]);
-                }
-                argByte = _uploadReadByte(client);
-                goto readfile;
-              }
-            } else {
-              _uploadWriteByte(0x0D);
-              goto readfile;
-            }
-            break;
-          }
-        }
-      }
-    }
-
-    int iarg;
-    int totalArgs = ((32 - postArgsLen) < _currentArgCount)?(32 - postArgsLen):_currentArgCount;
-    for (iarg = 0; iarg < totalArgs; iarg++){
-      RequestArgument& arg = postArgs[postArgsLen++];
-      arg.key = _currentArgs[iarg].key;
-      arg.value = _currentArgs[iarg].value;
-    }
-    if (_currentArgs) delete[] _currentArgs;
-    _currentArgs = new RequestArgument[postArgsLen];
-    for (iarg = 0; iarg < postArgsLen; iarg++){
-      RequestArgument& arg = _currentArgs[iarg];
-      arg.key = postArgs[iarg].key;
-      arg.value = postArgs[iarg].value;
-    }
-    _currentArgCount = iarg;
-    if (postArgs) delete[] postArgs;
-    return true;
-  }
-#ifdef DEBUG_ESP_HTTP_SERVER
-  DEBUG_OUTPUT.print("Error: line: ");
-  DEBUG_OUTPUT.println(line);
-#endif
-  return false;
-}
-
-String ESP32WebServer::urlDecode(const String& text)
-{
-	String decoded = "";
-	char temp[] = "0x00";
-	unsigned int len = text.length();
-	unsigned int i = 0;
-	while (i < len)
-	{
-		char decodedChar;
-		char encodedChar = text.charAt(i++);
-		if ((encodedChar == '%') && (i + 1 < len))
-		{
-			temp[2] = text.charAt(i++);
-			temp[3] = text.charAt(i++);
-
-			decodedChar = strtol(temp, NULL, 16);
-		}
-		else {
-			if (encodedChar == '+')
-			{
-				decodedChar = ' ';
-			}
-			else {
-				decodedChar = encodedChar;  // normal ascii char
-			}
-		}
-		decoded += decodedChar;
-	}
-	return decoded;
-}
-
-bool ESP32WebServer::_parseFormUploadAborted(){
-  _currentUpload.status = UPLOAD_FILE_ABORTED;
-  if(_currentHandler && _currentHandler->canUpload(_currentUri))
-    _currentHandler->upload(*this, _currentUri, _currentUpload);
-  return false;
-}

+ 0 - 19
lib/ESP32WebServer/src/detail/RequestHandler.h

@@ -1,19 +0,0 @@
-#ifndef REQUESTHANDLER_H
-#define REQUESTHANDLER_H
-
-class RequestHandler {
-public:
-    virtual ~RequestHandler() { }
-    virtual bool canHandle(HTTPMethod method, String uri) { (void) method; (void) uri; return false; }
-    virtual bool canUpload(String uri) { (void) uri; return false; }
-    virtual bool handle(ESP32WebServer& server, HTTPMethod requestMethod, String requestUri) { (void) server; (void) requestMethod; (void) requestUri; return false; }
-    virtual void upload(ESP32WebServer& server, String requestUri, HTTPUpload& upload) { (void) server; (void) requestUri; (void) upload; }
-
-    RequestHandler* next() { return _next; }
-    void next(RequestHandler* r) { _next = r; }
-
-private:
-    RequestHandler* _next = nullptr;
-};
-
-#endif //REQUESTHANDLER_H

+ 0 - 153
lib/ESP32WebServer/src/detail/RequestHandlersImpl.h

@@ -1,153 +0,0 @@
-#ifndef REQUESTHANDLERSIMPL_H
-#define REQUESTHANDLERSIMPL_H
-
-#include "RequestHandler.h"
-
-class FunctionRequestHandler : public RequestHandler {
-public:
-    FunctionRequestHandler(ESP32WebServer::THandlerFunction fn, ESP32WebServer::THandlerFunction ufn, const String &uri, HTTPMethod method)
-    : _fn(fn)
-    , _ufn(ufn)
-    , _uri(uri)
-    , _method(method)
-    {
-    }
-
-    bool canHandle(HTTPMethod requestMethod, String requestUri) override  {
-        if (_method != HTTP_ANY && _method != requestMethod)
-            return false;
-
-        if (requestUri != _uri)
-            return false;
-
-        return true;
-    }
-
-    bool canUpload(String requestUri) override  {
-        if (!_ufn || !canHandle(HTTP_POST, requestUri))
-            return false;
-
-        return true;
-    }
-
-    bool handle(ESP32WebServer& server, HTTPMethod requestMethod, String requestUri) override {
-        (void) server;
-        if (!canHandle(requestMethod, requestUri))
-            return false;
-
-        _fn();
-        return true;
-    }
-
-    void upload(ESP32WebServer& server, String requestUri, HTTPUpload& upload) override {
-        (void) server;
-        (void) upload;
-        if (canUpload(requestUri))
-            _ufn();
-    }
-
-protected:
-    ESP32WebServer::THandlerFunction _fn;
-    ESP32WebServer::THandlerFunction _ufn;
-    String _uri;
-    HTTPMethod _method;
-};
-
-class StaticRequestHandler : public RequestHandler {
-public:
-    StaticRequestHandler(FS& fs, const char* path, const char* uri, const char* cache_header)
-    : _fs(fs)
-    , _uri(uri)
-    , _path(path)
-    , _cache_header(cache_header)
-    {
-        _isFile = fs.exists(path);
-        log_e("StaticRequestHandler: path=%s uri=%s isFile=%d, cache_header=%s\r\n", path, uri, _isFile, cache_header);
-        _baseUriLength = _uri.length();
-    }
-
-    bool canHandle(HTTPMethod requestMethod, String requestUri) override  {
-        if (requestMethod != HTTP_GET)
-            return false;
-
-        if ((_isFile && requestUri != _uri) || !requestUri.startsWith(_uri))
-            return false;
-
-        return true;
-    }
-
-    bool handle(ESP32WebServer& server, HTTPMethod requestMethod, String requestUri) override {
-        if (!canHandle(requestMethod, requestUri))
-            return false;
-
-        log_e("StaticRequestHandler::handle: request=%s _uri=%s\r\n", requestUri.c_str(), _uri.c_str());
-
-        String path(_path);
-
-        if (!_isFile) {
-            // Base URI doesn't point to a file.
-            // If a directory is requested, look for index file.
-            if (requestUri.endsWith("/")) requestUri += "index.htm";
-
-            // Append whatever follows this URI in request to get the file path.
-            path += requestUri.substring(_baseUriLength);
-        }
-        log_e("StaticRequestHandler::handle: path=%s, isFile=%d\r\n", path.c_str(), _isFile);
-
-        String contentType = getContentType(path);
-
-        // look for gz file, only if the original specified path is not a gz.  So part only works to send gzip via content encoding when a non compressed is asked for
-        // if you point the the path to gzip you will serve the gzip as content type "application/x-gzip", not text or javascript etc...
-        if (!path.endsWith(".gz") && !_fs.exists(path))  {
-            String pathWithGz = path + ".gz";
-            if(_fs.exists(pathWithGz))
-                path += ".gz";
-        }
-
-        File f = _fs.open(path, "r");
-        if (!f)
-            return false;
-
-        if (_cache_header.length() != 0)
-            server.sendHeader("Cache-Control", _cache_header);
-
-        server.streamFile(f, contentType);
-        return true;
-    }
-
-    static String getContentType(const String& path) {
-        if (path.endsWith(".html")) return "text/html";
-        else if (path.endsWith(".htm")) return "text/html";
-        else if (path.endsWith(".css")) return "text/css";
-        else if (path.endsWith(".txt")) return "text/plain";
-        else if (path.endsWith(".js")) return "application/javascript";
-        else if (path.endsWith(".png")) return "image/png";
-        else if (path.endsWith(".gif")) return "image/gif";
-        else if (path.endsWith(".jpg")) return "image/jpeg";
-        else if (path.endsWith(".ico")) return "image/x-icon";
-        else if (path.endsWith(".svg")) return "image/svg+xml";
-        else if (path.endsWith(".ttf")) return "application/x-font-ttf";
-        else if (path.endsWith(".otf")) return "application/x-font-opentype";
-        else if (path.endsWith(".woff")) return "application/font-woff";
-        else if (path.endsWith(".woff2")) return "application/font-woff2";
-        else if (path.endsWith(".eot")) return "application/vnd.ms-fontobject";
-        else if (path.endsWith(".sfnt")) return "application/font-sfnt";
-        else if (path.endsWith(".xml")) return "text/xml";
-        else if (path.endsWith(".pdf")) return "application/pdf";
-        else if (path.endsWith(".zip")) return "application/zip";
-        else if(path.endsWith(".gz")) return "application/x-gzip";
-        else if (path.endsWith(".appcache")) return "text/cache-manifest";
-        return "application/octet-stream";
-    }
-
-protected:
-    FS _fs;
-    String _uri;
-    String _path;
-    String _cache_header;
-    bool _isFile;
-    size_t _baseUriLength;
-};
-
-
-#endif //REQUESTHANDLERSIMPL_H

+ 0 - 70
lib/WiFiEsp/CHANGES.txt

@@ -1,70 +0,0 @@
-2.2.2 (2017-11-03)
-  * Make SSID a const char * in begin() #116
-  * Replace NULL with 0 to avoid compilation warnings
-  * Changing _ESPLOGLEVEL_ requires editing debug.h #88
-
-2.2.1 (2017-01-02)
-  * Fixing Issue #69 (Can't declare member function to have static linkage) 
-  * Supporting ESP8266 firmware 2.X
-
-2.1.2 (2016-05-08)
-  * Added retry in EspDrv::wifiDriverInit method
-  * Clean buffer in ScanNetwork (bug #43)
-
-2.1.1 (2016-05-09)
-  * Implemented gatwayIP() and subnetMask() methods
-
-2.1 (2016-03-13)
-  * SSL connection support
-  * Implementation of config and configAP methods
-  * Fixed read methods WiFiEspClient.read(buf, size) and WiFiEspUDP::read(buf, size)
-  * Fixed possible buffer overflow in EspDrv.sendCmdGet
-  * Added beginAP methods similar to WiFi101 library - parameters order for beginAP is now different!
-
-1.6 (2016-02-21)
-  * Improved UDP support
-  * Added WiFiEspClient.remoteIP() method
-  * Consistent use use of uint16_t to manage port numbers
-  * Added AT+CIPDINFO=1 during init to return remote IP and port with IPD
-  * Added AT+CWAUTOCONN=0 during init to disable autoconnect
-
-1.5.1 (2016-02-11)
-  * Fix in EspDrv.getScanNetworks method 
-  * Fix buffer overflow in getFwVersion
-
-1.5 (2016-01-25)
-  * Implemented scanNetworks method
-  * Increased ring buffer size to 32 to read long SSID names
-
-1.4.2 (2016-01-05)
-  * Fixed compilation problem when using WiFiEspClient.print
-
-1.4.1 (2016-01-05)
-  * Speed optimizations
-
-1.4 (2016-01-04)
-  * Reduced dynamic memory footprint
-
-1.3 (2016-01-03)
-  * UDP support (experimental)
-  * Fixed WiFiEspClient.connected and WiFi.status and methods
-  * Connection close detection
-  * Ring buffer optimization
-  * Client peek method fixed
-
-1.2 (2015-12-29)
-  * Redesigned WiFi.init method to accept a Stream object
-  * Use CUR when starting the AP
-  * Small improvements to samples
-
-1.1 (2015-12-20)
-  * Fix for receiving large data packets
-  * Access point mode support
-  * Ring buffer class is now used in EspDrv.cpp
-  * Removed not implemented methods
-  * Prints firmware version if not recognized
-  * Multiple exclamation marks fixed for Arduino Mega
-  * Cleaned up comments
-
-1.0 (2015-12-11)
-  * First stable release

+ 0 - 675
lib/WiFiEsp/LICENSE

@@ -1,675 +0,0 @@
-GNU GENERAL PUBLIC LICENSE
-                       Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-                            Preamble
-
-  The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
-  The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works.  By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users.  We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors.  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
-  To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights.  Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received.  You must make sure that they, too, receive
-or can get the source code.  And you must show them these terms so they
-know their rights.
-
-  Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
-  For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software.  For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
-  Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so.  This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software.  The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable.  Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products.  If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
-  Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary.  To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-                       TERMS AND CONDITIONS
-
-  0. Definitions.
-
-  "This License" refers to version 3 of the GNU General Public License.
-
-  "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
-  "The Program" refers to any copyrightable work licensed under this
-License.  Each licensee is addressed as "you".  "Licensees" and
-"recipients" may be individuals or organizations.
-
-  To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy.  The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
-  A "covered work" means either the unmodified Program or a work based
-on the Program.
-
-  To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy.  Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
-  To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies.  Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
-  An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License.  If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
-  1. Source Code.
-
-  The "source code" for a work means the preferred form of the work
-for making modifications to it.  "Object code" means any non-source
-form of a work.
-
-  A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
-  The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form.  A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
-  The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities.  However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work.  For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
-  The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
-  The Corresponding Source for a work in source code form is that
-same work.
-
-  2. Basic Permissions.
-
-  All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met.  This License explicitly affirms your unlimited
-permission to run the unmodified Program.  The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work.  This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
-  You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force.  You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright.  Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
-  Conveying under any other circumstances is permitted solely under
-the conditions stated below.  Sublicensing is not allowed; section 10
-makes it unnecessary.
-
-  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
-  No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
-  When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
-  4. Conveying Verbatim Copies.
-
-  You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
-  You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
-  5. Conveying Modified Source Versions.
-
-  You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
-    a) The work must carry prominent notices stating that you modified
-    it, and giving a relevant date.
-
-    b) The work must carry prominent notices stating that it is
-    released under this License and any conditions added under section
-    7.  This requirement modifies the requirement in section 4 to
-    "keep intact all notices".
-
-    c) You must license the entire work, as a whole, under this
-    License to anyone who comes into possession of a copy.  This
-    License will therefore apply, along with any applicable section 7
-    additional terms, to the whole of the work, and all its parts,
-    regardless of how they are packaged.  This License gives no
-    permission to license the work in any other way, but it does not
-    invalidate such permission if you have separately received it.
-
-    d) If the work has interactive user interfaces, each must display
-    Appropriate Legal Notices; however, if the Program has interactive
-    interfaces that do not display Appropriate Legal Notices, your
-    work need not make them do so.
-
-  A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit.  Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
-  6. Conveying Non-Source Forms.
-
-  You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
-    a) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by the
-    Corresponding Source fixed on a durable physical medium
-    customarily used for software interchange.
-
-    b) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by a
-    written offer, valid for at least three years and valid for as
-    long as you offer spare parts or customer support for that product
-    model, to give anyone who possesses the object code either (1) a
-    copy of the Corresponding Source for all the software in the
-    product that is covered by this License, on a durable physical
-    medium customarily used for software interchange, for a price no
-    more than your reasonable cost of physically performing this
-    conveying of source, or (2) access to copy the
-    Corresponding Source from a network server at no charge.
-
-    c) Convey individual copies of the object code with a copy of the
-    written offer to provide the Corresponding Source.  This
-    alternative is allowed only occasionally and noncommercially, and
-    only if you received the object code with such an offer, in accord
-    with subsection 6b.
-
-    d) Convey the object code by offering access from a designated
-    place (gratis or for a charge), and offer equivalent access to the
-    Corresponding Source in the same way through the same place at no
-    further charge.  You need not require recipients to copy the
-    Corresponding Source along with the object code.  If the place to
-    copy the object code is a network server, the Corresponding Source
-    may be on a different server (operated by you or a third party)
-    that supports equivalent copying facilities, provided you maintain
-    clear directions next to the object code saying where to find the
-    Corresponding Source.  Regardless of what server hosts the
-    Corresponding Source, you remain obligated to ensure that it is
-    available for as long as needed to satisfy these requirements.
-
-    e) Convey the object code using peer-to-peer transmission, provided
-    you inform other peers where the object code and Corresponding
-    Source of the work are being offered to the general public at no
-    charge under subsection 6d.
-
-  A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
-  A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling.  In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage.  For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product.  A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
-  "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source.  The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
-  If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information.  But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
-  The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed.  Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
-  Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
-  7. Additional Terms.
-
-  "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law.  If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
-  When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it.  (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.)  You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
-  Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
-    a) Disclaiming warranty or limiting liability differently from the
-    terms of sections 15 and 16 of this License; or
-
-    b) Requiring preservation of specified reasonable legal notices or
-    author attributions in that material or in the Appropriate Legal
-    Notices displayed by works containing it; or
-
-    c) Prohibiting misrepresentation of the origin of that material, or
-    requiring that modified versions of such material be marked in
-    reasonable ways as different from the original version; or
-
-    d) Limiting the use for publicity purposes of names of licensors or
-    authors of the material; or
-
-    e) Declining to grant rights under trademark law for use of some
-    trade names, trademarks, or service marks; or
-
-    f) Requiring indemnification of licensors and authors of that
-    material by anyone who conveys the material (or modified versions of
-    it) with contractual assumptions of liability to the recipient, for
-    any liability that these contractual assumptions directly impose on
-    those licensors and authors.
-
-  All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10.  If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term.  If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
-  If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
-  Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
-  8. Termination.
-
-  You may not propagate or modify a covered work except as expressly
-provided under this License.  Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
-  However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
-  Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
-  Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License.  If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
-  9. Acceptance Not Required for Having Copies.
-
-  You are not required to accept this License in order to receive or
-run a copy of the Program.  Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance.  However,
-nothing other than this License grants you permission to propagate or
-modify any covered work.  These actions infringe copyright if you do
-not accept this License.  Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
-  10. Automatic Licensing of Downstream Recipients.
-
-  Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License.  You are not responsible
-for enforcing compliance by third parties with this License.
-
-  An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations.  If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
-  You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License.  For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
-  11. Patents.
-
-  A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based.  The
-work thus licensed is called the contributor's "contributor version".
-
-  A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version.  For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
-  Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
-  In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement).  To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
-  If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients.  "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
-  If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
-  A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License.  You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
-  Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
-  12. No Surrender of Others' Freedom.
-
-  If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all.  For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
-  13. Use with the GNU Affero General Public License.
-
-  Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work.  The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
-  14. Revised Versions of this License.
-
-  The Free Software Foundation may publish revised and/or new versions of
-the GNU General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-  Each version is given a distinguishing version number.  If the
-Program specifies that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation.  If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
-  If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
-  Later license versions may give you additional or different
-permissions.  However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
-  15. Disclaimer of Warranty.
-
-  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. Limitation of Liability.
-
-  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
-  17. Interpretation of Sections 15 and 16.
-
-  If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
-                     END OF TERMS AND CONDITIONS
-
-            How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    {one line to give the program's name and a brief idea of what it does.}
-    Copyright (C) {year}  {name of author}
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-Also add information on how to contact you by electronic and paper mail.
-
-  If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
-    {project}  Copyright (C) {year}  {fullname}
-    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, your program's commands
-might be different; for a GUI interface, you would use an "about box".
-
-  You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU GPL, see
-<http://www.gnu.org/licenses/>.
-
-  The GNU General Public License does not permit incorporating your program
-into proprietary programs.  If your program is a subroutine library, you
-may consider it more useful to permit linking proprietary applications with
-the library.  If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.  But first, please read
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
-

+ 0 - 102
lib/WiFiEsp/README.md

@@ -1,102 +0,0 @@
-# WiFiEsp
-
-With an ESP8266 board, WiFiEsp library allows an Arduino board to connect to the internet.
-It can serve as either a server accepting incoming connections or a client making outgoing ones.
-The WiFiEsp library is very similar to the Arduino [WiFi](http://www.arduino.cc/en/Reference/WiFi) and [Ethernet](http://www.arduino.cc/en/Reference/Ethernet) libraries, and many of the function calls are the same. 
-
-Supports ESP SDK version 1.1.1 and above (AT version 0.25 and above).
-
-
-## Features
-
-- APIs compatible with standard Arduino WiFi library.
-- Use AT commands of standard ESP firmware (no need to flash a custom firmware).
-- Support hardware and software serial ports.
-- Configurable tracing level.
-
-## Wiring
-
-The WiFiEsp library has been designed to work with the [ESP WiFi shield](http://www.instructables.com/id/Cheap-Arduino-WiFi-Shield-With-ESP8266/).
-It is a cheap version of the Arduino WiFi shield that uses an ESP-01 module to provide networking capabilities to Arduino boards.
-
-
-## Examples
-
-- [ConnectWPA](https://github.com/bportaluri/WiFiEsp/blob/master/examples/ConnectWPA/ConnectWPA.ino) - Demonstrates how to connect to a network that is encrypted with WPA2 Personal
-- [WebClient](https://github.com/bportaluri/WiFiEsp/blob/master/examples/WebClient/WebClient.ino) - Connect to a remote webserver 
-- [WebClientRepeating](https://github.com/bportaluri/WiFiEsp/blob/master/examples/WebClientRepeating/WebClientRepeating.ino) - Make repeated HTTP calls to a webserver 
-- [WebServer](https://github.com/bportaluri/WiFiEsp/blob/master/examples/WebServer/WebServer.ino) - Serve a webpage from the WiFi shield 
-- [WebServerAP](https://github.com/bportaluri/WiFiEsp/blob/master/examples/WebServerAP/WebServerAP.ino) - Serve a webpage from the WiFi shield starting a local Access Point
-- [WebServerLed](https://github.com/bportaluri/WiFiEsp/blob/master/examples/WebServerLed/WebServerLed.ino) - Turn on and off a led from a webpage
-- [UdpNTPClient](https://github.com/bportaluri/WiFiEsp/blob/master/examples/UdpNTPClient/UdpNTPClient.ino) - Query a Network Time Protocol (NTP) server using UDP
-
-
-## Supported APIs
-
-Most of the standard Arduino WiFi library methods are available. Refer to the [WiFi library page](http://www.arduino.cc/en/Reference/WiFi) for more details.
-
-### WiFiEsp class
-
-- begin() - Not all authentication types
-- disconnect() - YES
-- config()
-- setDNS() - NO (no AT command available)
-- SSID() - YES
-- BSSID() - YES
-- RSSI() - YES
-- encryptionType() - NO (no AT command available)
-- scanNetworks() - YES
-- getSocket()
-- macAddress() - YES
-
-
-### WiFiEspServer class
-
-The WiFiEspServer class creates servers which can send data to and receive data from connected clients (programs running on other computers or devices).
-
-- WiFiEspServer() - YES
-- begin() - YES
-- available() - YES
-- write() - YES
-- print() - YES
-- println() - YES
-
-
-### Client class
-
-The WiFiEspClient class creates clients that can connect to servers and send and receive data.
-
-- WiFiEspClient() - YES
-- connected() - YES
-- connect() - YES
-- write() - YES
-- print() - YES
-- println() - YES
-- available() - YES
-- read() - YES
-- flush() - YES
-- stop() - YES
-
-
-### WiFiEspUDP class
-
-The UDP class enables UDP message to be sent and received.
-
-- WiFiUDP - YES
-- begin() - YES
-- available() - YES
-- beginPacket() - YES
-- endPacket() - YES
-- write() - YES
-- parsePacket() - YES
-- peek()
-- read() - YES
-- flush()
-- stop()
-- remoteIP() - YES
-- remotePort() - YES
-
-
-## Contributing
-
-If you discover a bug or would like to propose a new feature, please open a new [issue](https://github.com/bportaluri/WiFiEsp/issues).

+ 0 - 94
lib/WiFiEsp/examples/ConnectWPA/ConnectWPA.ino

@@ -1,94 +0,0 @@
-/*
- WiFiEsp example: ConnectWPA
- 
- This example connects to an encrypted WiFi network using an ESP8266 module.
- Then it prints the  MAC address of the WiFi shield, the IP address obtained
- and other network details.
-
- For more details see: http://yaab-arduino.blogspot.com/p/wifiesp-example-connect.html
-*/
-
-#include "WiFiEsp.h"
-
-// Emulate Serial1 on pins 6/7 if not present
-#ifndef HAVE_HWSERIAL1
-#include "SoftwareSerial.h"
-SoftwareSerial Serial1(6, 7); // RX, TX
-#endif
-
-char ssid[] = "Twim";            // your network SSID (name)
-char pass[] = "12345678";        // your network password
-int status = WL_IDLE_STATUS;     // the Wifi radio's status
-
-void setup()
-{
-  // initialize serial for debugging
-  Serial.begin(115200);
-  // initialize serial for ESP module
-  Serial1.begin(9600);
-  // initialize ESP module
-  WiFi.init(&Serial1);
-
-  // check for the presence of the shield
-  if (WiFi.status() == WL_NO_SHIELD) {
-    Serial.println("WiFi shield not present");
-    // don't continue
-    while (true);
-  }
-
-  // attempt to connect to WiFi network
-  while ( status != WL_CONNECTED) {
-    Serial.print("Attempting to connect to WPA SSID: ");
-    Serial.println(ssid);
-    // Connect to WPA/WPA2 network
-    status = WiFi.begin(ssid, pass);
-  }
-
-  Serial.println("You're connected to the network");
-}
-
-void loop()
-{
-  // print the network connection information every 10 seconds
-  Serial.println();
-  printCurrentNet();
-  printWifiData();
-  
-  delay(10000);
-}
-
-void printWifiData()
-{
-  // print your WiFi shield's IP address
-  IPAddress ip = WiFi.localIP();
-  Serial.print("IP Address: ");
-  Serial.println(ip);
-
-  // print your MAC address
-  byte mac[6];
-  WiFi.macAddress(mac);
-  char buf[20];
-  sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", mac[5], mac[4], mac[3], mac[2], mac[1], mac[0]);
-  Serial.print("MAC address: ");
-  Serial.println(buf);
-}
-
-void printCurrentNet()
-{
-  // print the SSID of the network you're attached to
-  Serial.print("SSID: ");
-  Serial.println(WiFi.SSID());
-
-  // print the MAC address of the router you're attached to
-  byte bssid[6];
-  WiFi.BSSID(bssid);
-  char buf[20];
-  sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", bssid[5], bssid[4], bssid[3], bssid[2], bssid[1], bssid[0]);
-  Serial.print("BSSID: ");
-  Serial.println(buf);
-
-  // print the received signal strength
-  long rssi = WiFi.RSSI();
-  Serial.print("Signal strength (RSSI): ");
-  Serial.println(rssi);
-}

+ 0 - 109
lib/WiFiEsp/examples/ScanNetworks/ScanNetworks.ino

@@ -1,109 +0,0 @@
-/*
- WiFiEsp example: ScanNetworks
-
- This example  prints the Wifi shield's MAC address, and
- scans for available Wifi networks using the Wifi shield.
- Every ten seconds, it scans again. It doesn't actually
- connect to any network, so no encryption scheme is specified.
-
- For more details see: http://yaab-arduino.blogspot.com/p/wifiesp.html
-*/
-
-#include "WiFiEsp.h"
-
-// Emulate Serial1 on pins 6/7 if not present
-#ifndef HAVE_HWSERIAL1
-#include "SoftwareSerial.h"
-SoftwareSerial Serial1(6, 7); // RX, TX
-#endif
-
-void setup() {
-  // initialize serial for debugging
-  Serial.begin(115200);
-  // initialize serial for ESP module
-  Serial1.begin(9600);
-  // initialize ESP module
-  WiFi.init(&Serial1);
-
-  // check for the presence of the shield
-  if (WiFi.status() == WL_NO_SHIELD) {
-    Serial.println("WiFi shield not present");
-    // don't continue
-    while (true);
-  }
-
-  // Print WiFi MAC address
-  printMacAddress();
-}
-
-void loop()
-{
-  // scan for existing networks
-  Serial.println();
-  Serial.println("Scanning available networks...");
-  listNetworks();
-  delay(10000);
-}
-
-
-void printMacAddress()
-{
-  // get your MAC address
-  byte mac[6];
-  WiFi.macAddress(mac);
-  
-  // print MAC address
-  char buf[20];
-  sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", mac[5], mac[4], mac[3], mac[2], mac[1], mac[0]);
-  Serial.print("MAC address: ");
-  Serial.println(buf);
-}
-
-void listNetworks()
-{
-  // scan for nearby networks
-  int numSsid = WiFi.scanNetworks();
-  if (numSsid == -1) {
-    Serial.println("Couldn't get a wifi connection");
-    while (true);
-  }
-
-  // print the list of networks seen
-  Serial.print("Number of available networks:");
-  Serial.println(numSsid);
-
-  // print the network number and name for each network found
-  for (int thisNet = 0; thisNet < numSsid; thisNet++) {
-    Serial.print(thisNet);
-    Serial.print(") ");
-    Serial.print(WiFi.SSID(thisNet));
-    Serial.print("\tSignal: ");
-    Serial.print(WiFi.RSSI(thisNet));
-    Serial.print(" dBm");
-    Serial.print("\tEncryption: ");
-    printEncryptionType(WiFi.encryptionType(thisNet));
-  }
-}
-
-void printEncryptionType(int thisType) {
-  // read the encryption type and print out the name
-  switch (thisType) {
-    case ENC_TYPE_WEP:
-      Serial.print("WEP");
-      break;
-    case ENC_TYPE_WPA_PSK:
-      Serial.print("WPA_PSK");
-      break;
-    case ENC_TYPE_WPA2_PSK:
-      Serial.print("WPA2_PSK");
-      break;
-    case ENC_TYPE_WPA_WPA2_PSK:
-      Serial.print("WPA_WPA2_PSK");
-      break;
-    case ENC_TYPE_NONE:
-      Serial.print("None");
-      break;
-  }
-  Serial.println();
-}
-

+ 0 - 154
lib/WiFiEsp/examples/UdpNTPClient/UdpNTPClient.ino

@@ -1,154 +0,0 @@
-/*
- WiFiEsp example: UdpNTPClient
-
- Get the time from a Network Time Protocol (NTP) time server.
- Demonstrates use of UDP to send and receive data packets
- For more on NTP time servers and the messages needed to communicate with them,
- see http://en.wikipedia.org/wiki/Network_Time_Protocol
-
- NOTE: The serial buffer size must be larger than 36 + packet size
- In this example we use an UDP packet of 48 bytes so the buffer must be
- at least 36+48=84 bytes that exceeds the default buffer size (64).
- You must modify the serial buffer size to 128
- For HardwareSerial modify _SS_MAX_RX_BUFF in
-   Arduino\hardware\arduino\avr\cores\arduino\SoftwareSerial.h
- For SoftwareSerial modify _SS_MAX_RX_BUFF in
-   Arduino\hardware\arduino\avr\libraries\SoftwareSerial\SoftwareSerial.h
-*/
-
-#include "WiFiEsp.h"
-#include "WiFiEspUdp.h"
-
-// Emulate Serial1 on pins 6/7 if not present
-#ifndef HAVE_HWSERIAL1
-#include "SoftwareSerial.h"
-SoftwareSerial Serial1(6, 7); // RX, TX
-#endif
-
-char ssid[] = "Twim";            // your network SSID (name)
-char pass[] = "12345678";        // your network password
-int status = WL_IDLE_STATUS;     // the Wifi radio's status
-
-char timeServer[] = "time.nist.gov";  // NTP server
-unsigned int localPort = 2390;        // local port to listen for UDP packets
-
-const int NTP_PACKET_SIZE = 48;  // NTP timestamp is in the first 48 bytes of the message
-const int UDP_TIMEOUT = 2000;    // timeout in miliseconds to wait for an UDP packet to arrive
-
-byte packetBuffer[NTP_PACKET_SIZE]; // buffer to hold incoming and outgoing packets
-
-// A UDP instance to let us send and receive packets over UDP
-WiFiEspUDP Udp;
-
-void setup()
-{
-  // initialize serial for debugging
-  Serial.begin(115200);
-  // initialize serial for ESP module
-  Serial1.begin(9600);
-  // initialize ESP module
-  WiFi.init(&Serial1);
-
-  // check for the presence of the shield
-  if (WiFi.status() == WL_NO_SHIELD) {
-    Serial.println("WiFi shield not present");
-    // don't continue
-    while (true);
-  }
-
-  // attempt to connect to WiFi network
-  while ( status != WL_CONNECTED) {
-    Serial.print("Attempting to connect to WPA SSID: ");
-    Serial.println(ssid);
-    // Connect to WPA/WPA2 network
-    status = WiFi.begin(ssid, pass);
-  }
-
-  // you're connected now, so print out the data
-  Serial.println("You're connected to the network");
-  
-  Udp.begin(localPort);
-}
-
-void loop()
-{
-  sendNTPpacket(timeServer); // send an NTP packet to a time server
-  
-  // wait for a reply for UDP_TIMEOUT miliseconds
-  unsigned long startMs = millis();
-  while (!Udp.available() && (millis() - startMs) < UDP_TIMEOUT) {}
-
-  Serial.println(Udp.parsePacket());
-  if (Udp.parsePacket()) {
-    Serial.println("packet received");
-    // We've received a packet, read the data from it into the buffer
-    Udp.read(packetBuffer, NTP_PACKET_SIZE);
-
-    // the timestamp starts at byte 40 of the received packet and is four bytes,
-    // or two words, long. First, esxtract the two words:
-
-    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
-    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
-    // combine the four bytes (two words) into a long integer
-    // this is NTP time (seconds since Jan 1 1900):
-    unsigned long secsSince1900 = highWord << 16 | lowWord;
-    Serial.print("Seconds since Jan 1 1900 = ");
-    Serial.println(secsSince1900);
-
-    // now convert NTP time into everyday time:
-    Serial.print("Unix time = ");
-    // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
-    const unsigned long seventyYears = 2208988800UL;
-    // subtract seventy years:
-    unsigned long epoch = secsSince1900 - seventyYears;
-    // print Unix time:
-    Serial.println(epoch);
-
-
-    // print the hour, minute and second:
-    Serial.print("The UTC time is ");       // UTC is the time at Greenwich Meridian (GMT)
-    Serial.print((epoch  % 86400L) / 3600); // print the hour (86400 equals secs per day)
-    Serial.print(':');
-    if (((epoch % 3600) / 60) < 10) {
-      // In the first 10 minutes of each hour, we'll want a leading '0'
-      Serial.print('0');
-    }
-    Serial.print((epoch  % 3600) / 60); // print the minute (3600 equals secs per minute)
-    Serial.print(':');
-    if ((epoch % 60) < 10) {
-      // In the first 10 seconds of each minute, we'll want a leading '0'
-      Serial.print('0');
-    }
-    Serial.println(epoch % 60); // print the second
-  }
-  // wait ten seconds before asking for the time again
-  delay(10000);
-}
-
-// send an NTP request to the time server at the given address
-void sendNTPpacket(char *ntpSrv)
-{
-  // set all bytes in the buffer to 0
-  memset(packetBuffer, 0, NTP_PACKET_SIZE);
-  // Initialize values needed to form NTP request
-  // (see URL above for details on the packets)
-
-  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
-  packetBuffer[1] = 0;     // Stratum, or type of clock
-  packetBuffer[2] = 6;     // Polling Interval
-  packetBuffer[3] = 0xEC;  // Peer Clock Precision
-  // 8 bytes of zero for Root Delay & Root Dispersion
-  packetBuffer[12]  = 49;
-  packetBuffer[13]  = 0x4E;
-  packetBuffer[14]  = 49;
-  packetBuffer[15]  = 52;
-
-  // all NTP fields have been given values, now
-  // you can send a packet requesting a timestamp:
-  Udp.beginPacket(ntpSrv, 123); //NTP requests are to port 123
-
-  Udp.write(packetBuffer, NTP_PACKET_SIZE);
-
-  Udp.endPacket();
-}
-

+ 0 - 109
lib/WiFiEsp/examples/UdpSendReceive/UdpSendReceive.ino

@@ -1,109 +0,0 @@
-/*
- WiFiEsp example: WiFi UDP Send and Receive String
-
- This sketch wait an UDP packet on localPort using a WiFi shield.
- When a packet is received an 'ACK' packet is sent to the client on port remotePort.
-
- For more details see: http://yaab-arduino.blogspot.com/p/wifiesp-example-client.html
-*/
-
-
-#include <WiFiEsp.h>
-#include <WiFiEspUdp.h>
-
-// Emulate Serial1 on pins 6/7 if not present
-#ifndef HAVE_HWSERIAL1
-#include "SoftwareSerial.h"
-SoftwareSerial Serial1(6, 7); // RX, TX
-#endif
-
-char ssid[] = "Twim";            // your network SSID (name)
-char pass[] = "12345678";        // your network password
-int status = WL_IDLE_STATUS;     // the Wifi radio's status
-
-unsigned int localPort = 10002;  // local port to listen on
-
-char packetBuffer[255];          // buffer to hold incoming packet
-char ReplyBuffer[] = "ACK";      // a string to send back
-
-WiFiEspUDP Udp;
-
-void setup() {
-  // initialize serial for debugging
-  Serial.begin(115200);
-  // initialize serial for ESP module
-  Serial1.begin(9600);
-  // initialize ESP module
-  WiFi.init(&Serial1);
-
-  // check for the presence of the shield:
-  if (WiFi.status() == WL_NO_SHIELD) {
-    Serial.println("WiFi shield not present");
-    // don't continue:
-    while (true);
-  }
-
-  // attempt to connect to WiFi network
-  while ( status != WL_CONNECTED) {
-    Serial.print("Attempting to connect to WPA SSID: ");
-    Serial.println(ssid);
-    // Connect to WPA/WPA2 network
-    status = WiFi.begin(ssid, pass);
-  }
-  
-  Serial.println("Connected to wifi");
-  printWifiStatus();
-
-  Serial.println("\nStarting connection to server...");
-  // if you get a connection, report back via serial:
-  Udp.begin(localPort);
-  
-  Serial.print("Listening on port ");
-  Serial.println(localPort);
-}
-
-void loop() {
-
-  // if there's data available, read a packet
-  int packetSize = Udp.parsePacket();
-  if (packetSize) {
-    Serial.print("Received packet of size ");
-    Serial.println(packetSize);
-    Serial.print("From ");
-    IPAddress remoteIp = Udp.remoteIP();
-    Serial.print(remoteIp);
-    Serial.print(", port ");
-    Serial.println(Udp.remotePort());
-
-    // read the packet into packetBufffer
-    int len = Udp.read(packetBuffer, 255);
-    if (len > 0) {
-      packetBuffer[len] = 0;
-    }
-    Serial.println("Contents:");
-    Serial.println(packetBuffer);
-
-    // send a reply, to the IP address and port that sent us the packet we received
-    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
-    Udp.write(ReplyBuffer);
-    Udp.endPacket();
-  }
-}
-
-
-void printWifiStatus() {
-  // print the SSID of the network you're attached to:
-  Serial.print("SSID: ");
-  Serial.println(WiFi.SSID());
-
-  // print your WiFi shield's IP address:
-  IPAddress ip = WiFi.localIP();
-  Serial.print("IP Address: ");
-  Serial.println(ip);
-
-  // print the received signal strength:
-  long rssi = WiFi.RSSI();
-  Serial.print("signal strength (RSSI):");
-  Serial.print(rssi);
-  Serial.println(" dBm");
-}

+ 0 - 106
lib/WiFiEsp/examples/WebClient/WebClient.ino

@@ -1,106 +0,0 @@
-/*
- WiFiEsp example: WebClient
-
- This sketch connects to google website using an ESP8266 module to
- perform a simple web search.
-
- For more details see: http://yaab-arduino.blogspot.com/p/wifiesp-example-client.html
-*/
-
-#include "WiFiEsp.h"
-
-// Emulate Serial1 on pins 6/7 if not present
-#ifndef HAVE_HWSERIAL1
-#include "SoftwareSerial.h"
-SoftwareSerial Serial1(6, 7); // RX, TX
-#endif
-
-char ssid[] = "Twim";            // your network SSID (name)
-char pass[] = "12345678";        // your network password
-int status = WL_IDLE_STATUS;     // the Wifi radio's status
-
-char server[] = "arduino.cc";
-
-// Initialize the Ethernet client object
-WiFiEspClient client;
-
-void setup()
-{
-  // initialize serial for debugging
-  Serial.begin(115200);
-  // initialize serial for ESP module
-  Serial1.begin(9600);
-  // initialize ESP module
-  WiFi.init(&Serial1);
-
-  // check for the presence of the shield
-  if (WiFi.status() == WL_NO_SHIELD) {
-    Serial.println("WiFi shield not present");
-    // don't continue
-    while (true);
-  }
-
-  // attempt to connect to WiFi network
-  while ( status != WL_CONNECTED) {
-    Serial.print("Attempting to connect to WPA SSID: ");
-    Serial.println(ssid);
-    // Connect to WPA/WPA2 network
-    status = WiFi.begin(ssid, pass);
-  }
-
-  // you're connected now, so print out the data
-  Serial.println("You're connected to the network");
-  
-  printWifiStatus();
-
-  Serial.println();
-  Serial.println("Starting connection to server...");
-  // if you get a connection, report back via serial
-  if (client.connect(server, 80)) {
-    Serial.println("Connected to server");
-    // Make a HTTP request
-    client.println("GET /asciilogo.txt HTTP/1.1");
-    client.println("Host: arduino.cc");
-    client.println("Connection: close");
-    client.println();
-  }
-}
-
-void loop()
-{
-  // if there are incoming bytes available
-  // from the server, read them and print them
-  while (client.available()) {
-    char c = client.read();
-    Serial.write(c);
-  }
-
-  // if the server's disconnected, stop the client
-  if (!client.connected()) {
-    Serial.println();
-    Serial.println("Disconnecting from server...");
-    client.stop();
-
-    // do nothing forevermore
-    while (true);
-  }
-}
-
-
-void printWifiStatus()
-{
-  // print the SSID of the network you're attached to
-  Serial.print("SSID: ");
-  Serial.println(WiFi.SSID());
-
-  // print your WiFi shield's IP address
-  IPAddress ip = WiFi.localIP();
-  Serial.print("IP Address: ");
-  Serial.println(ip);
-
-  // print the received signal strength
-  long rssi = WiFi.RSSI();
-  Serial.print("Signal strength (RSSI):");
-  Serial.print(rssi);
-  Serial.println(" dBm");
-}

+ 0 - 121
lib/WiFiEsp/examples/WebClientRepeating/WebClientRepeating.ino

@@ -1,121 +0,0 @@
-/*
- WiFiEsp example: WebClientRepeating
-
- This sketch connects to a web server and makes an HTTP request
- using an Arduino ESP8266 module.
- It repeats the HTTP call each 10 seconds.
-
- For more details see: http://yaab-arduino.blogspot.com/p/wifiesp.html
-*/
-
-#include "WiFiEsp.h"
-
-// Emulate Serial1 on pins 6/7 if not present
-#ifndef HAVE_HWSERIAL1
-#include "SoftwareSerial.h"
-SoftwareSerial Serial1(6, 7); // RX, TX
-#endif
-
-char ssid[] = "Twim";            // your network SSID (name)
-char pass[] = "12345678";        // your network password
-int status = WL_IDLE_STATUS;     // the Wifi radio's status
-
-char server[] = "arduino.cc";
-
-unsigned long lastConnectionTime = 0;         // last time you connected to the server, in milliseconds
-const unsigned long postingInterval = 10000L; // delay between updates, in milliseconds
-
-// Initialize the Ethernet client object
-WiFiEspClient client;
-
-void setup()
-{
-  // initialize serial for debugging
-  Serial.begin(115200);
-  // initialize serial for ESP module
-  Serial1.begin(9600);
-  // initialize ESP module
-  WiFi.init(&Serial1);
-
-  // check for the presence of the shield
-  if (WiFi.status() == WL_NO_SHIELD) {
-    Serial.println("WiFi shield not present");
-    // don't continue
-    while (true);
-  }
-
-  // attempt to connect to WiFi network
-  while ( status != WL_CONNECTED) {
-    Serial.print("Attempting to connect to WPA SSID: ");
-    Serial.println(ssid);
-    // Connect to WPA/WPA2 network
-    status = WiFi.begin(ssid, pass);
-  }
-
-  Serial.println("You're connected to the network");
-  
-  printWifiStatus();
-}
-
-void loop()
-{
-  // if there's incoming data from the net connection send it out the serial port
-  // this is for debugging purposes only
-  while (client.available()) {
-    char c = client.read();
-    Serial.write(c);
-  }
-
-  // if 10 seconds have passed since your last connection,
-  // then connect again and send data
-  if (millis() - lastConnectionTime > postingInterval) {
-    httpRequest();
-  }
-}
-
-// this method makes a HTTP connection to the server
-void httpRequest()
-{
-  Serial.println();
-    
-  // close any connection before send a new request
-  // this will free the socket on the WiFi shield
-  client.stop();
-
-  // if there's a successful connection
-  if (client.connect(server, 80)) {
-    Serial.println("Connecting...");
-    
-    // send the HTTP PUT request
-    client.println(F("GET /asciilogo.txt HTTP/1.1"));
-    client.println(F("Host: arduino.cc"));
-    client.println("Connection: close");
-    client.println();
-
-    // note the time that the connection was made
-    lastConnectionTime = millis();
-  }
-  else {
-    // if you couldn't make a connection
-    Serial.println("Connection failed");
-  }
-}
-
-
-void printWifiStatus()
-{
-  // print the SSID of the network you're attached to
-  Serial.print("SSID: ");
-  Serial.println(WiFi.SSID());
-
-  // print your WiFi shield's IP address
-  IPAddress ip = WiFi.localIP();
-  Serial.print("IP Address: ");
-  Serial.println(ip);
-
-  // print the received signal strength
-  long rssi = WiFi.RSSI();
-  Serial.print("Signal strength (RSSI):");
-  Serial.print(rssi);
-  Serial.println(" dBm");
-}

+ 0 - 106
lib/WiFiEsp/examples/WebClientSSL/WebClientSSL.ino

@@ -1,106 +0,0 @@
-/*
- WiFiEsp example: WebClient
-
- This sketch connects to google website using an ESP8266 module to
- perform a simple web search.
-
- For more details see: http://yaab-arduino.blogspot.com/p/wifiesp-example-client.html
-*/
-
-#include "WiFiEsp.h"
-
-// Emulate Serial1 on pins 6/7 if not present
-#ifndef HAVE_HWSERIAL1
-#include "SoftwareSerial.h"
-SoftwareSerial Serial1(6, 7); // RX, TX
-#endif
-
-char ssid[] = "Twim";            // your network SSID (name)
-char pass[] = "12345678";        // your network password
-int status = WL_IDLE_STATUS;     // the Wifi radio's status
-
-char server[] = "www.google.com";
-
-// Initialize the Ethernet client object
-WiFiEspClient client;
-
-void setup()
-{
-  // initialize serial for debugging
-  Serial.begin(115200);
-  // initialize serial for ESP module
-  Serial1.begin(9600);
-  // initialize ESP module
-  WiFi.init(&Serial1);
-
-  // check for the presence of the shield
-  if (WiFi.status() == WL_NO_SHIELD) {
-    Serial.println("WiFi shield not present");
-    // don't continue
-    while (true);
-  }
-
-  // attempt to connect to WiFi network
-  while ( status != WL_CONNECTED) {
-    Serial.print("Attempting to connect to WPA SSID: ");
-    Serial.println(ssid);
-    // Connect to WPA/WPA2 network
-    status = WiFi.begin(ssid, pass);
-  }
-
-  // you're connected now, so print out the data
-  Serial.println("You're connected to the network");
-  
-  printWifiStatus();
-
-  Serial.println();
-  Serial.println("Starting connection to server...");
-  // if you get a connection, report back via serial
-  if (client.connectSSL(server, 443)) {
-    Serial.println("Connected to server");
-    // Make a HTTP request
-    client.println("GET / HTTP/1.1");
-    client.println("Host: www.google.com");
-    client.println("Connection: close");
-    client.println();
-  }
-}
-
-void loop()
-{
-  // if there are incoming bytes available
-  // from the server, read them and print them
-  while (client.available()) {
-    char c = client.read();
-    Serial.write(c);
-  }
-
-  // if the server's disconnected, stop the client
-  if (!client.connected()) {
-    Serial.println();
-    Serial.println("Disconnecting from server...");
-    client.stop();
-
-    // do nothing forevermore
-    while (true);
-  }
-}
-
-
-void printWifiStatus()
-{
-  // print the SSID of the network you're attached to
-  Serial.print("SSID: ");
-  Serial.println(WiFi.SSID());
-
-  // print your WiFi shield's IP address
-  IPAddress ip = WiFi.localIP();
-  Serial.print("IP Address: ");
-  Serial.println(ip);
-
-  // print the received signal strength
-  long rssi = WiFi.RSSI();
-  Serial.print("Signal strength (RSSI):");
-  Serial.print(rssi);
-  Serial.println(" dBm");
-}

+ 0 - 136
lib/WiFiEsp/examples/WebServer/WebServer.ino

@@ -1,136 +0,0 @@
-/*
- WiFiEsp example: WebServer
-
- A simple web server that shows the value of the analog input 
- pins via a web page using an ESP8266 module.
- This sketch will print the IP address of your ESP8266 module (once connected)
- to the Serial monitor. From there, you can open that address in a web browser
- to display the web page.
- The web page will be automatically refreshed each 20 seconds.
-
- For more details see: http://yaab-arduino.blogspot.com/p/wifiesp.html
-*/
-
-#include "WiFiEsp.h"
-
-// Emulate Serial1 on pins 6/7 if not present
-#ifndef HAVE_HWSERIAL1
-#include "SoftwareSerial.h"
-SoftwareSerial Serial1(6, 7); // RX, TX
-#endif
-
-char ssid[] = "Twim";            // your network SSID (name)
-char pass[] = "12345678";        // your network password
-int status = WL_IDLE_STATUS;     // the Wifi radio's status
-int reqCount = 0;                // number of requests received
-
-WiFiEspServer server(80);
-
-
-void setup()
-{
-  // initialize serial for debugging
-  Serial.begin(115200);
-  // initialize serial for ESP module
-  Serial1.begin(9600);
-  // initialize ESP module
-  WiFi.init(&Serial1);
-
-  // check for the presence of the shield
-  if (WiFi.status() == WL_NO_SHIELD) {
-    Serial.println("WiFi shield not present");
-    // don't continue
-    while (true);
-  }
-
-  // attempt to connect to WiFi network
-  while ( status != WL_CONNECTED) {
-    Serial.print("Attempting to connect to WPA SSID: ");
-    Serial.println(ssid);
-    // Connect to WPA/WPA2 network
-    status = WiFi.begin(ssid, pass);
-  }
-
-  Serial.println("You're connected to the network");
-  printWifiStatus();
-  
-  // start the web server on port 80
-  server.begin();
-}
-
-
-void loop()
-{
-  // listen for incoming clients
-  WiFiEspClient client = server.available();
-  if (client) {
-    Serial.println("New client");
-    // an http request ends with a blank line
-    boolean currentLineIsBlank = true;
-    while (client.connected()) {
-      if (client.available()) {
-        char c = client.read();
-        Serial.write(c);
-        // if you've gotten to the end of the line (received a newline
-        // character) and the line is blank, the http request has ended,
-        // so you can send a reply
-        if (c == '\n' && currentLineIsBlank) {
-          Serial.println("Sending response");
-          
-          // send a standard http response header
-          // use \r\n instead of many println statements to speedup data send
-          client.print(
-            "HTTP/1.1 200 OK\r\n"
-            "Content-Type: text/html\r\n"
-            "Connection: close\r\n"  // the connection will be closed after completion of the response
-            "Refresh: 20\r\n"        // refresh the page automatically every 20 sec
-            "\r\n");
-          client.print("<!DOCTYPE HTML>\r\n");
-          client.print("<html>\r\n");
-          client.print("<h1>Hello World!</h1>\r\n");
-          client.print("Requests received: ");
-          client.print(++reqCount);
-          client.print("<br>\r\n");
-          client.print("Analog input A0: ");
-          client.print(analogRead(0));
-          client.print("<br>\r\n");
-          client.print("</html>\r\n");
-          break;
-        }
-        if (c == '\n') {
-          // you're starting a new line
-          currentLineIsBlank = true;
-        }
-        else if (c != '\r') {
-          // you've gotten a character on the current line
-          currentLineIsBlank = false;
-        }
-      }
-    }
-    // give the web browser time to receive the data
-    delay(10);
-
-    // close the connection:
-    client.stop();
-    Serial.println("Client disconnected");
-  }
-}
-
-
-void printWifiStatus()
-{
-  // print the SSID of the network you're attached to
-  Serial.print("SSID: ");
-  Serial.println(WiFi.SSID());
-
-  // print your WiFi shield's IP address
-  IPAddress ip = WiFi.localIP();
-  Serial.print("IP Address: ");
-  Serial.println(ip);
-  
-  // print where to go in the browser
-  Serial.println();
-  Serial.print("To see this page in action, open a browser to http://");
-  Serial.println(ip);
-  Serial.println();
-}

+ 0 - 128
lib/WiFiEsp/examples/WebServerAP/WebServerAP.ino

@@ -1,128 +0,0 @@
-/*
- WiFiEsp example: WebServerAP
-
- A simple web server that shows the value of the analog input 
- pins via a web page using an ESP8266 module.
- This sketch will start an access point and print the IP address of your
- ESP8266 module to the Serial monitor. From there, you can open
- that address in a web browser to display the web page.
- The web page will be automatically refreshed each 20 seconds.
-
- For more details see: http://yaab-arduino.blogspot.com/p/wifiesp.html
-*/
-
-#include "WiFiEsp.h"
-
-// Emulate Serial1 on pins 6/7 if not present
-#ifndef HAVE_HWSERIAL1
-#include "SoftwareSerial.h"
-SoftwareSerial Serial1(6, 7); // RX, TX
-#endif
-
-char ssid[] = "TwimEsp";         // your network SSID (name)
-char pass[] = "12345678";        // your network password
-int status = WL_IDLE_STATUS;     // the Wifi radio's status
-int reqCount = 0;                // number of requests received
-
-WiFiEspServer server(80);
-
-// use a ring buffer to increase speed and reduce memory allocation
-RingBuffer buf(8);
-
-void setup()
-{
-  Serial.begin(115200);   // initialize serial for debugging
-  Serial1.begin(9600);    // initialize serial for ESP module
-  WiFi.init(&Serial1);    // initialize ESP module
-
-  // check for the presence of the shield
-  if (WiFi.status() == WL_NO_SHIELD) {
-    Serial.println("WiFi shield not present");
-    while (true); // don't continue
-  }
-
-  Serial.print("Attempting to start AP ");
-  Serial.println(ssid);
-
-  // uncomment these two lines if you want to set the IP address of the AP
-  //IPAddress localIp(192, 168, 111, 111);
-  //WiFi.configAP(localIp);
-  
-  // start access point
-  status = WiFi.beginAP(ssid, 10, pass, ENC_TYPE_WPA2_PSK);
-
-  Serial.println("Access point started");
-  printWifiStatus();
-  
-  // start the web server on port 80
-  server.begin();
-  Serial.println("Server started");
-}
-
-
-void loop()
-{
-  WiFiEspClient client = server.available();  // listen for incoming clients
-
-  if (client) {                               // if you get a client,
-    Serial.println("New client");             // print a message out the serial port
-    buf.init();                               // initialize the circular buffer
-    while (client.connected()) {              // loop while the client's connected
-      if (client.available()) {               // if there's bytes to read from the client,
-        char c = client.read();               // read a byte, then
-        buf.push(c);                          // push it to the ring buffer
-
-        // you got two newline characters in a row
-        // that's the end of the HTTP request, so send a response
-        if (buf.endsWith("\r\n\r\n")) {
-          sendHttpResponse(client);
-          break;
-        }
-      }
-    }
-    
-    // give the web browser time to receive the data
-    delay(10);
-
-    // close the connection
-    client.stop();
-    Serial.println("Client disconnected");
-  }
-}
-
-void sendHttpResponse(WiFiEspClient client)
-{
-  client.print(
-    "HTTP/1.1 200 OK\r\n"
-    "Content-Type: text/html\r\n"
-    "Connection: close\r\n"  // the connection will be closed after completion of the response
-    "Refresh: 20\r\n"        // refresh the page automatically every 20 sec
-    "\r\n");
-  client.print("<!DOCTYPE HTML>\r\n");
-  client.print("<html>\r\n");
-  client.print("<h1>Hello World!</h1>\r\n");
-  client.print("Requests received: ");
-  client.print(++reqCount);
-  client.print("<br>\r\n");
-  client.print("Analog input A0: ");
-  client.print(analogRead(0));
-  client.print("<br>\r\n");
-  client.print("</html>\r\n");
-}
-
-void printWifiStatus()
-{
-  // print your WiFi shield's IP address
-  IPAddress ip = WiFi.localIP();
-  Serial.print("IP Address: ");
-  Serial.println(ip);
-
-  // print where to go in the browser
-  Serial.println();
-  Serial.print("To see this page in action, connect to ");
-  Serial.print(ssid);
-  Serial.print(" and open a browser to http://");
-  Serial.println(ip);
-  Serial.println();
-}
-

+ 0 - 142
lib/WiFiEsp/examples/WebServerLed/WebServerLed.ino

@@ -1,142 +0,0 @@
-/*
- WiFiEsp example: WebServerLed
- 
- A simple web server that lets you turn on and of an LED via a web page.
- This sketch will print the IP address of your ESP8266 module (once connected)
- to the Serial monitor. From there, you can open that address in a web browser
- to turn on and off the LED on pin 13.
-
- For more details see: http://yaab-arduino.blogspot.com/p/wifiesp.html
-*/
-
-#include "WiFiEsp.h"
-
-// Emulate Serial1 on pins 6/7 if not present
-#ifndef HAVE_HWSERIAL1
-#include "SoftwareSerial.h"
-SoftwareSerial Serial1(6, 7); // RX, TX
-#endif
-
-char ssid[] = "Twim";            // your network SSID (name)
-char pass[] = "12345678";        // your network password
-int status = WL_IDLE_STATUS;
-
-int ledStatus = LOW;
-
-WiFiEspServer server(80);
-
-// use a ring buffer to increase speed and reduce memory allocation
-RingBuffer buf(8);
-
-void setup()
-{
-  pinMode(LED_BUILTIN, OUTPUT);	// initialize digital pin LED_BUILTIN as an output.
-  Serial.begin(115200);   // initialize serial for debugging
-  Serial1.begin(9600);    // initialize serial for ESP module
-  WiFi.init(&Serial1);    // initialize ESP module
-
-  // check for the presence of the shield
-  if (WiFi.status() == WL_NO_SHIELD) {
-    Serial.println("WiFi shield not present");
-    // don't continue
-    while (true);
-  }
-
-  // attempt to connect to WiFi network
-  while (status != WL_CONNECTED) {
-    Serial.print("Attempting to connect to WPA SSID: ");
-    Serial.println(ssid);
-    // Connect to WPA/WPA2 network
-    status = WiFi.begin(ssid, pass);
-  }
-
-  Serial.println("You're connected to the network");
-  printWifiStatus();
-  
-  // start the web server on port 80
-  server.begin();
-}
-
-
-void loop()
-{
-  WiFiEspClient client = server.available();  // listen for incoming clients
-
-  if (client) {                               // if you get a client,
-    Serial.println("New client");             // print a message out the serial port
-    buf.init();                               // initialize the circular buffer
-    while (client.connected()) {              // loop while the client's connected
-      if (client.available()) {               // if there's bytes to read from the client,
-        char c = client.read();               // read a byte, then
-        buf.push(c);                          // push it to the ring buffer
-
-        // printing the stream to the serial monitor will slow down
-        // the receiving of data from the ESP filling the serial buffer
-        //Serial.write(c);
-        
-        // you got two newline characters in a row
-        // that's the end of the HTTP request, so send a response
-        if (buf.endsWith("\r\n\r\n")) {
-          sendHttpResponse(client);
-          break;
-        }
-
-        // Check to see if the client request was "GET /H" or "GET /L":
-        if (buf.endsWith("GET /H")) {
-          Serial.println("Turn led ON");
-          ledStatus = HIGH;
-          digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
-        }
-        else if (buf.endsWith("GET /L")) {
-          Serial.println("Turn led OFF");
-          ledStatus = LOW;
-          digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
-        }
-      }
-    }
-    
-    // close the connection
-    client.stop();
-    Serial.println("Client disconnected");
-  }
-}
-
-
-void sendHttpResponse(WiFiEspClient client)
-{
-  // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
-  // and a content-type so the client knows what's coming, then a blank line:
-  client.println("HTTP/1.1 200 OK");
-  client.println("Content-type:text/html");
-  client.println();
-  
-  // the content of the HTTP response follows the header:
-  client.print("The LED is ");
-  client.print(ledStatus);
-  client.println("<br>");
-  client.println("<br>");
-  
-  client.println("Click <a href=\"/H\">here</a> turn the LED on<br>");
-  client.println("Click <a href=\"/L\">here</a> turn the LED off<br>");
-  
-  // The HTTP response ends with another blank line:
-  client.println();
-}
-
-void printWifiStatus()
-{
-  // print the SSID of the network you're attached to
-  Serial.print("SSID: ");
-  Serial.println(WiFi.SSID());
-
-  // print your WiFi shield's IP address
-  IPAddress ip = WiFi.localIP();
-  Serial.print("IP Address: ");
-  Serial.println(ip);
-
-  // print where to go in the browser
-  Serial.println();
-  Serial.print("To see this page in action, open a browser to http://");
-  Serial.println(ip);
-  Serial.println();
-}

+ 0 - 59
lib/WiFiEsp/keywords.txt

@@ -1,59 +0,0 @@
-#######################################
-# Syntax Coloring Map For WiFiEsp
-#######################################
-
-#######################################
-# Library (KEYWORD3)
-#######################################
-
-WiFiEsp	KEYWORD3
-
-
-#######################################
-# Datatypes (KEYWORD1)
-#######################################
-
-WiFiEspClient	KEYWORD1
-WiFiEspServer	KEYWORD1
-WiFiEspUDP	KEYWORD1
-RingBuffer	KEYWORD1
-
-#######################################
-# Methods and Functions (KEYWORD2)
-#######################################
-
-firmwareVersion	KEYWORD2
-status	KEYWORD2
-connect	KEYWORD2
-write	KEYWORD2
-available	KEYWORD2
-config	KEYWORD2
-setDNS	KEYWORD2
-read	KEYWORD2
-flush	KEYWORD2
-stop	KEYWORD2
-connected	KEYWORD2
-begin	KEYWORD2
-disconnect	KEYWORD2
-macAddress	KEYWORD2
-localIP	KEYWORD2
-subnetMask	KEYWORD2
-gatewayIP	KEYWORD2
-scanNetworks	KEYWORD2
-SSID	KEYWORD2
-BSSID		KEYWORD2
-RSSI	KEYWORD2
-encryptionType	KEYWORD2
-getResult	KEYWORD2
-getSocket	KEYWORD2
-beginPacket	KEYWORD2
-endPacket	KEYWORD2
-parsePacket	KEYWORD2
-remoteIP	KEYWORD2
-remotePort	KEYWORD2
-
-
-#######################################
-# Constants (LITERAL1)
-#######################################
-

+ 0 - 9
lib/WiFiEsp/library.properties

@@ -1,9 +0,0 @@
-name=WiFiEsp
-version=2.2.2
-author=bportaluri
-maintainer=Bruno Portaluri <bportaluri@gmail.com>
-sentence=Arduino WiFi library for ESP8266
-paragraph=Arduino WiFi library for ESP8266. Works only with SDK version 1.1.1 and above (AT version 0.25 and above).
-category=Other
-url=https://github.com/bportaluri/WiFiEsp
-architectures=*

+ 0 - 233
lib/WiFiEsp/src/WiFiEsp.cpp

@@ -1,233 +0,0 @@
-/*--------------------------------------------------------------------
-This file is part of the Arduino WiFiEsp library.
-
-The Arduino WiFiEsp library is free software: you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation, either version 3 of the
-License, or (at your option) any later version.
-
-The Arduino WiFiEsp library is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with The Arduino WiFiEsp library.  If not, see
-<http://www.gnu.org/licenses/>.
---------------------------------------------------------------------*/
-
-#include "WiFiEsp.h"
-
-
-int16_t 	WiFiEspClass::_state[MAX_SOCK_NUM] = { NA_STATE, NA_STATE, NA_STATE, NA_STATE };
-uint16_t 	WiFiEspClass::_server_port[MAX_SOCK_NUM] = { 0, 0, 0, 0 };
-
-
-uint8_t WiFiEspClass::espMode = 0;
-
-
-WiFiEspClass::WiFiEspClass()
-{
-
-}
-
-void WiFiEspClass::init(Stream* espSerial)
-{
-    LOGINFO(F("Initializing ESP module"));
-	EspDrv::wifiDriverInit(espSerial);
-}
-
-
-
-char* WiFiEspClass::firmwareVersion()
-{
-	return EspDrv::getFwVersion();
-}
-
-
-int WiFiEspClass::begin(const char* ssid, const char* passphrase)
-{
-    espMode = 1;
-	if (EspDrv::wifiConnect(ssid, passphrase))
-		return WL_CONNECTED;
-
-	return WL_CONNECT_FAILED;
-}
-
-
-int WiFiEspClass::beginAP(const char* ssid, uint8_t channel, const char* pwd, uint8_t enc, bool apOnly)
-{
-	if(apOnly)
-        espMode = 2;
-    else
-        espMode = 3;
-    
-    if (EspDrv::wifiStartAP(ssid, pwd, channel, enc, espMode))
-		return WL_CONNECTED;
-
-	return WL_CONNECT_FAILED;
-}
-
-int WiFiEspClass::beginAP(const char* ssid)
-{
-	return beginAP(ssid, 10, "", 0);
-}
-
-int WiFiEspClass::beginAP(const char* ssid, uint8_t channel)
-{
-	return beginAP(ssid, channel, "", 0);
-}
-
-
-void WiFiEspClass::config(IPAddress ip)
-{
-	EspDrv::config(ip);
-}
-
-void WiFiEspClass::configAP(IPAddress ip)
-{
-	EspDrv::configAP(ip);
-}
-
-
-
-int WiFiEspClass::disconnect()
-{
-    return EspDrv::disconnect();
-}
-
-uint8_t* WiFiEspClass::macAddress(uint8_t* mac)
-{
-	// TODO we don't need _mac variable
-	uint8_t* _mac = EspDrv::getMacAddress();
-	memcpy(mac, _mac, WL_MAC_ADDR_LENGTH);
-    return mac;
-}
-
-IPAddress WiFiEspClass::localIP()
-{
-	IPAddress ret;
-	if(espMode==1)
-		EspDrv::getIpAddress(ret);
-	else
-		EspDrv::getIpAddressAP(ret);
-	return ret;
-}
-
-IPAddress WiFiEspClass::subnetMask()
-{
-	IPAddress mask;
-	if(espMode==1)
-    EspDrv::getNetmask(mask);
-	return mask;
-}
-
-IPAddress WiFiEspClass::gatewayIP()
-{
-	IPAddress gw;
-	if(espMode==1)
-		EspDrv::getGateway(gw);
-	return gw;
-}
-
-
-char* WiFiEspClass::SSID()
-{
-    return EspDrv::getCurrentSSID();
-}
-
-uint8_t* WiFiEspClass::BSSID(uint8_t* bssid)
-{
-	// TODO we don't need _bssid
-	uint8_t* _bssid = EspDrv::getCurrentBSSID();
-	memcpy(bssid, _bssid, WL_MAC_ADDR_LENGTH);
-    return bssid;
-}
-
-int32_t WiFiEspClass::RSSI()
-{
-    return EspDrv::getCurrentRSSI();
-}
-
-
-int8_t WiFiEspClass::scanNetworks()
-{
-	return EspDrv::getScanNetworks();
-}
-
-char* WiFiEspClass::SSID(uint8_t networkItem)
-{
-	return EspDrv::getSSIDNetoworks(networkItem);
-}
-
-int32_t WiFiEspClass::RSSI(uint8_t networkItem)
-{
-	return EspDrv::getRSSINetoworks(networkItem);
-}
-
-uint8_t WiFiEspClass::encryptionType(uint8_t networkItem)
-{
-    return EspDrv::getEncTypeNetowrks(networkItem);
-}
-
-
-uint8_t WiFiEspClass::status()
-{
-	return EspDrv::getConnectionStatus();
-}
-
-
-
-////////////////////////////////////////////////////////////////////////////
-// Non standard methods
-////////////////////////////////////////////////////////////////////////////
-
-void WiFiEspClass::reset(void)
-{
-	EspDrv::reset();
-}
-
-
-/*
-void ESP8266::hardReset(void)
-{
-connected = false;
-strcpy(ip, "");
-digitalWrite(ESP8266_RST, LOW);
-delay(ESP8266_HARD_RESET_DURATION);
-digitalWrite(ESP8266_RST, HIGH);
-delay(ESP8266_HARD_RESET_DURATION);
-}
-*/
-
-
-bool WiFiEspClass::ping(const char *host)
-{
-	return EspDrv::ping(host);
-}
-
-uint8_t WiFiEspClass::getFreeSocket()
-{
-  // ESP Module assigns socket numbers in ascending order, so we will assign them in descending order
-    for (int i = MAX_SOCK_NUM - 1; i >= 0; i--)
-	{
-      if (_state[i] == NA_STATE)
-      {
-          return i;
-      }
-    }
-    return SOCK_NOT_AVAIL;
-}
-
-void WiFiEspClass::allocateSocket(uint8_t sock)
-{
-  _state[sock] = sock;
-}
-
-void WiFiEspClass::releaseSocket(uint8_t sock)
-{
-  _state[sock] = NA_STATE;
-}
-
-
-WiFiEspClass WiFi;

+ 0 - 274
lib/WiFiEsp/src/WiFiEsp.h

@@ -1,274 +0,0 @@
-/*--------------------------------------------------------------------
-This file is part of the Arduino WiFiEsp library.
-
-The Arduino WiFiEsp library is free software: you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation, either version 3 of the
-License, or (at your option) any later version.
-
-The Arduino WiFiEsp library is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with The Arduino WiFiEsp library.  If not, see
-<http://www.gnu.org/licenses/>.
---------------------------------------------------------------------*/
-
-#ifndef WiFiEsp_h
-#define WiFiEsp_h
-
-#include <Arduino.h>
-#include <Stream.h>
-#include <IPAddress.h>
-#include <inttypes.h>
-
-
-#include "WiFiEspClient.h"
-#include "WiFiEspServer.h"
-#include "utility/EspDrv.h"
-#include "utility/RingBuffer.h"
-#include "utility/debug.h"
-
-
-class WiFiEspClass
-{
-
-public:
-
-	static int16_t _state[MAX_SOCK_NUM];
-	static uint16_t _server_port[MAX_SOCK_NUM];
-
-	WiFiEspClass();
-
-
-	/**
-	* Initialize the ESP module.
-	*
-	* param espSerial: the serial interface (HW or SW) used to communicate with the ESP module
-	*/
-	static void init(Stream* espSerial);
-
-
-	/**
-	* Get firmware version
-	*/
-	static char* firmwareVersion();
-
-
-	// NOT IMPLEMENTED
-	//int begin(char* ssid);
-
-	// NOT IMPLEMENTED
-	//int begin(char* ssid, uint8_t key_idx, const char* key);
-
-
-	/**
-	* Start Wifi connection with passphrase
-	* the most secure supported mode will be automatically selected
-	*
-	* param ssid: Pointer to the SSID string.
-	* param passphrase: Passphrase. Valid characters in a passphrase
-	*		  must be between ASCII 32-126 (decimal).
-	*/
-	int begin(const char* ssid, const char* passphrase);
-
-
-	/**
-	* Change Ip configuration settings disabling the DHCP client
-	*
-	* param local_ip:	Static ip configuration
-	*/
-	void config(IPAddress local_ip);
-
-
-	// NOT IMPLEMENTED
-	//void config(IPAddress local_ip, IPAddress dns_server);
-
-	// NOT IMPLEMENTED
-	//void config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway);
-
-	// NOT IMPLEMENTED
-	//void config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet);
-
-	// NOT IMPLEMENTED
-	//void setDNS(IPAddress dns_server1);
-
-	// NOT IMPLEMENTED
-	//void setDNS(IPAddress dns_server1, IPAddress dns_server2);
-
-	/**
-	* Disconnect from the network
-	*
-	* return: one value of wl_status_t enum
-	*/
-	int disconnect(void);
-
-	/**
-	* Get the interface MAC address.
-	*
-	* return: pointer to uint8_t array with length WL_MAC_ADDR_LENGTH
-	*/
-	uint8_t* macAddress(uint8_t* mac);
-
-	/**
-	* Get the interface IP address.
-	*
-	* return: Ip address value
-	*/
-	IPAddress localIP();
-
-
-	/**
-	* Get the interface subnet mask address.
-	*
-	* return: subnet mask address value
-	*/
-	IPAddress subnetMask();
-
-	/**
-	* Get the gateway ip address.
-	*
-	* return: gateway ip address value
-	*/
-   IPAddress gatewayIP();
-
-	/**
-	* Return the current SSID associated with the network
-	*
-	* return: ssid string
-	*/
-	char* SSID();
-
-	/**
-	* Return the current BSSID associated with the network.
-	* It is the MAC address of the Access Point
-	*
-	* return: pointer to uint8_t array with length WL_MAC_ADDR_LENGTH
-	*/
-	uint8_t* BSSID(uint8_t* bssid);
-
-
-	/**
-	* Return the current RSSI /Received Signal Strength in dBm)
-	* associated with the network
-	*
-	* return: signed value
-	*/
-	int32_t RSSI();
-
-
-	/**
-	* Return Connection status.
-	*
-	* return: one of the value defined in wl_status_t
-	*         see https://www.arduino.cc/en/Reference/WiFiStatus
-	*/
-	uint8_t status();
-
-
-    /*
-      * Return the Encryption Type associated with the network
-      *
-      * return: one value of wl_enc_type enum
-      */
-    //uint8_t	encryptionType();
-
-    /*
-     * Start scan WiFi networks available
-     *
-     * return: Number of discovered networks
-     */
-    int8_t scanNetworks();
-
-    /*
-     * Return the SSID discovered during the network scan.
-     *
-     * param networkItem: specify from which network item want to get the information
-	 *
-     * return: ssid string of the specified item on the networks scanned list
-     */
-    char*	SSID(uint8_t networkItem);
-
-    /*
-     * Return the encryption type of the networks discovered during the scanNetworks
-     *
-     * param networkItem: specify from which network item want to get the information
-	 *
-     * return: encryption type (enum wl_enc_type) of the specified item on the networks scanned list
-     */
-    uint8_t	encryptionType(uint8_t networkItem);
-
-    /*
-     * Return the RSSI of the networks discovered during the scanNetworks
-     *
-     * param networkItem: specify from which network item want to get the information
-	 *
-     * return: signed value of RSSI of the specified item on the networks scanned list
-     */
-    int32_t RSSI(uint8_t networkItem);
-
-
-	// NOT IMPLEMENTED
-	//int hostByName(const char* aHostname, IPAddress& aResult);
-
-
-
-	////////////////////////////////////////////////////////////////////////////
-	// Non standard methods
-	////////////////////////////////////////////////////////////////////////////
-
-	/**
-	* Start the ESP access point.
-	*
-	* param ssid: Pointer to the SSID string.
-	* param channel: WiFi channel (1-14)
-	* param pwd: Passphrase. Valid characters in a passphrase
-	*		  must be between ASCII 32-126 (decimal).
-	* param enc: encryption type (enum wl_enc_type)
-	* param apOnly: Set to false if you want to run AP and Station modes simultaneously
-	*/
-	int beginAP(const char* ssid, uint8_t channel, const char* pwd, uint8_t enc, bool apOnly=true);
-
-	/*
-	* Start the ESP access point with open security.
-	*/
-	int beginAP(const char* ssid);
-	int beginAP(const char* ssid, uint8_t channel);
-
-	/**
-	* Change IP address of the AP
-	*
-	* param ip:	Static ip configuration
-	*/
-	void configAP(IPAddress ip);
-
-
-
-	/**
-	* Restart the ESP module.
-	*/
-	void reset();
-
-	/**
-	* Ping a host.
-	*/
-	bool ping(const char *host);
-
-
-	friend class WiFiEspClient;
-	friend class WiFiEspServer;
-	friend class WiFiEspUDP;
-
-private:
-	static uint8_t getFreeSocket();
-	static void allocateSocket(uint8_t sock);
-	static void releaseSocket(uint8_t sock);
-
-	static uint8_t espMode;
-};
-
-extern WiFiEspClass WiFi;
-
-#endif

+ 0 - 290
lib/WiFiEsp/src/WiFiEspClient.cpp

@@ -1,290 +0,0 @@
-/*--------------------------------------------------------------------
-This file is part of the Arduino WiFiEsp library.
-
-The Arduino WiFiEsp library is free software: you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation, either version 3 of the
-License, or (at your option) any later version.
-
-The Arduino WiFiEsp library is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with The Arduino WiFiEsp library.  If not, see
-<http://www.gnu.org/licenses/>.
---------------------------------------------------------------------*/
-
-#include <inttypes.h>
-
-#include "WiFiEsp.h"
-#include "WiFiEspClient.h"
-#include "WiFiEspServer.h"
-
-#include "utility/EspDrv.h"
-#include "utility/debug.h"
-
-
-WiFiEspClient::WiFiEspClient() : _sock(255)
-{
-}
-
-WiFiEspClient::WiFiEspClient(uint8_t sock) : _sock(sock)
-{
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-// Overrided Print methods
-////////////////////////////////////////////////////////////////////////////////
-
-// the standard print method will call write for each character in the buffer
-// this is very slow on ESP
-size_t WiFiEspClient::print(const __FlashStringHelper *ifsh)
-{
-	printFSH(ifsh, false);
-}
-
-// if we do override this, the standard println will call the print
-// method twice
-size_t WiFiEspClient::println(const __FlashStringHelper *ifsh)
-{
-	printFSH(ifsh, true);
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-// Implementation of Client virtual methods
-////////////////////////////////////////////////////////////////////////////////
-
-int WiFiEspClient::connectSSL(const char* host, uint16_t port)
-{
-	return connect(host, port, SSL_MODE);
-}
-
-int WiFiEspClient::connectSSL(IPAddress ip, uint16_t port)
-{
-	char s[16];
-	sprintf_P(s, PSTR("%d.%d.%d.%d"), ip[0], ip[1], ip[2], ip[3]);
-	return connect(s, port, SSL_MODE);
-}
-
-int WiFiEspClient::connect(const char* host, uint16_t port)
-{
-    return connect(host, port, TCP_MODE);
-}
-
-int WiFiEspClient::connect(IPAddress ip, uint16_t port)
-{
-	char s[16];
-	sprintf_P(s, PSTR("%d.%d.%d.%d"), ip[0], ip[1], ip[2], ip[3]);
-
-	return connect(s, port, TCP_MODE);
-}
-
-/* Private method */
-int WiFiEspClient::connect(const char* host, uint16_t port, uint8_t protMode)
-{
-	LOGINFO1(F("Connecting to"), host);
-
-	_sock = WiFiEspClass::getFreeSocket();
-
-    if (_sock != NO_SOCKET_AVAIL)
-    {
-    	if (!EspDrv::startClient(host, port, _sock, protMode))
-			return 0;
-
-    	WiFiEspClass::allocateSocket(_sock);
-    }
-	else
-	{
-    	LOGERROR(F("No socket available"));
-    	return 0;
-    }
-    return 1;
-}
-
-
-
-size_t WiFiEspClient::write(uint8_t b)
-{
-	  return write(&b, 1);
-}
-
-size_t WiFiEspClient::write(const uint8_t *buf, size_t size)
-{
-	if (_sock >= MAX_SOCK_NUM or size==0)
-	{
-		setWriteError();
-		return 0;
-	}
-
-	bool r = EspDrv::sendData(_sock, buf, size);
-	if (!r)
-	{
-		setWriteError();
-		LOGERROR1(F("Failed to write to socket"), _sock);
-		delay(4000);
-		stop();
-		return 0;
-	}
-
-	return size;
-}
-
-
-
-int WiFiEspClient::available()
-{
-	if (_sock != 255)
-	{
-		int bytes = EspDrv::availData(_sock);
-		if (bytes>0)
-		{
-			return bytes;
-		}
-	}
-
-	return 0;
-}
-
-int WiFiEspClient::read()
-{
-	uint8_t b;
-	if (!available())
-		return -1;
-
-	bool connClose = false;
-	EspDrv::getData(_sock, &b, false, &connClose);
-
-	if (connClose)
-	{
-		WiFiEspClass::releaseSocket(_sock);
-		_sock = 255;
-	}
-
-	return b;
-}
-
-int WiFiEspClient::read(uint8_t* buf, size_t size)
-{
-	if (!available())
-		return -1;
-	return EspDrv::getDataBuf(_sock, buf, size);
-}
-
-int WiFiEspClient::peek()
-{
-	uint8_t b;
-	if (!available())
-		return -1;
-
-	bool connClose = false;
-	EspDrv::getData(_sock, &b, true, &connClose);
-
-	if (connClose)
-	{
-		WiFiEspClass::releaseSocket(_sock);
-		_sock = 255;
-	}
-
-	return b;
-}
-
-
-void WiFiEspClient::flush()
-{
-	while (available())
-		read();
-}
-
-
-
-void WiFiEspClient::stop()
-{
-	if (_sock == 255)
-		return;
-
-	LOGINFO1(F("Disconnecting "), _sock);
-
-	EspDrv::stopClient(_sock);
-
-	WiFiEspClass::releaseSocket(_sock);
-	_sock = 255;
-}
-
-
-uint8_t WiFiEspClient::connected()
-{
-	return (status() == ESTABLISHED);
-}
-
-
-WiFiEspClient::operator bool()
-{
-  return _sock != 255;
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-// Additional WiFi standard methods
-////////////////////////////////////////////////////////////////////////////////
-
-
-uint8_t WiFiEspClient::status()
-{
-	if (_sock == 255)
-	{
-		return CLOSED;
-	}
-
-	if (EspDrv::availData(_sock))
-	{
-		return ESTABLISHED;
-	}
-
-	if (EspDrv::getClientState(_sock))
-	{
-		return ESTABLISHED;
-	}
-
-	WiFiEspClass::releaseSocket(_sock);
-	_sock = 255;
-
-	return CLOSED;
-}
-
-IPAddress WiFiEspClient::remoteIP()
-{
-	IPAddress ret;
-	EspDrv::getRemoteIpAddress(ret);
-	return ret;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Private Methods
-////////////////////////////////////////////////////////////////////////////////
-
-size_t WiFiEspClient::printFSH(const __FlashStringHelper *ifsh, bool appendCrLf)
-{
-	size_t size = strlen_P((char*)ifsh);
-	
-	if (_sock >= MAX_SOCK_NUM or size==0)
-	{
-		setWriteError();
-		return 0;
-	}
-
-	bool r = EspDrv::sendData(_sock, ifsh, size, appendCrLf);
-	if (!r)
-	{
-		setWriteError();
-		LOGERROR1(F("Failed to write to socket"), _sock);
-		delay(4000);
-		stop();
-		return 0;
-	}
-
-	return size;
-}

+ 0 - 144
lib/WiFiEsp/src/WiFiEspClient.h

@@ -1,144 +0,0 @@
-/*--------------------------------------------------------------------
-This file is part of the Arduino WiFiEsp library.
-
-The Arduino WiFiEsp library is free software: you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation, either version 3 of the
-License, or (at your option) any later version.
-
-The Arduino WiFiEsp library is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with The Arduino WiFiEsp library.  If not, see
-<http://www.gnu.org/licenses/>.
---------------------------------------------------------------------*/
-
-#ifndef WiFiEspClient_h
-#define WiFiEspClient_h
-
-
-#include "Arduino.h"
-#include "Print.h"
-#include "Client.h"
-#include "IPAddress.h"
-
-
-
-class WiFiEspClient : public Client
-{
-public:
-  WiFiEspClient();
-  WiFiEspClient(uint8_t sock);
-  
-  
-  // override Print.print method
-  
-  size_t print(const __FlashStringHelper *ifsh);
-  size_t println(const __FlashStringHelper *ifsh);
-
-
-  /*
-  * Connect to the specified IP address and port. The return value indicates success or failure.
-  * Returns true if the connection succeeds, false if not.
-  */
-  virtual int connect(IPAddress ip, uint16_t port);
-
-  /*
-  * Connect to the specified host and port. The return value indicates success or failure.
-  * Returns true if the connection succeeds, false if not.
-  */
-  virtual int connect(const char *host, uint16_t port);
-
-  /*
-  * Connect to the specified IP address and port using SSL. The return value indicates success or failure.
-  * Returns true if the connection succeeds, false if not.
-  */
-  int connectSSL(IPAddress ip, uint16_t port);
-  
-  /*
-  * Connect to the specified host and port using SSL. The return value indicates success or failure.
-  * Returns true if the connection succeeds, false if not.
-  */
-  int connectSSL(const char* host, uint16_t port);
-  
-  /*
-  * Write a character to the server the client is connected to.
-  * Returns the number of characters written.
-  */
-  virtual size_t write(uint8_t);
-
-  /*
-  * Write data to the server the client is connected to.
-  * Returns the number of characters written.
-  */
-  virtual size_t write(const uint8_t *buf, size_t size);
-
-
-  virtual int available();
-
-  /*
-  * Read the next byte received from the server the client is connected to (after the last call to read()).
-  * Returns the next byte (or character), or -1 if none is available.
-  */
-  virtual int read();
-
-
-  virtual int read(uint8_t *buf, size_t size);
-
-  /*
-  * Returns the next byte (character) of incoming serial data without removing it from the internal serial buffer.
-  */
-  virtual int peek();
-
-  /*
-  * Discard any bytes that have been written to the client but not yet read.
-  */
-  virtual void flush();
-
-  /*
-  * Disconnect from the server.
-  */
-  virtual void stop();
-
-  /*
-  * Whether or not the client is connected.
-  * Note that a client is considered connected if the connection has been closed but there is still unread data.
-  * Returns true if the client is connected, false if not.
-  */
-  virtual uint8_t connected();
-
-
-  uint8_t status();
-  
-  virtual operator bool();
-
-  
-  // needed to correctly handle overriding
-  // see http://stackoverflow.com/questions/888235/overriding-a-bases-overloaded-function-in-c
-  using Print::write;
-  using Print::print;
-  using Print::println;
-
-
-  /*
-  * Returns the remote IP address.
-  */
-  IPAddress remoteIP();
-  
-
-  friend class WiFiEspServer;
-
-private:
-
-  uint8_t _sock;     // connection id
-
-  int connect(const char* host, uint16_t port, uint8_t protMode);
-  
-  size_t printFSH(const __FlashStringHelper *ifsh, bool appendCrLf);
-
-};
-
-#endif

+ 0 - 99
lib/WiFiEsp/src/WiFiEspServer.cpp

@@ -1,99 +0,0 @@
-/*--------------------------------------------------------------------
-This file is part of the Arduino WiFiEsp library.
-
-The Arduino WiFiEsp library is free software: you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation, either version 3 of the
-License, or (at your option) any later version.
-
-The Arduino WiFiEsp library is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with The Arduino WiFiEsp library.  If not, see
-<http://www.gnu.org/licenses/>.
---------------------------------------------------------------------*/
-
-#include "WiFiEspServer.h"
-
-#include "utility/EspDrv.h"
-#include "utility/debug.h"
-
-
-
-WiFiEspServer::WiFiEspServer(uint16_t port)
-{
-	_port = port;
-}
-
-void WiFiEspServer::begin()
-{
-	LOGDEBUG(F("Starting server"));
-
-	/* The ESP Module only allows socket 1 to be used for the server */
-#if 0
-	_sock = WiFiEspClass::getFreeSocket();
-	if (_sock == SOCK_NOT_AVAIL)
-	  {
-	    LOGERROR(F("No socket available for server"));
-	    return;
-	  }
-#else
-	_sock = 1; // If this is already in use, the startServer attempt will fail
-#endif
-	WiFiEspClass::allocateSocket(_sock);
-
-	_started = EspDrv::startServer(_port, _sock);
-
-	if (_started)
-	{
-		LOGINFO1(F("Server started on port"), _port);
-	}
-	else
-	{
-		LOGERROR(F("Server failed to start"));
-	}
-}
-
-WiFiEspClient WiFiEspServer::available(byte* status)
-{
-	// TODO the original method seems to handle automatic server restart
-
-	int bytes = EspDrv::availData(0);
-	if (bytes>0)
-	{
-		LOGINFO1(F("New client"), EspDrv::_connId);
-		WiFiEspClass::allocateSocket(EspDrv::_connId);
-		WiFiEspClient client(EspDrv::_connId);
-		return client;
-	}
-
-    return WiFiEspClient(255);
-}
-
-uint8_t WiFiEspServer::status()
-{
-    return EspDrv::getServerState(0);
-}
-
-size_t WiFiEspServer::write(uint8_t b)
-{
-    return write(&b, 1);
-}
-
-size_t WiFiEspServer::write(const uint8_t *buffer, size_t size)
-{
-	size_t n = 0;
-
-    for (int sock = 0; sock < MAX_SOCK_NUM; sock++)
-    {
-        if (WiFiEspClass::_state[sock] != 0)
-        {
-        	WiFiEspClient client(sock);
-            n += client.write(buffer, size);
-        }
-    }
-    return n;
-}

+ 0 - 63
lib/WiFiEsp/src/WiFiEspServer.h

@@ -1,63 +0,0 @@
-/*--------------------------------------------------------------------
-This file is part of the Arduino WiFiEsp library.
-
-The Arduino WiFiEsp library is free software: you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation, either version 3 of the
-License, or (at your option) any later version.
-
-The Arduino WiFiEsp library is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with The Arduino WiFiEsp library.  If not, see
-<http://www.gnu.org/licenses/>.
---------------------------------------------------------------------*/
-
-#ifndef WiFiEspServer_h
-#define WiFiEspServer_h
-
-#include <Server.h>
-
-#include "WiFiEsp.h"
-
-
-class WiFiEspClient;
-
-class WiFiEspServer : public Server
-{
-
-public:
-	WiFiEspServer(uint16_t port);
-
-
-	/*
-	* Gets a client that is connected to the server and has data available for reading.
-	* The connection persists when the returned client object goes out of scope; you can close it by calling client.stop().
-	* Returns a Client object; if no Client has data available for reading, this object will evaluate to false in an if-statement.
-	*/
-	WiFiEspClient available(uint8_t* status = NULL);
-
-	/*
-	* Start the TCP server
-	*/
-	void begin();
-
-	virtual size_t write(uint8_t);
-	virtual size_t write(const uint8_t *buf, size_t size);
-
-	uint8_t status();
-
-	using Print::write;
-
-
-private:
-	uint16_t _port;
-	uint8_t _sock;
-	bool _started;
-
-};
-
-#endif

+ 0 - 193
lib/WiFiEsp/src/WiFiEspUdp.cpp

@@ -1,193 +0,0 @@
-/*--------------------------------------------------------------------
-This file is part of the Arduino WiFiEsp library.
-
-The Arduino WiFiEsp library is free software: you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation, either version 3 of the
-License, or (at your option) any later version.
-
-The Arduino WiFiEsp library is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with The Arduino WiFiEsp library.  If not, see
-<http://www.gnu.org/licenses/>.
---------------------------------------------------------------------*/
-
-#include "WiFiEsp.h"
-#include "WiFiEspUdp.h"
-
-#include "utility/EspDrv.h"
-#include "utility/debug.h"
-
-/* Constructor */
-WiFiEspUDP::WiFiEspUDP() : _sock(NO_SOCKET_AVAIL) {}
-
-
-
-
-/* Start WiFiUDP socket, listening at local port PORT */
-
-uint8_t WiFiEspUDP::begin(uint16_t port)
-{
-    uint8_t sock = WiFiEspClass::getFreeSocket();
-    if (sock != NO_SOCKET_AVAIL)
-    {
-        EspDrv::startClient("0", port, sock, UDP_MODE);
-		
-        WiFiEspClass::allocateSocket(sock);  // allocating the socket for the listener
-        WiFiEspClass::_server_port[sock] = port;
-        _sock = sock;
-        _port = port;
-        return 1;
-    }
-    return 0;
-
-}
-
-
-/* return number of bytes available in the current packet,
-   will return zero if parsePacket hasn't been called yet */
-int WiFiEspUDP::available()
-{
-	 if (_sock != NO_SOCKET_AVAIL)
-	 {
-		int bytes = EspDrv::availData(_sock);
-		if (bytes>0)
-		{
-			return bytes;
-		}
-	}
-
-	return 0;
-}
-
-/* Release any resources being used by this WiFiUDP instance */
-void WiFiEspUDP::stop()
-{
-	  if (_sock == NO_SOCKET_AVAIL)
-	    return;
-
-      // Discard data that might be in the incoming buffer
-      flush();
-      
-      // Stop the listener and return the socket to the pool
-	  EspDrv::stopClient(_sock);
-      WiFiEspClass::_state[_sock] = NA_STATE;
-      WiFiEspClass::_server_port[_sock] = 0;
-
-	  _sock = NO_SOCKET_AVAIL;
-}
-
-int WiFiEspUDP::beginPacket(const char *host, uint16_t port)
-{
-  if (_sock == NO_SOCKET_AVAIL)
-	  _sock = WiFiEspClass::getFreeSocket();
-  if (_sock != NO_SOCKET_AVAIL)
-  {
-	  //EspDrv::startClient(host, port, _sock, UDP_MODE);
-	  _remotePort = port;
-	  strcpy(_remoteHost, host);
-	  WiFiEspClass::allocateSocket(_sock);
-	  return 1;
-  }
-  return 0;
-}
-
-
-int WiFiEspUDP::beginPacket(IPAddress ip, uint16_t port)
-{
-	char s[18];
-	sprintf_P(s, PSTR("%d.%d.%d.%d"), ip[0], ip[1], ip[2], ip[3]);
-
-	return beginPacket(s, port);
-}
-
-
-int WiFiEspUDP::endPacket()
-{
-	return 1; //ServerDrv::sendUdpData(_sock);
-}
-
-size_t WiFiEspUDP::write(uint8_t byte)
-{
-  return write(&byte, 1);
-}
-
-size_t WiFiEspUDP::write(const uint8_t *buffer, size_t size)
-{
-	bool r = EspDrv::sendDataUdp(_sock, _remoteHost, _remotePort, buffer, size);
-	if (!r)
-	{
-		return 0;
-	}
-
-	return size;
-}
-
-int WiFiEspUDP::parsePacket()
-{
-	return available();
-}
-
-int WiFiEspUDP::read()
-{
-	uint8_t b;
-	if (!available())
-		return -1;
-
-	bool connClose = false;
-	
-    // Read the data and handle the timeout condition
-	if (! EspDrv::getData(_sock, &b, false, &connClose))
-      return -1;  // Timeout occured
-
-	return b;
-}
-
-int WiFiEspUDP::read(uint8_t* buf, size_t size)
-{
-	if (!available())
-		return -1;
-	return EspDrv::getDataBuf(_sock, buf, size);
-}
-
-int WiFiEspUDP::peek()
-{
-  uint8_t b;
-  if (!available())
-    return -1;
-
-  return b;
-}
-
-void WiFiEspUDP::flush()
-{
-	  // Discard all input data
-	  int count = available();
-	  while (count-- > 0)
-	    read();
-}
-
-
-IPAddress  WiFiEspUDP::remoteIP()
-{
-	IPAddress ret;
-	EspDrv::getRemoteIpAddress(ret);
-	return ret;
-}
-
-uint16_t  WiFiEspUDP::remotePort()
-{
-	return EspDrv::getRemotePort();
-}
-
-
-
-////////////////////////////////////////////////////////////////////////////////
-// Private Methods
-////////////////////////////////////////////////////////////////////////////////
-
-

+ 0 - 97
lib/WiFiEsp/src/WiFiEspUdp.h

@@ -1,97 +0,0 @@
-/*--------------------------------------------------------------------
-This file is part of the Arduino WiFiEsp library.
-
-The Arduino WiFiEsp library is free software: you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation, either version 3 of the
-License, or (at your option) any later version.
-
-The Arduino WiFiEsp library is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with The Arduino WiFiEsp library.  If not, see
-<http://www.gnu.org/licenses/>.
---------------------------------------------------------------------*/
-
-#ifndef WiFiEspUdp_h
-#define WiFiEspUdp_h
-
-#include <Udp.h>
-
-#define UDP_TX_PACKET_MAX_SIZE 24
-
-class WiFiEspUDP : public UDP {
-private:
-  uint8_t _sock;  // socket ID for Wiz5100
-  uint16_t _port; // local port to listen on
-  
-  
-  uint16_t _remotePort;
-  char _remoteHost[30];
-  
-
-public:
-  WiFiEspUDP();  // Constructor
-
-  virtual uint8_t begin(uint16_t);	// initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
-  virtual void stop();  // Finish with the UDP socket
-
-  // Sending UDP packets
-
-  // Start building up a packet to send to the remote host specific in ip and port
-  // Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
-  virtual int beginPacket(IPAddress ip, uint16_t port);
-
-  // Start building up a packet to send to the remote host specific in host and port
-  // Returns 1 if successful, 0 if there was a problem resolving the hostname or port
-  virtual int beginPacket(const char *host, uint16_t port);
-
-  // Finish off this packet and send it
-  // Returns 1 if the packet was sent successfully, 0 if there was an error
-  virtual int endPacket();
-
-  // Write a single byte into the packet
-  virtual size_t write(uint8_t);
-
-  // Write size bytes from buffer into the packet
-  virtual size_t write(const uint8_t *buffer, size_t size);
-
-  using Print::write;
-
-  // Start processing the next available incoming packet
-  // Returns the size of the packet in bytes, or 0 if no packets are available
-  virtual int parsePacket();
-
-  // Number of bytes remaining in the current packet
-  virtual int available();
-
-  // Read a single byte from the current packet
-  virtual int read();
-
-  // Read up to len bytes from the current packet and place them into buffer
-  // Returns the number of bytes read, or 0 if none are available
-  virtual int read(unsigned char* buffer, size_t len);
-
-  // Read up to len characters from the current packet and place them into buffer
-  // Returns the number of characters read, or 0 if none are available
-  virtual int read(char* buffer, size_t len) { return read((unsigned char*)buffer, len); };
-
-  // Return the next byte from the current packet without moving on to the next byte
-  virtual int peek();
-
-  virtual void flush();	// Finish reading the current packet
-
-  // Return the IP address of the host who sent the current incoming packet
-  virtual IPAddress remoteIP();
-
-  // Return the port of the host who sent the current incoming packet
-  virtual uint16_t remotePort();
-
-
-  friend class WiFiEspServer;
-};
-
-#endif

+ 0 - 1127
lib/WiFiEsp/src/utility/EspDrv.cpp

@@ -1,1127 +0,0 @@
-/*--------------------------------------------------------------------
-This file is part of the Arduino WiFiEsp library.
-
-The Arduino WiFiEsp library is free software: you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation, either version 3 of the
-License, or (at your option) any later version.
-
-The Arduino WiFiEsp library is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with The Arduino WiFiEsp library.  If not, see
-<http://www.gnu.org/licenses/>.
---------------------------------------------------------------------*/
-
-#include <Arduino.h>
-#include <avr/pgmspace.h>
-
-#include "utility/EspDrv.h"
-#include "utility/debug.h"
-
-
-#define NUMESPTAGS 5
-
-const char* ESPTAGS[] =
-{
-    "\r\nOK\r\n",
-	"\r\nERROR\r\n",
-	"\r\nFAIL\r\n",
-    "\r\nSEND OK\r\n",
-    " CONNECT\r\n"
-};
-
-typedef enum
-{
-	TAG_OK,
-	TAG_ERROR,
-	TAG_FAIL,
-	TAG_SENDOK,
-	TAG_CONNECT
-} TagsEnum;
-
-
-Stream *EspDrv::espSerial;
-
-RingBuffer EspDrv::ringBuf(32);
-
-// Array of data to cache the information related to the networks discovered
-char 	EspDrv::_networkSsid[][WL_SSID_MAX_LENGTH] = {{"1"},{"2"},{"3"},{"4"},{"5"}};
-int32_t EspDrv::_networkRssi[WL_NETWORKS_LIST_MAXNUM] = { 0 };
-uint8_t EspDrv::_networkEncr[WL_NETWORKS_LIST_MAXNUM] = { 0 };
-
-// Cached values of retrieved data
-char EspDrv::_ssid[] = {0};
-uint8_t EspDrv::_bssid[] = {0};
-uint8_t EspDrv::_mac[] = {0};
-uint8_t EspDrv::_localIp[] = {0};
-char EspDrv::fwVersion[] = {0};
-
-long EspDrv::_bufPos=0;
-uint8_t EspDrv::_connId=0;
-
-uint16_t EspDrv::_remotePort  =0;
-uint8_t EspDrv::_remoteIp[] = {0};
-
-
-void EspDrv::wifiDriverInit(Stream *espSerial)
-{
-	LOGDEBUG(F("> wifiDriverInit"));
-
-	EspDrv::espSerial = espSerial;
-
-	bool initOK = false;
-	
-	for(int i=0; i<5; i++)
-	{
-		if (sendCmd(F("AT")) == TAG_OK)
-		{
-			initOK=true;
-			break;
-		}
-		delay(1000);
-	}
-
-	if (!initOK)
-	{
-		LOGERROR(F("Cannot initialize ESP module"));
-		delay(5000);
-		return;
-	}
-
-	reset();
-
-	// check firmware version
-	getFwVersion();
-
-	// prints a warning message if the firmware is not 1.X or 2.X
-	if ((fwVersion[0] != '1' and fwVersion[0] != '2') or
-		fwVersion[1] != '.')
-	{
-		LOGWARN1(F("Warning: Unsupported firmware"), fwVersion);
-		delay(4000);
-	}
-	else
-	{
-		LOGINFO1(F("Initilization successful -"), fwVersion);
-	}
-}
-
-
-void EspDrv::reset()
-{
-	LOGDEBUG(F("> reset"));
-
-	sendCmd(F("AT+RST"));
-	delay(3000);
-	espEmptyBuf(false);  // empty dirty characters from the buffer
-
-	// disable echo of commands
-	sendCmd(F("ATE0"));
-
-	// set station mode
-	sendCmd(F("AT+CWMODE=1"));
-	delay(200);
-
-	// set multiple connections mode
-	sendCmd(F("AT+CIPMUX=1"));
-
-	// Show remote IP and port with "+IPD"
-	sendCmd(F("AT+CIPDINFO=1"));
-	
-	// Disable autoconnect
-	// Automatic connection can create problems during initialization phase at next boot
-	sendCmd(F("AT+CWAUTOCONN=0"));
-
-	// enable DHCP
-	sendCmd(F("AT+CWDHCP=1,1"));
-	delay(200);
-}
-
-
-
-bool EspDrv::wifiConnect(const char* ssid, const char* passphrase)
-{
-	LOGDEBUG(F("> wifiConnect"));
-
-	// TODO
-	// Escape character syntax is needed if "SSID" or "password" contains
-	// any special characters (',', '"' and '/')
-
-    // connect to access point, use CUR mode to avoid connection at boot
-	int ret = sendCmd(F("AT+CWJAP_CUR=\"%s\",\"%s\""), 20000, ssid, passphrase);
-
-	if (ret==TAG_OK)
-	{
-		LOGINFO1(F("Connected to"), ssid);
-		return true;
-	}
-
-	LOGWARN1(F("Failed connecting to"), ssid);
-
-	// clean additional messages logged after the FAIL tag
-	delay(1000);
-	espEmptyBuf(false);
-
-	return false;
-}
-
-
-bool EspDrv::wifiStartAP(const char* ssid, const char* pwd, uint8_t channel, uint8_t enc, uint8_t espMode)
-{
-	LOGDEBUG(F("> wifiStartAP"));
-
-	// set AP mode, use CUR mode to avoid automatic start at boot
-    int ret = sendCmd(F("AT+CWMODE_CUR=%d"), 10000, espMode);
-	if (ret!=TAG_OK)
-	{
-		LOGWARN1(F("Failed to set AP mode"), ssid);
-		return false;
-	}
-
-	// TODO
-	// Escape character syntax is needed if "SSID" or "password" contains
-	// any special characters (',', '"' and '/')
-
-	// start access point
-	ret = sendCmd(F("AT+CWSAP_CUR=\"%s\",\"%s\",%d,%d"), 10000, ssid, pwd, channel, enc);
-
-	if (ret!=TAG_OK)
-	{
-		LOGWARN1(F("Failed to start AP"), ssid);
-		return false;
-	}
-	
-	if (espMode==2)
-		sendCmd(F("AT+CWDHCP_CUR=0,1"));    // enable DHCP for AP mode
-	if (espMode==3)
-		sendCmd(F("AT+CWDHCP_CUR=2,1"));    // enable DHCP for station and AP mode
-
-	LOGINFO1(F("Access point started"), ssid);
-	return true;
-}
-
-
-int8_t EspDrv::disconnect()
-{
-	LOGDEBUG(F("> disconnect"));
-
-	if(sendCmd(F("AT+CWQAP"))==TAG_OK)
-		return WL_DISCONNECTED;
-
-	// wait and clear any additional message
-	delay(2000);
-	espEmptyBuf(false);
-
-	return WL_DISCONNECTED;
-}
-
-void EspDrv::config(IPAddress ip)
-{
-	LOGDEBUG(F("> config"));
-
-	// disable station DHCP
-	sendCmd(F("AT+CWDHCP_CUR=1,0"));
-	
-	// it seems we need to wait here...
-	delay(500);
-	
-	char buf[16];
-	sprintf_P(buf, PSTR("%d.%d.%d.%d"), ip[0], ip[1], ip[2], ip[3]);
-
-	int ret = sendCmd(F("AT+CIPSTA_CUR=\"%s\""), 2000, buf);
-	delay(500);
-
-	if (ret==TAG_OK)
-	{
-		LOGINFO1(F("IP address set"), buf);
-	}
-}
-
-void EspDrv::configAP(IPAddress ip)
-{
-	LOGDEBUG(F("> config"));
-	
-    sendCmd(F("AT+CWMODE_CUR=2"));
-	
-	// disable station DHCP
-	sendCmd(F("AT+CWDHCP_CUR=2,0"));
-	
-	// it seems we need to wait here...
-	delay(500);
-	
-	char buf[16];
-	sprintf_P(buf, PSTR("%d.%d.%d.%d"), ip[0], ip[1], ip[2], ip[3]);
-
-	int ret = sendCmd(F("AT+CIPAP_CUR=\"%s\""), 2000, buf);
-	delay(500);
-
-	if (ret==TAG_OK)
-	{
-		LOGINFO1(F("IP address set"), buf);
-	}
-}
-
-uint8_t EspDrv::getConnectionStatus()
-{
-	LOGDEBUG(F("> getConnectionStatus"));
-
-/*
-	AT+CIPSTATUS
-
-	Response
-
-		STATUS:<stat>
-		+CIPSTATUS:<link ID>,<type>,<remote_IP>,<remote_port>,<local_port>,<tetype>
-
-	Parameters
-
-		<stat>
-			2: Got IP
-			3: Connected
-			4: Disconnected
-		<link ID> ID of the connection (0~4), for multi-connect
-		<type> string, "TCP" or "UDP"
-		<remote_IP> string, remote IP address.
-		<remote_port> remote port number
-		<local_port> ESP8266 local port number
-		<tetype>
-			0: ESP8266 runs as client
-			1: ESP8266 runs as server
-*/
-
-	char buf[10];
-	if(!sendCmdGet(F("AT+CIPSTATUS"), F("STATUS:"), F("\r\n"), buf, sizeof(buf)))
-		return WL_NO_SHIELD;
-
-	// 4: client disconnected
-	// 5: wifi disconnected
-	int s = atoi(buf);
-	if(s==2 or s==3 or s==4)
-		return WL_CONNECTED;
-	else if(s==5)
-		return WL_DISCONNECTED;
-
-	return WL_IDLE_STATUS;
-}
-
-uint8_t EspDrv::getClientState(uint8_t sock)
-{
-	LOGDEBUG1(F("> getClientState"), sock);
-
-	char findBuf[20];
-	sprintf_P(findBuf, PSTR("+CIPSTATUS:%d,"), sock);
-
-	char buf[10];
-	if (sendCmdGet(F("AT+CIPSTATUS"), findBuf, ",", buf, sizeof(buf)))
-	{
-		LOGDEBUG(F("Connected"));
-		return true;
-	}
-
-	LOGDEBUG(F("Not connected"));
-	return false;
-}
-
-uint8_t* EspDrv::getMacAddress()
-{
-	LOGDEBUG(F("> getMacAddress"));
-
-	memset(_mac, 0, WL_MAC_ADDR_LENGTH);
-
-	char buf[20];
-	if (sendCmdGet(F("AT+CIFSR"), F(":STAMAC,\""), F("\""), buf, sizeof(buf)))
-	{
-		char* token;
-
-		token = strtok(buf, ":");
-		_mac[5] = (byte)strtol(token, NULL, 16);
-		token = strtok(NULL, ":");
-		_mac[4] = (byte)strtol(token, NULL, 16);
-		token = strtok(NULL, ":");
-		_mac[3] = (byte)strtol(token, NULL, 16);
-		token = strtok(NULL, ":");
-		_mac[2] = (byte)strtol(token, NULL, 16);
-		token = strtok(NULL, ":");
-		_mac[1] = (byte)strtol(token, NULL, 16);
-		token = strtok(NULL, ":");
-		_mac[0] = (byte)strtol(token, NULL, 16);
-	}
-	return _mac;
-}
-
-
-void EspDrv::getIpAddress(IPAddress& ip)
-{
-	LOGDEBUG(F("> getIpAddress"));
-
-	char buf[20];
-	if (sendCmdGet(F("AT+CIFSR"), F(":STAIP,\""), F("\""), buf, sizeof(buf)))
-	{
-		char* token;
-
-		token = strtok(buf, ".");
-		_localIp[0] = atoi(token);
-		token = strtok(NULL, ".");
-		_localIp[1] = atoi(token);
-		token = strtok(NULL, ".");
-		_localIp[2] = atoi(token);
-		token = strtok(NULL, ".");
-		_localIp[3] = atoi(token);
-
-		ip = _localIp;
-	}
-}
-
-void EspDrv::getIpAddressAP(IPAddress& ip)
-{
-	LOGDEBUG(F("> getIpAddressAP"));
-
-	char buf[20];
-	if (sendCmdGet(F("AT+CIPAP?"), F("+CIPAP:ip:\""), F("\""), buf, sizeof(buf)))
-	{
-		char* token;
-
-		token = strtok(buf, ".");
-		_localIp[0] = atoi(token);
-		token = strtok(NULL, ".");
-		_localIp[1] = atoi(token);
-		token = strtok(NULL, ".");
-		_localIp[2] = atoi(token);
-		token = strtok(NULL, ".");
-		_localIp[3] = atoi(token);
-
-		ip = _localIp;
-	}
-}
-
-
-
-char* EspDrv::getCurrentSSID()
-{
-	LOGDEBUG(F("> getCurrentSSID"));
-
-	_ssid[0] = 0;
-	sendCmdGet(F("AT+CWJAP?"), F("+CWJAP:\""), F("\""), _ssid, sizeof(_ssid));
-
-	return _ssid;
-}
-
-uint8_t* EspDrv::getCurrentBSSID()
-{
-	LOGDEBUG(F("> getCurrentBSSID"));
-
-	memset(_bssid, 0, WL_MAC_ADDR_LENGTH);
-
-	char buf[20];
-	if (sendCmdGet(F("AT+CWJAP?"), F(",\""), F("\","), buf, sizeof(buf)))
-	{
-		char* token;
-
-		token = strtok(buf, ":");
-		_bssid[5] = (byte)strtol(token, NULL, 16);
-		token = strtok(NULL, ":");
-		_bssid[4] = (byte)strtol(token, NULL, 16);
-		token = strtok(NULL, ":");
-		_bssid[3] = (byte)strtol(token, NULL, 16);
-		token = strtok(NULL, ":");
-		_bssid[2] = (byte)strtol(token, NULL, 16);
-		token = strtok(NULL, ":");
-		_bssid[1] = (byte)strtol(token, NULL, 16);
-		token = strtok(NULL, ":");
-		_bssid[0] = (byte)strtol(token, NULL, 16);
-	}
-	return _bssid;
-
-}
-
-int32_t EspDrv::getCurrentRSSI()
-{
-	LOGDEBUG(F("> getCurrentRSSI"));
-
-    int ret=0;
-	char buf[10];
-	sendCmdGet(F("AT+CWJAP?"), F(",-"), F("\r\n"), buf, sizeof(buf));
-
-	if (isDigit(buf[0])) {
-      ret = -atoi(buf);
-    }
-
-    return ret;
-}
-
-
-uint8_t EspDrv::getScanNetworks()
-{
-    uint8_t ssidListNum = 0;
-    int idx;
-	bool ret = false;
-	
-
-	espEmptyBuf();
-
-	LOGDEBUG(F("----------------------------------------------"));
-	LOGDEBUG(F(">> AT+CWLAP"));
-	
-	espSerial->println(F("AT+CWLAP"));
-
-	char buf[100];
-	
-	idx = readUntil(10000, "+CWLAP:(");
-	
-	while (idx == NUMESPTAGS)
-	{
-		_networkEncr[ssidListNum] = espSerial->parseInt();
-		
-		// discard , and " characters
-		readUntil(1000, "\"");
-
-		idx = readUntil(1000, "\"", false);
-		if(idx==NUMESPTAGS)
-		{
-			memset(_networkSsid[ssidListNum], 0, WL_SSID_MAX_LENGTH );
-			ringBuf.getStrN(_networkSsid[ssidListNum], 1, WL_SSID_MAX_LENGTH-1);
-		}
-		
-		// discard , character
-		readUntil(1000, ",");
-		
-		_networkRssi[ssidListNum] = espSerial->parseInt();
-		
-		idx = readUntil(1000, "+CWLAP:(");
-
-		if(ssidListNum==WL_NETWORKS_LIST_MAXNUM-1)
-			break;
-
-		ssidListNum++;
-	}
-	
-	if (idx==-1)
-		return -1;
-
-	LOGDEBUG1(F("---------------------------------------------- >"), ssidListNum);
-	LOGDEBUG();
-    return ssidListNum;
-}
-
-bool EspDrv::getNetmask(IPAddress& mask) {
-	LOGDEBUG(F("> getNetmask"));
-
-	char buf[20];
-	if (sendCmdGet(F("AT+CIPSTA?"), F("+CIPSTA:netmask:\""), F("\""), buf, sizeof(buf)))
-	{
-		mask.fromString (buf);
-		return true;
-	}
-
-	return false;
-}
-
-bool EspDrv::getGateway(IPAddress& gw)
-{
-	LOGDEBUG(F("> getGateway"));
-
-	char buf[20];
-	if (sendCmdGet(F("AT+CIPSTA?"), F("+CIPSTA:gateway:\""), F("\""), buf, sizeof(buf)))
-	{
-		gw.fromString (buf);
-		return true;
-	}
-
-	return false;
-}
-
-char* EspDrv::getSSIDNetoworks(uint8_t networkItem)
-{
-	if (networkItem >= WL_NETWORKS_LIST_MAXNUM)
-		return NULL;
-
-	return _networkSsid[networkItem];
-}
-
-uint8_t EspDrv::getEncTypeNetowrks(uint8_t networkItem)
-{
-	if (networkItem >= WL_NETWORKS_LIST_MAXNUM)
-		return 0;
-
-    return _networkEncr[networkItem];
-}
-
-int32_t EspDrv::getRSSINetoworks(uint8_t networkItem)
-{
-	if (networkItem >= WL_NETWORKS_LIST_MAXNUM)
-		return 0;
-
-    return _networkRssi[networkItem];
-}
-
-char* EspDrv::getFwVersion()
-{
-	LOGDEBUG(F("> getFwVersion"));
-
-	fwVersion[0] = 0;
-
-	sendCmdGet(F("AT+GMR"), F("SDK version:"), F("\r\n"), fwVersion, sizeof(fwVersion));
-
-    return fwVersion;
-}
-
-
-
-bool EspDrv::ping(const char *host)
-{
-	LOGDEBUG(F("> ping"));
-
-	int ret = sendCmd(F("AT+PING=\"%s\""), 8000, host);
-	
-	if (ret==TAG_OK)
-		return true;
-
-	return false;
-}
-
-
-
-// Start server TCP on port specified
-bool EspDrv::startServer(uint16_t port, uint8_t sock)
-{
-	LOGDEBUG1(F("> startServer"), port);
-
-	int ret = sendCmd(F("AT+CIPSERVER=%d,%d"), 1000, sock, port);
-
-	return ret==TAG_OK;
-}
-
-
-bool EspDrv::startClient(const char* host, uint16_t port, uint8_t sock, uint8_t protMode)
-{
-	LOGDEBUG2(F("> startClient"), host, port);
-	
-	// TCP
-	// AT+CIPSTART=<link ID>,"TCP",<remote IP>,<remote port>
-
-	// UDP
-	// AT+CIPSTART=<link ID>,"UDP",<remote IP>,<remote port>[,<UDP local port>,<UDP mode>]
-
-	// for UDP we set a dummy remote port and UDP mode to 2
-	// this allows to specify the target host/port in CIPSEND
-
-	int ret;
-	if (protMode==TCP_MODE)
-		ret = sendCmd(F("AT+CIPSTART=%d,\"TCP\",\"%s\",%u"), 5000, sock, host, port);
-	else if (protMode==SSL_MODE)
-	{
-		// better to put the CIPSSLSIZE here because it is not supported before firmware 1.4
-		sendCmd(F("AT+CIPSSLSIZE=4096"));
-		ret = sendCmd(F("AT+CIPSTART=%d,\"SSL\",\"%s\",%u"), 5000, sock, host, port);
-	}
-	else if (protMode==UDP_MODE)
-		ret = sendCmd(F("AT+CIPSTART=%d,\"UDP\",\"%s\",0,%u,2"), 5000, sock, host, port);
-
-	return ret==TAG_OK;
-}
-
-
-// Start server TCP on port specified
-void EspDrv::stopClient(uint8_t sock)
-{
-	LOGDEBUG1(F("> stopClient"), sock);
-
-	int ret = sendCmd(F("AT+CIPCLOSE=%d"), 4000, sock);
-}
-
-
-uint8_t EspDrv::getServerState(uint8_t sock)
-{
-    return 0;
-}
-
-
-
-////////////////////////////////////////////////////////////////////////////
-// TCP/IP functions
-////////////////////////////////////////////////////////////////////////////
-
-
-
-uint16_t EspDrv::availData(uint8_t connId)
-{
-    //LOGDEBUG(bufPos);
-
-	// if there is data in the buffer
-	if (_bufPos>0)
-	{
-		if (_connId==connId)
-			return _bufPos;
-		else if (_connId==0)
-			return _bufPos;
-	}
-
-
-    int bytes = espSerial->available();
-
-	if (bytes)
-	{
-		//LOGDEBUG1(F("Bytes in the serial buffer: "), bytes);
-		if (espSerial->find((char *)"+IPD,"))
-		{
-			// format is : +IPD,<id>,<len>:<data>
-			// format is : +IPD,<ID>,<len>[,<remote IP>,<remote port>]:<data>
-
-			_connId = espSerial->parseInt();    // <ID>
-			espSerial->read();                  // ,
-			_bufPos = espSerial->parseInt();    // <len>
-			espSerial->read();                  // "
-			_remoteIp[0] = espSerial->parseInt();    // <remote IP>
-			espSerial->read();                  // .
-			_remoteIp[1] = espSerial->parseInt();
-			espSerial->read();                  // .
-			_remoteIp[2] = espSerial->parseInt();
-			espSerial->read();                  // .
-			_remoteIp[3] = espSerial->parseInt();
-			espSerial->read();                  // "
-			espSerial->read();                  // ,
-			_remotePort = espSerial->parseInt();     // <remote port>
-			
-			espSerial->read();                  // :
-
-			LOGDEBUG();
-			LOGDEBUG2(F("Data packet"), _connId, _bufPos);
-
-			if(_connId==connId || connId==0)
-				return _bufPos;
-		}
-	}
-	return 0;
-}
-
-
-bool EspDrv::getData(uint8_t connId, uint8_t *data, bool peek, bool* connClose)
-{
-	if (connId!=_connId)
-		return false;
-
-
-	// see Serial.timedRead
-
-	long _startMillis = millis();
-	do
-	{
-		if (espSerial->available())
-		{
-			if (peek)
-			{
-				*data = (char)espSerial->peek();
-			}
-			else
-			{
-				*data = (char)espSerial->read();
-				_bufPos--;
-			}
-			//Serial.print((char)*data);
-
-			if (_bufPos == 0)
-			{
-				// after the data packet a ",CLOSED" string may be received
-				// this means that the socket is now closed
-
-				delay(5);
-
-				if (espSerial->available())
-				{
-					//LOGDEBUG(".2");
-					//LOGDEBUG(espSerial->peek());
-
-					// 48 = '0'
-					if (espSerial->peek()==48+connId)
-					{
-						int idx = readUntil(500, ",CLOSED\r\n", false);
-						if(idx!=NUMESPTAGS)
-						{
-							LOGERROR(F("Tag CLOSED not found"));
-						}
-
-						LOGDEBUG();
-						LOGDEBUG(F("Connection closed"));
-
-						*connClose=true;
-					}
-				}
-			}
-
-			return true;
-		}
-	} while(millis() - _startMillis < 2000);
-
-    // timed out, reset the buffer
-	LOGERROR1(F("TIMEOUT:"), _bufPos);
-
-    _bufPos = 0;
-	_connId = 0;
-	*data = 0;
-	
-	return false;
-}
-
-/**
- * Receive the data into a buffer.
- * It reads up to bufSize bytes.
- * @return	received data size for success else -1.
- */
-int EspDrv::getDataBuf(uint8_t connId, uint8_t *buf, uint16_t bufSize)
-{
-	if (connId!=_connId)
-		return false;
-
-	if(_bufPos<bufSize)
-		bufSize = _bufPos;
-	
-	for(int i=0; i<bufSize; i++)
-	{
-		int c = timedRead();
-		//LOGDEBUG(c);
-		if(c==-1)
-			return -1;
-		
-		buf[i] = (char)c;
-		_bufPos--;
-	}
-
-	return bufSize;
-}
-
-
-bool EspDrv::sendData(uint8_t sock, const uint8_t *data, uint16_t len)
-{
-	LOGDEBUG2(F("> sendData:"), sock, len);
-
-	char cmdBuf[20];
-	sprintf_P(cmdBuf, PSTR("AT+CIPSEND=%d,%u"), sock, len);
-	espSerial->println(cmdBuf);
-
-	int idx = readUntil(1000, (char *)">", false);
-	if(idx!=NUMESPTAGS)
-	{
-		LOGERROR(F("Data packet send error (1)"));
-		return false;
-	}
-
-	espSerial->write(data, len);
-
-	idx = readUntil(2000);
-	if(idx!=TAG_SENDOK)
-	{
-		LOGERROR(F("Data packet send error (2)"));
-		return false;
-	}
-
-    return true;
-}
-
-// Overrided sendData method for __FlashStringHelper strings
-bool EspDrv::sendData(uint8_t sock, const __FlashStringHelper *data, uint16_t len, bool appendCrLf)
-{
-	LOGDEBUG2(F("> sendData:"), sock, len);
-
-	char cmdBuf[20];
-	uint16_t len2 = len + 2*appendCrLf;
-	sprintf_P(cmdBuf, PSTR("AT+CIPSEND=%d,%u"), sock, len2);
-	espSerial->println(cmdBuf);
-
-	int idx = readUntil(1000, (char *)">", false);
-	if(idx!=NUMESPTAGS)
-	{
-		LOGERROR(F("Data packet send error (1)"));
-		return false;
-	}
-
-	//espSerial->write(data, len);
-	PGM_P p = reinterpret_cast<PGM_P>(data);
-	for (int i=0; i<len; i++)
-	{
-		unsigned char c = pgm_read_byte(p++);
-		espSerial->write(c);
-	}
-	if (appendCrLf)
-	{
-		espSerial->write('\r');
-		espSerial->write('\n');
-	}
-
-	idx = readUntil(2000);
-	if(idx!=TAG_SENDOK)
-	{
-		LOGERROR(F("Data packet send error (2)"));
-		return false;
-	}
-
-    return true;
-}
-
-bool EspDrv::sendDataUdp(uint8_t sock, const char* host, uint16_t port, const uint8_t *data, uint16_t len)
-{
-	LOGDEBUG2(F("> sendDataUdp:"), sock, len);
-	LOGDEBUG2(F("> sendDataUdp:"), host, port);
-
-	char cmdBuf[40];
-	sprintf_P(cmdBuf, PSTR("AT+CIPSEND=%d,%u,\"%s\",%u"), sock, len, host, port);
-	//LOGDEBUG1(F("> sendDataUdp:"), cmdBuf);
-	espSerial->println(cmdBuf);
-
-	int idx = readUntil(1000, (char *)">", false);
-	if(idx!=NUMESPTAGS)
-	{
-		LOGERROR(F("Data packet send error (1)"));
-		return false;
-	}
-
-	espSerial->write(data, len);
-
-	idx = readUntil(2000);
-	if(idx!=TAG_SENDOK)
-	{
-		LOGERROR(F("Data packet send error (2)"));
-		return false;
-	}
-
-    return true;
-}
-
-
-
-void EspDrv::getRemoteIpAddress(IPAddress& ip)
-{
-	ip = _remoteIp;
-}
-
-uint16_t EspDrv::getRemotePort()
-{
-	return _remotePort;
-}
-
-
-////////////////////////////////////////////////////////////////////////////
-// Utility functions
-////////////////////////////////////////////////////////////////////////////
-
-
-
-/*
-* Sends the AT command and stops if any of the TAGS is found.
-* Extract the string enclosed in the passed tags and returns it in the outStr buffer.
-* Returns true if the string is extracted, false if tags are not found of timed out.
-*/
-bool EspDrv::sendCmdGet(const __FlashStringHelper* cmd, const char* startTag, const char* endTag, char* outStr, int outStrLen)
-{
-    int idx;
-	bool ret = false;
-
-	outStr[0] = 0;
-
-	espEmptyBuf();
-
-	LOGDEBUG(F("----------------------------------------------"));
-	LOGDEBUG1(F(">>"), cmd);
-
-	// send AT command to ESP
-	espSerial->println(cmd);
-
-	// read result until the startTag is found
-	idx = readUntil(1000, startTag);
-
-	if(idx==NUMESPTAGS)
-	{
-		// clean the buffer to get a clean string
-		ringBuf.init();
-
-		// start tag found, search the endTag
-		idx = readUntil(500, endTag);
-
-		if(idx==NUMESPTAGS)
-		{
-			// end tag found
-			// copy result to output buffer avoiding overflow
-			ringBuf.getStrN(outStr, strlen(endTag), outStrLen-1);
-
-			// read the remaining part of the response
-			readUntil(2000);
-
-			ret = true;
-		}
-		else
-		{
-			LOGWARN(F("End tag not found"));
-		}
-	}
-	else if(idx>=0 and idx<NUMESPTAGS)
-	{
-		// the command has returned but no start tag is found
-		LOGDEBUG1(F("No start tag found:"), idx);
-	}
-	else
-	{
-		// the command has returned but no tag is found
-		LOGWARN(F("No tag found"));
-	}
-
-	LOGDEBUG1(F("---------------------------------------------- >"), outStr);
-	LOGDEBUG();
-
-	return ret;
-}
-
-bool EspDrv::sendCmdGet(const __FlashStringHelper* cmd, const __FlashStringHelper* startTag, const __FlashStringHelper* endTag, char* outStr, int outStrLen)
-{
-	char _startTag[strlen_P((char*)startTag)+1];
-	strcpy_P(_startTag,  (char*)startTag);
-
-	char _endTag[strlen_P((char*)endTag)+1];
-	strcpy_P(_endTag,  (char*)endTag);
-
-	return sendCmdGet(cmd, _startTag, _endTag, outStr, outStrLen);
-}
-
-
-/*
-* Sends the AT command and returns the id of the TAG.
-* Return -1 if no tag is found.
-*/
-int EspDrv::sendCmd(const __FlashStringHelper* cmd, int timeout)
-{
-    espEmptyBuf();
-
-	LOGDEBUG(F("----------------------------------------------"));
-	LOGDEBUG1(F(">>"), cmd);
-
-	espSerial->println(cmd);
-
-	int idx = readUntil(timeout);
-
-	LOGDEBUG1(F("---------------------------------------------- >"), idx);
-	LOGDEBUG();
-
-    return idx;
-}
-
-
-/*
-* Sends the AT command and returns the id of the TAG.
-* The additional arguments are formatted into the command using sprintf.
-* Return -1 if no tag is found.
-*/
-int EspDrv::sendCmd(const __FlashStringHelper* cmd, int timeout, ...)
-{
-	char cmdBuf[CMD_BUFFER_SIZE];
-
-	va_list args;
-	va_start (args, timeout);
-	vsnprintf_P (cmdBuf, CMD_BUFFER_SIZE, (char*)cmd, args);
-	va_end (args);
-
-	espEmptyBuf();
-
-	LOGDEBUG(F("----------------------------------------------"));
-	LOGDEBUG1(F(">>"), cmdBuf);
-
-	espSerial->println(cmdBuf);
-
-	int idx = readUntil(timeout);
-
-	LOGDEBUG1(F("---------------------------------------------- >"), idx);
-	LOGDEBUG();
-
-	return idx;
-}
-
-
-// Read from serial until one of the tags is found
-// Returns:
-//   the index of the tag found in the ESPTAGS array
-//   -1 if no tag was found (timeout)
-int EspDrv::readUntil(int timeout, const char* tag, bool findTags)
-{
-	ringBuf.reset();
-
-	char c;
-    unsigned long start = millis();
-	int ret = -1;
-
-	while ((millis() - start < timeout) and ret<0)
-	{
-        if(espSerial->available())
-		{
-            c = (char)espSerial->read();
-			LOGDEBUG0(c);
-			ringBuf.push(c);
-
-			if (tag!=NULL)
-			{
-				if (ringBuf.endsWith(tag))
-				{
-					ret = NUMESPTAGS;
-					//LOGDEBUG1("xxx");
-				}
-			}
-			if(findTags)
-			{
-				for(int i=0; i<NUMESPTAGS; i++)
-				{
-					if (ringBuf.endsWith(ESPTAGS[i]))
-					{
-						ret = i;
-						break;
-					}
-				}
-			}
-		}
-    }
-
-	if (millis() - start >= timeout)
-	{
-		LOGWARN(F(">>> TIMEOUT >>>"));
-	}
-
-    return ret;
-}
-
-
-void EspDrv::espEmptyBuf(bool warn)
-{
-    char c;
-	int i=0;
-	while(espSerial->available() > 0)
-    {
-		c = espSerial->read();
-		if (i>0 and warn==true)
-			LOGDEBUG0(c);
-		i++;
-	}
-	if (i>0 and warn==true)
-    {
-		LOGDEBUG(F(""));
-		LOGDEBUG1(F("Dirty characters in the serial buffer! >"), i);
-	}
-}
-
-
-// copied from Serial::timedRead
-int EspDrv::timedRead()
-{
-  int _timeout = 1000;
-  int c;
-  long _startMillis = millis();
-  do
-  {
-    c = espSerial->read();
-    if (c >= 0) return c;
-  } while(millis() - _startMillis < _timeout);
-
-  return -1; // -1 indicates timeout
-}
-
-
-
-EspDrv espDrv;

+ 0 - 340
lib/WiFiEsp/src/utility/EspDrv.h

@@ -1,340 +0,0 @@
-/*--------------------------------------------------------------------
-This file is part of the Arduino WiFiEsp library.
-
-The Arduino WiFiEsp library is free software: you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation, either version 3 of the
-License, or (at your option) any later version.
-
-The Arduino WiFiEsp library is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with The Arduino WiFiEsp library.  If not, see
-<http://www.gnu.org/licenses/>.
---------------------------------------------------------------------*/
-
-#ifndef EspDrv_h
-#define EspDrv_h
-
-#include "Stream.h"
-#include "IPAddress.h"
-
-
-#include "RingBuffer.h"
-
-
-
-// Maximum size of a SSID
-#define WL_SSID_MAX_LENGTH 32
-
-// Size of a MAC-address or BSSID
-#define WL_MAC_ADDR_LENGTH 6
-
-// Size of a MAC-address or BSSID
-#define WL_IPV4_LENGTH 4
-
-// Maximum size of a SSID list
-#define WL_NETWORKS_LIST_MAXNUM	10
-
-// Maxmium number of socket
-#define	MAX_SOCK_NUM		4
-
-// Socket not available constant
-#define SOCK_NOT_AVAIL  255
-
-// Default state value for Wifi state field
-#define NA_STATE -1
-
-#define WL_FW_VER_LENGTH 6
-
-#define NO_SOCKET_AVAIL 255
-
-
-// maximum size of AT command
-#define CMD_BUFFER_SIZE 200
-
-
-typedef enum eProtMode {TCP_MODE, UDP_MODE, SSL_MODE} tProtMode;
-
-
-typedef enum {
-        WL_FAILURE = -1,
-        WL_SUCCESS = 1,
-} wl_error_code_t;
-
-/* Authentication modes */
-enum wl_auth_mode {
-        AUTH_MODE_INVALID,
-        AUTH_MODE_AUTO,
-        AUTH_MODE_OPEN_SYSTEM,
-        AUTH_MODE_SHARED_KEY,
-        AUTH_MODE_WPA,
-        AUTH_MODE_WPA2,
-        AUTH_MODE_WPA_PSK,
-        AUTH_MODE_WPA2_PSK
-};
-
-
-typedef enum {
-	WL_NO_SHIELD = 255,
-	WL_IDLE_STATUS = 0,
-	//WL_NO_SSID_AVAIL,
-	//WL_SCAN_COMPLETED,
-	WL_CONNECTED,
-	WL_CONNECT_FAILED,
-	//WL_CONNECTION_LOST,
-	WL_DISCONNECTED
-} wl_status_t;
-
-/* Encryption modes */
-enum wl_enc_type {
-	ENC_TYPE_NONE = 0,
-	ENC_TYPE_WEP = 1,
-	ENC_TYPE_WPA_PSK = 2,
-	ENC_TYPE_WPA2_PSK = 3,
-	ENC_TYPE_WPA_WPA2_PSK = 4
-};
-
-
-enum wl_tcp_state {
-	CLOSED      = 0,
-	LISTEN      = 1,
-	SYN_SENT    = 2,
-	SYN_RCVD    = 3,
-	ESTABLISHED = 4,
-	FIN_WAIT_1  = 5,
-	FIN_WAIT_2  = 6,
-	CLOSE_WAIT  = 7,
-	CLOSING     = 8,
-	LAST_ACK    = 9,
-	TIME_WAIT   = 10
-};
-
-
-
-class EspDrv
-{
-
-public:
-
-    static void wifiDriverInit(Stream *espSerial);
-
-
-    /* Start Wifi connection with passphrase
-     *
-     * param ssid: Pointer to the SSID string.
-     * param passphrase: Passphrase. Valid characters in a passphrase must be between ASCII 32-126 (decimal).
-     */
-    static bool wifiConnect(const char* ssid, const char* passphrase);
-
-
-    /*
-	* Start the Access Point
-	*/
-	static bool wifiStartAP(const char* ssid, const char* pwd, uint8_t channel, uint8_t enc, uint8_t espMode);
-
-
-    /*
-	 * Set ip configuration disabling dhcp client
-	 */
-    static void config(IPAddress local_ip);
-
-    /*
-	 * Set ip configuration disabling dhcp client
-	 */
-    static void configAP(IPAddress local_ip);
-
-
-    /*
-     * Disconnect from the network
-     *
-     * return: WL_SUCCESS or WL_FAILURE
-     */
-    static int8_t disconnect();
-
-    /*
-     *
-     *
-     * return: one value of wl_status_t enum
-     */
-    static uint8_t getConnectionStatus();
-
-    /*
-     * Get the interface MAC address.
-     *
-     * return: pointer to uint8_t array with length WL_MAC_ADDR_LENGTH
-     */
-    static uint8_t* getMacAddress();
-
-    /*
-     * Get the interface IP address.
-     *
-     * return: copy the ip address value in IPAddress object
-     */
-    static void getIpAddress(IPAddress& ip);
-
-	static void getIpAddressAP(IPAddress& ip);
-
-    /*
-     * Get the interface IP netmask.
-     * This can be used to retrieve settings configured through DHCP.
-     *
-     * return: true if successful
-     */
-    static bool getNetmask(IPAddress& mask);
-
-    /*
-     * Get the interface IP gateway.
-     * This can be used to retrieve settings configured through DHCP.
-     *
-     * return: true if successful
-     */
-    static bool getGateway(IPAddress& mask);
-
-    /*
-     * Return the current SSID associated with the network
-     *
-     * return: ssid string
-     */
-    static char* getCurrentSSID();
-
-    /*
-     * Return the current BSSID associated with the network.
-     * It is the MAC address of the Access Point
-     *
-     * return: pointer to uint8_t array with length WL_MAC_ADDR_LENGTH
-     */
-    static uint8_t* getCurrentBSSID();
-
-    /*
-     * Return the current RSSI /Received Signal Strength in dBm)
-     * associated with the network
-     *
-     * return: signed value
-     */
-    static int32_t getCurrentRSSI();
-
-    /*
-     * Get the networks available
-     *
-     * return: Number of discovered networks
-     */
-    static uint8_t getScanNetworks();
-
-	/*
-     * Return the SSID discovered during the network scan.
-     *
-     * param networkItem: specify from which network item want to get the information
-	 *
-     * return: ssid string of the specified item on the networks scanned list
-     */
-    static char* getSSIDNetoworks(uint8_t networkItem);
-
-    /*
-     * Return the RSSI of the networks discovered during the scanNetworks
-     *
-     * param networkItem: specify from which network item want to get the information
-	 *
-     * return: signed value of RSSI of the specified item on the networks scanned list
-     */
-    static int32_t getRSSINetoworks(uint8_t networkItem);
-
-    /*
-     * Return the encryption type of the networks discovered during the scanNetworks
-     *
-     * param networkItem: specify from which network item want to get the information
-	 *
-     * return: encryption type (enum wl_enc_type) of the specified item on the networks scanned list
-     */
-    static uint8_t getEncTypeNetowrks(uint8_t networkItem);
-
-
-    /*
-     * Get the firmware version
-     */
-    static char* getFwVersion();
-
-
-	////////////////////////////////////////////////////////////////////////////
-	// Client/Server methods
-	////////////////////////////////////////////////////////////////////////////
-
-
-    static bool startServer(uint16_t port, uint8_t sock);
-    static bool startClient(const char* host, uint16_t port, uint8_t sock, uint8_t protMode);
-    static void stopClient(uint8_t sock);
-    static uint8_t getServerState(uint8_t sock);
-    static uint8_t getClientState(uint8_t sock);
-    static bool getData(uint8_t connId, uint8_t *data, bool peek, bool* connClose);
-    static int getDataBuf(uint8_t connId, uint8_t *buf, uint16_t bufSize);
-    static bool sendData(uint8_t sock, const uint8_t *data, uint16_t len);
-    static bool sendData(uint8_t sock, const __FlashStringHelper *data, uint16_t len, bool appendCrLf=false);
-	static bool sendDataUdp(uint8_t sock, const char* host, uint16_t port, const uint8_t *data, uint16_t len);
-    static uint16_t availData(uint8_t connId);
-
-
-	static bool ping(const char *host);
-    static void reset();
-
-    static void getRemoteIpAddress(IPAddress& ip);
-    static uint16_t getRemotePort();
-
-
-////////////////////////////////////////////////////////////////////////////////
-
-private:
-	static Stream *espSerial;
-
-	static long _bufPos;
-	static uint8_t _connId;
-
-	static uint16_t _remotePort;
-	static uint8_t  _remoteIp[WL_IPV4_LENGTH];
-
-
-	// firmware version string
-	static char 	fwVersion[WL_FW_VER_LENGTH];
-
-	// settings of requested network
-	static char 	_networkSsid[WL_NETWORKS_LIST_MAXNUM][WL_SSID_MAX_LENGTH];
-	static int32_t 	_networkRssi[WL_NETWORKS_LIST_MAXNUM];
-	static uint8_t 	_networkEncr[WL_NETWORKS_LIST_MAXNUM];
-
-
-	// settings of current selected network
-	static char 	_ssid[WL_SSID_MAX_LENGTH];
-	static uint8_t 	_bssid[WL_MAC_ADDR_LENGTH];
-	static uint8_t 	_mac[WL_MAC_ADDR_LENGTH];
-	static uint8_t  _localIp[WL_IPV4_LENGTH];
-
-
-	// the ring buffer is used to search the tags in the stream
-	static RingBuffer ringBuf;
-
-
-	//static int sendCmd(const char* cmd, int timeout=1000);
-	static int sendCmd(const __FlashStringHelper* cmd, int timeout=1000);
-	static int sendCmd(const __FlashStringHelper* cmd, int timeout, ...);
-
-	static bool sendCmdGet(const __FlashStringHelper* cmd, const char* startTag, const char* endTag, char* outStr, int outStrLen);
-	static bool sendCmdGet(const __FlashStringHelper* cmd, const __FlashStringHelper* startTag, const __FlashStringHelper* endTag, char* outStr, int outStrLen);
-
-	static int readUntil(int timeout, const char* tag=NULL, bool findTags=true);
-
-	static void espEmptyBuf(bool warn=true);
-
-	static int timedRead();
-
-
-	friend class WiFiEsp;
-	friend class WiFiEspServer;
-	friend class WiFiEspClient;
-	friend class WiFiEspUdp;
-};
-
-extern EspDrv espDrv;
-
-#endif

+ 0 - 105
lib/WiFiEsp/src/utility/RingBuffer.cpp

@@ -1,105 +0,0 @@
-/*--------------------------------------------------------------------
-This file is part of the Arduino WiFiEsp library.
-
-The Arduino WiFiEsp library is free software: you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation, either version 3 of the
-License, or (at your option) any later version.
-
-The Arduino WiFiEsp library is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with The Arduino WiFiEsp library.  If not, see
-<http://www.gnu.org/licenses/>.
---------------------------------------------------------------------*/
-
-#include "RingBuffer.h"
-
-#include <Arduino.h>
-
-RingBuffer::RingBuffer(unsigned int size)
-{
-	_size = size;
-	// add one char to terminate the string
-	ringBuf = new char[size+1];
-	ringBufEnd = &ringBuf[size];
-	init();
-}
-
-RingBuffer::~RingBuffer() {}
-
-void RingBuffer::reset()
-{
-	ringBufP = ringBuf;
-}
-
-void RingBuffer::init()
-{
-	ringBufP = ringBuf;
-	memset(ringBuf, 0, _size+1);
-}
-
-void RingBuffer::push(char c)
-{
-	*ringBufP = c;
-	ringBufP++;
-	if (ringBufP>=ringBufEnd)
-		ringBufP = ringBuf;
-}
-
-
-
-bool RingBuffer::endsWith(const char* str)
-{
-	int findStrLen = strlen(str);
-
-	// b is the start position into the ring buffer
-	char* b = ringBufP-findStrLen;
-	if(b < ringBuf)
-		b = b + _size;
-
-	char *p1 = (char*)&str[0];
-	char *p2 = p1 + findStrLen;
-
-	for(char *p=p1; p<p2; p++)
-	{
-		if(*p != *b)
-			return false;
-
-		b++;
-		if (b == ringBufEnd)
-			b=ringBuf;
-	}
-
-	return true;
-}
-
-
-
-void RingBuffer::getStr(char * destination, unsigned int skipChars)
-{
-	int len = ringBufP-ringBuf-skipChars;
-
-	// copy buffer to destination string
-	strncpy(destination, ringBuf, len);
-
-	// terminate output string
-	//destination[len]=0;
-}
-
-void RingBuffer::getStrN(char * destination, unsigned int skipChars, unsigned int num)
-{
-	int len = ringBufP-ringBuf-skipChars;
-
-	if (len>num)
-		len=num;
-
-	// copy buffer to destination string
-	strncpy(destination, ringBuf, len);
-
-	// terminate output string
-	//destination[len]=0;
-}

+ 0 - 47
lib/WiFiEsp/src/utility/RingBuffer.h

@@ -1,47 +0,0 @@
-/*--------------------------------------------------------------------
-This file is part of the Arduino WiFiEsp library.
-
-The Arduino WiFiEsp library is free software: you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation, either version 3 of the
-License, or (at your option) any later version.
-
-The Arduino WiFiEsp library is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with The Arduino WiFiEsp library.  If not, see
-<http://www.gnu.org/licenses/>.
---------------------------------------------------------------------*/
-
-#ifndef RingBuffer_h
-#define RingBuffer_h
-
-
-class RingBuffer
-{
-public:
-	RingBuffer(unsigned int size);
-	~RingBuffer();
-
-	void reset();
-	void init();
-	void push(char c);
-	int getPos();
-	bool endsWith(const char* str);
-	void getStr(char * destination, unsigned int skipChars);
-	void getStrN(char * destination, unsigned int skipChars, unsigned int num);
-
-
-private:
-
-	unsigned int _size;
-	char* ringBuf;
-	char* ringBufEnd;
-	char* ringBufP;
-
-};
-
-#endif

+ 0 - 49
lib/WiFiEsp/src/utility/debug.h

@@ -1,49 +0,0 @@
-/*--------------------------------------------------------------------
-This file is part of the Arduino WiFiEsp library.
-
-The Arduino WiFiEsp library is free software: you can redistribute it
-and/or modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation, either version 3 of the
-License, or (at your option) any later version.
-
-The Arduino WiFiEsp library is distributed in the hope that it will be
-useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with The Arduino WiFiEsp library.  If not, see
-<http://www.gnu.org/licenses/>.
---------------------------------------------------------------------*/
-
-#ifndef EspDebug_H
-#define EspDebug_H
-
-#include <stdio.h>
-
-// Change _ESPLOGLEVEL_ to set tracing and logging verbosity
-// 0: DISABLED: no logging
-// 1: ERROR: errors
-// 2: WARN: errors and warnings
-// 3: INFO: errors, warnings and informational (default)
-// 4: DEBUG: errors, warnings, informational and debug
-
-#ifndef _ESPLOGLEVEL_
-#define _ESPLOGLEVEL_ 3
-#endif
-
-
-#define LOGERROR(x)    if(_ESPLOGLEVEL_>0) { Serial.print("[WiFiEsp] "); Serial.println(x); }
-#define LOGERROR1(x,y) if(_ESPLOGLEVEL_>2) { Serial.print("[WiFiEsp] "); Serial.print(x); Serial.print(" "); Serial.println(y); }
-#define LOGWARN(x)     if(_ESPLOGLEVEL_>1) { Serial.print("[WiFiEsp] "); Serial.println(x); }
-#define LOGWARN1(x,y)  if(_ESPLOGLEVEL_>2) { Serial.print("[WiFiEsp] "); Serial.print(x); Serial.print(" "); Serial.println(y); }
-#define LOGINFO(x)     if(_ESPLOGLEVEL_>2) { Serial.print("[WiFiEsp] "); Serial.println(x); }
-#define LOGINFO1(x,y)  if(_ESPLOGLEVEL_>2) { Serial.print("[WiFiEsp] "); Serial.print(x); Serial.print(" "); Serial.println(y); }
-
-#define LOGDEBUG(x)      if(_ESPLOGLEVEL_>3) { Serial.println(x); }
-#define LOGDEBUG0(x)     if(_ESPLOGLEVEL_>3) { Serial.print(x); }
-#define LOGDEBUG1(x,y)   if(_ESPLOGLEVEL_>3) { Serial.print(x); Serial.print(" "); Serial.println(y); }
-#define LOGDEBUG2(x,y,z) if(_ESPLOGLEVEL_>3) { Serial.print(x); Serial.print(" "); Serial.print(y); Serial.print(" "); Serial.println(z); }
-
-
-#endif

+ 0 - 142
lib/WiFiEsp/test/BasicTest/BasicTest.ino

@@ -1,142 +0,0 @@
-/*
- WiFiEsp test: BasicTest
- 
- Performs basic connectivity test and checks.
-*/
-
-#include "WiFiEsp.h"
-
-// Emulate Serial1 on pins 7/6 if not present
-#ifndef HAVE_HWSERIAL1
-#include "SoftwareSerial.h"
-SoftwareSerial Serial1(6, 7); // RX, TX
-#endif
-
-
-char ssid[] = "Twim";     // your network SSID (name)
-char pwd[] = "12345678";  // your network password
-char pwdErr[] = "xxxx";   // wrong password
-
-
-void setup()
-{
-  Serial.begin(115200);
-  Serial1.begin(9600);
-  WiFi.init(&Serial1);
-}
-
-void loop()
-{
-  assertEquals("Firmware version", WiFi.firmwareVersion(), "1.5.2");
-  assertEquals("Status is (WL_DISCONNECTED)", WiFi.status(), WL_DISCONNECTED);
-  assertEquals("Connect", WiFi.begin(ssid, pwd), WL_CONNECTED);
-  assertEquals("Check status (WL_CONNECTED)", WiFi.status(), WL_CONNECTED);
-  assertEquals("Check SSID", WiFi.SSID(), ssid);
-
-  IPAddress ip = WiFi.localIP();
-  assertNotEquals("Check IP Address", ip[0], 0);
-  Serial.print("IP Address: ");
-  Serial.println(ip);
-  
-  byte mac[6]={0,0,0,0,0,0};
-  WiFi.macAddress(mac);
-
-  Serial.print("MAC: ");
-  Serial.print(mac[5], HEX);
-  Serial.print(":");
-  Serial.print(mac[4], HEX);
-  Serial.print(":");
-  Serial.print(mac[3], HEX);
-  Serial.print(":");
-  Serial.print(mac[2], HEX);
-  Serial.print(":");
-  Serial.print(mac[1], HEX);
-  Serial.print(":");
-  Serial.println(mac[0], HEX);
-  Serial.println();
-  
-  assertEquals("Disconnect", WiFi.disconnect(), WL_DISCONNECTED);
-  assertEquals("Check status (WL_DISCONNECTED)", WiFi.status(), WL_DISCONNECTED);
-  assertEquals("IP Address", WiFi.localIP(), 0);
-  assertEquals("Check SSID", WiFi.SSID(), "");
-  assertEquals("Wrong pwd", WiFi.begin(ssid, pwdErr), WL_CONNECT_FAILED);
-
-  IPAddress localIp(192, 168, 168, 111);
-  WiFi.config(localIp);
-  
-  assertEquals("Connect", WiFi.begin(ssid, pwd), WL_CONNECTED);
-  assertEquals("Check status (WL_CONNECTED)", WiFi.status(), WL_CONNECTED);
-
-  ip = WiFi.localIP();
-  assertNotEquals("Check IP Address", ip[0], 0);
-
-
-  Serial.println("END OF TESTS");
-  delay(60000);
-}
-
-
-////////////////////////////////////////////////////////////////////////////////////
-
-
-void assertNotEquals(const char* test, int actual, int expected)
-{
-  if(actual!=expected)
-    pass(test);
-  else
-    fail(test, actual, expected);
-}
-
-void assertEquals(const char* test, int actual, int expected)
-{
-  if(actual==expected)
-    pass(test);
-  else
-    fail(test, actual, expected);
-}
-
-void assertEquals(const char* test, char* actual, char* expected)
-{
-  if(strcmp(actual, expected) == 0)
-    pass(test);
-  else
-    fail(test, actual, expected);
-}
-
-
-void pass(const char* test)
-{
-  Serial.print(F("********************************************** "));
-  Serial.print(test);
-  Serial.println(" > PASSED");
-  Serial.println();
-}
-
-void fail(const char* test, char* actual, char* expected)
-{
-  Serial.print(F("********************************************** "));
-  Serial.print(test);
-  Serial.print(" > FAILED");
-  Serial.print(" (actual=\"");
-  Serial.print(actual);
-  Serial.print("\", expected=\"");
-  Serial.print(expected);
-  Serial.println("\")");
-  Serial.println();
-  delay(10000);
-}
-
-void fail(const char* test, int actual, int expected)
-{
-  Serial.print(F("********************************************** "));
-  Serial.print(test);
-  Serial.print(" > FAILED");
-  Serial.print(" (actual=");
-  Serial.print(actual);
-  Serial.print(", expected=");
-  Serial.print(expected);
-  Serial.println(")");
-  Serial.println();
-  delay(10000);
-}
-

+ 0 - 184
lib/WiFiEsp/test/ClientTest/ClientTest.ino

@@ -1,184 +0,0 @@
-/*
- WiFiEsp test: ClientTest
- 
- Test client functions.
-*/
-
-#include "WiFiEsp.h"
-
-// Emulate Serial1 on pins 7/6 if not present
-#ifndef HAVE_HWSERIAL1
-#include "SoftwareSerial.h"
-SoftwareSerial Serial1(6, 7); // RX, TX
-#endif
-
-
-char ssid[] = "Twim";     // your network SSID (name)
-char pwd[] = "12345678";  // your network password
-
-
-// Initialize the Wifi client library
-WiFiEspClient client;
-
-void setup()
-{
-  Serial.begin(115200);
-  Serial1.begin(9600);
-  WiFi.init(&Serial1);
-}
-
-void loop()
-{
-  bool f;
-  int c;
-
-  
-  assertEquals("Check status WL_DISCONNECTED", WiFi.status(), WL_DISCONNECTED);
-  
-  assertEquals("Connect", WiFi.begin(ssid, pwd), WL_CONNECTED);
-  
-  assertEquals("Check status WL_CONNECTED", WiFi.status(), WL_CONNECTED);
-  
-  IPAddress ip = WiFi.localIP();
-  Serial.print("IP Address: ");
-  Serial.println(ip);
-  
-  assertEquals("Ping", WiFi.ping("www.google.com"), true);
-  
-  assertEquals("Not connected", client.connected(), false);
-  assertEquals("Connect to server", client.connect("www.brainjar.com", 80), 1);
-  assertEquals("Connected", client.connected(), true);
-
-
-  //--------------------------------------------------------------
-  // HTTP request without 'Connection: close' command
-  
-  client.println("GET /java/host/test.html HTTP/1.1");
-  client.println("Host: www.brainjar.com");
-  client.println();
-
-  // wait for the response
-  long _startMillis = millis();
-  while (!client.available() and (millis()-_startMillis < 2000))
-  {
-  }
-  
-  assertEquals("Response received", (millis()-_startMillis < 2000), true);
-  
-  f = client.find("<html>");
-  assertEquals("Response check", f, true);
-  if (f)
-  {
-    while( (c = client.read()) > 0)
-      Serial.print((char)c);
-  }
-
-  assertEquals("Connected", client.connected(), true);
-
-
-  //--------------------------------------------------------------
-  
-  delay(5000);
-  
-  assertEquals("Check status WL_CONNECTED", WiFi.status(), WL_CONNECTED);
-
-  assertEquals("Connected", client.connected(), true);
-
-
-  //--------------------------------------------------------------
-  // HTTP request without 'Connection: close' command
-  
-  client.println("GET /java/host/test.html HTTP/1.1");
-  client.println("Host: www.brainjar.com");
-  client.println("Connection: close");
-  client.println();
-
-
-  // wait for the response
-  _startMillis = millis();
-  while (!client.available() and (millis()-_startMillis < 2000))
-  {
-  }
-  
-  assertEquals("Response received", (millis()-_startMillis < 2000), true);
-  
-  f = client.find("<html>");
-  assertEquals("Response check", f, true);
-  if (f)
-  {
-    while( (c = client.read()) > 0)
-      Serial.print((char)c);
-  }
-
-  //--------------------------------------------------------------
-  
-  assertEquals("Check status WL_CONNECTED", WiFi.status(), WL_CONNECTED);
-  assertEquals("Not connected", client.connected(), false);
-
-  assertEquals("Ping", WiFi.ping("www.google.com"), true);
-
-  assertEquals("Connect", WiFi.disconnect(), WL_DISCONNECTED);
-  assertEquals("Check status WL_DISCONNECTED", WiFi.status(), WL_DISCONNECTED);
-
-  Serial.println("END OF TESTS");
-  delay(30000);
-}
-
-
-////////////////////////////////////////////////////////////////////////////////////
-
-
-void assertEquals(const char* test, int actual, int expected)
-{
-  if(actual==expected)
-    pass(test);
-  else
-    fail(test, actual, expected);
-}
-
-void assertEquals(const char* test, char* actual, char* expected)
-{
-  if(strcmp(actual, expected) == 0)
-    pass(test);
-  else
-    fail(test, actual, expected);
-}
-
-
-void pass(const char* test)
-{
-  Serial.print(F("********************************************** "));
-  Serial.print(test);
-  Serial.println(" > PASSED");
-  Serial.println();
-}
-
-void fail(const char* test, char* actual, char* expected)
-{
-  Serial.print(F("********************************************** "));
-  Serial.print(test);
-  Serial.print(" > FAILED");
-  Serial.print(" (actual=\"");
-  Serial.print(actual);
-  Serial.print("\", expected=\"");
-  Serial.print(expected);
-  Serial.println("\")");
-  Serial.println();
-  delay(10000);
-}
-
-void fail(const char* test, int actual, int expected)
-{
-  Serial.print(F("********************************************** "));
-  Serial.print(test);
-  Serial.print(" > FAILED");
-  Serial.print(" (actual=");
-  Serial.print(actual);
-  Serial.print(", expected=");
-  Serial.print(expected);
-  Serial.println(")");
-  Serial.println();
-  delay(10000);
-}
-
-

+ 0 - 48
lib/WiFiEsp/test/EspDebug/EspDebug.ino

@@ -1,48 +0,0 @@
-// EspDebug - Test sketch for ESP8266 module
-
-#include "Arduino.h"
-
-// Emulate Serial1 on pins 7/6 if not present
-#ifndef HAVE_HWSERIAL1
-#include "SoftwareSerial.h"
-SoftwareSerial Serial1(6, 7); // RX, TX
-#endif
-
-void setup()
-{
-  Serial.begin(115200); // serial port used for debugging
-  Serial1.begin(9600);  // your ESP's baud rate might be different
-}
- 
-void loop()
-{
-  if(Serial1.available())  // check if the ESP is sending a message
-  {
-    while(Serial1.available())
-    {
-      int c = Serial1.read(); // read the next character
-      Serial.write((char)c);  // writes data to the serial monitor
-    }
-  }
- 
-  if(Serial.available())
-  {
-    // wait to let all the input command in the serial buffer
-    delay(10);
-
-    // read the input command in a string
-    String cmd = "";
-    while(Serial.available())
-    {
-      cmd += (char)Serial.read();
-    }
-
-    // print the command and send it to the ESP
-    Serial.println();
-    Serial.print(">>>> ");
-    Serial.println(cmd);
-
-    // send the read character to the ESP
-    Serial1.print(cmd);
-  }
-}

+ 0 - 58
lib/WiFiEsp/test/RingBufferTest/RingBufferTest.ino

@@ -1,58 +0,0 @@
-/*
- WiFiEsp test: RingBufferTest
- 
- Test of the RingBuffer class.
-*/
-
-#include "WiFiEsp.h"
-
-RingBuffer buf(5);
-
-
-void setup()
-{
-  Serial.begin(115200);
-  
-  Serial.println("Starting tests");
-
-  buf.init();
-
-  buf.push('a');
-  assert(10, buf.endsWith("a"), true);
-  assert(11, buf.endsWith("A"), false);
-  assert(12, buf.endsWith("ab"), false);
-
-  buf.push('b');
-  assert(21, buf.endsWith("a"), false);
-  assert(22, buf.endsWith("A"), false);
-  assert(23, buf.endsWith("ab"), true);
-
-  buf.push('c');
-  buf.push('d');
-  buf.push('e');
-  assert(31, buf.endsWith("abcde"), true);
-  assert(32, buf.endsWith("de"), true);
-
-  buf.push('f');
-  assert(43, buf.endsWith("bcdef"), true);
-  assert(44, buf.endsWith("ef"), true);
-
-  Serial.println("Done");
-}
-
-
-void loop()
-{
-  // nothing to do
-}
-
-
-void assert(int i, bool x, bool y)
-{
-  if (x!=y)
-  {
-    Serial.print ("FAIL ");
-    Serial.println(i);
-  }
-}
-

+ 12 - 0
lib/WiFiManager-development/.github/CONTRIBUTING.md

@@ -0,0 +1,12 @@
+## Contributing PRs and ISSUES
+
+The development branch is the active branch, no features or bugs will be fixed against master ( hotfixes may be considered ).
+
+Please test against development branch before submitting issues, issues against master will be closed, 
+
+PRs against master may be kept open if provides something useful to other members.
+
+Please open issues before sumbitting PRs against development, as commits might be occuring very frequently.
+
+### Documentation is in progress
+https://github.com/tzapu/WiFiManager/issues/500

+ 56 - 0
lib/WiFiManager-development/.github/ISSUE_TEMPLATE.md

@@ -0,0 +1,56 @@
+## PLEASE TRY DEVELOPMENT BRANCH before submitting bugs on release or master, in case they were already fixed. ##
+
+Issues without basic info will be ignored or closed!
+
+Please fill the info fields, it helps to get you faster support ;)
+
+if you have a stack dump decode it:
+https://github.com/esp8266/Arduino/blob/master/doc/Troubleshooting/stack_dump.rst
+
+for better debug messages:
+https://github.com/esp8266/Arduino/blob/master/doc/Troubleshooting/debugging.rst
+
+----------------------------- Remove above -----------------------------
+
+### Basic Infos
+
+#### Hardware
+WiFimanager Branch/Release:  Development
+
+Esp8266/Esp32: 
+
+Hardware:			ESP-12e, esp01, esp25
+
+Core Version:      	2.4.0, staging
+
+### Description
+
+Problem description
+
+### Settings in IDE
+
+Module:  			NodeMcu, Wemos D1
+
+Additional libraries: 
+
+### Sketch
+
+```cpp
+
+#include <Arduino.h>
+
+void setup() {
+
+}
+
+void loop() {
+
+}
+```
+
+### Debug Messages
+
+```
+messages here
+```
+

+ 1 - 0
lib/WiFiManager-development/.gitignore

@@ -0,0 +1 @@
+platformio.ini

+ 53 - 0
lib/WiFiManager-development/.travis.yml

@@ -0,0 +1,53 @@
+language: c
+sudo: false
+
+before_install:
+  - "/sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -ac -screen 0 1280x1024x16"
+  - sleep 3
+  - export DISPLAY=:1.0
+  - wget http://downloads.arduino.cc/arduino-1.8.10-linux64.tar.xz
+  - tar xf arduino-1.8.10-linux64.tar.xz
+  - sudo mv arduino-1.8.10 /usr/local/share/arduino
+  - sudo ln -s /usr/local/share/arduino/arduino /usr/local/bin/arduino
+
+install:
+  - ln -s $PWD /usr/local/share/arduino/libraries/WiFiManager
+  - arduino --pref "boardsmanager.additional.urls=http://arduino.esp8266.com/stable/package_esp8266com_index.json,http://dl.espressif.com/dl/package_esp32_index.json" --save-prefs
+  - arduino --install-library "ArduinoJson:5.13.2"
+  - arduino --install-boards esp8266:esp8266
+  - arduino --pref "compiler.warning_level=all" --save-prefs
+# install esp32
+  - arduino --install-boards esp32:esp32
+  # - pushd .
+  # - mkdir -p ~/Arduino/hardware/espressif
+  # - cd ~/Arduino/hardware/espressif
+  # - git clone https://github.com/espressif/arduino-esp32.git esp32
+  # - cd esp32
+  # - git submodule update --init --recursive
+  # - cd tools
+  # - python2 get.py
+  # - popd
+# esp32 needs WebServer_tng for now
+  # - git clone https://github.com/bbx10/WebServer_tng.git /usr/local/share/arduino/libraries/WebServer_tng
+
+script:
+  - "echo $PWD"
+  - "echo $HOME"
+  - "ls $PWD"
+  - source $TRAVIS_BUILD_DIR/travis/common.sh
+  - arduino --board esp8266:esp8266:generic:xtal=80,eesz=4M1M,FlashMode=qio,FlashFreq=80,dbg=Serial,lvl=CORE --save-prefs
+  - build_examples
+  - arduino --board esp32:esp32:esp32:FlashFreq=80,FlashSize=4M,DebugLevel=info --save-prefs
+# some examples fail (SPIFFS defines differ esp32 vs esp8266) so we exclude them
+  - build_examples
+#  - arduino -v --verbose-build --verify $PWD/examples/AutoConnect/AutoConnect.ino
+
+# no coverage generated, no need to run
+#
+#after_success:
+#  - bash <(curl -s https://codecov.io/bash)
+
+notifications:
+  email:
+    on_success: change
+    on_failure: change

+ 3 - 2
LICENSE → lib/WiFiManager-development/LICENSE

@@ -1,6 +1,6 @@
-MIT License
+The MIT License (MIT)
 
-Copyright (c) 2016-2020 M. Westenberg / Things4U
+Copyright (c) 2015 tzapu
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
@@ -19,3 +19,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
+

+ 552 - 0
lib/WiFiManager-development/README.md

@@ -0,0 +1,552 @@
+
+# WiFiManager
+ESP8266 WiFi Connection manager with fallback web configuration portal
+
+[![Build Status](https://travis-ci.org/tzapu/WiFiManager.svg?branch=development)](https://travis-ci.org/tzapu/WiFiManager)
+
+![ESP8266](https://img.shields.io/badge/ESP-8266-000000.svg?longCache=true&style=flat&colorA=CC101F)
+![ESP32](https://img.shields.io/badge/ESP-32-000000.svg?longCache=true&style=flat&colorA=CC101F)
+
+The configuration portal is of the captive variety, so on various devices it will present the configuration dialogue as soon as you connect to the created access point.
+
+First attempt at a library. Lots more changes and fixes to do. Contributions are welcome.
+
+**This works with the ESP8266 Arduino platform with a recent stable release(2.0.0 or newer)**
+
+[https://github.com/esp8266/Arduino](https://github.com/esp8266/Arduino)
+
+**This works with the ESP32 Arduino platform with staging** 
+
+[https://github.com/espressif/arduino-esp32](https://github.com/espressif/arduino-esp32)
+
+### Known Issues
+* Documentation needs to be updated, see [https://github.com/tzapu/WiFiManager/issues/500](https://github.com/tzapu/WiFiManager/issues/500)
+
+## Contents
+ - [How it works](#how-it-works)
+ - [Wishlist](#wishlist)
+ - [Quick start](#quick-start)
+   - Installing
+     - [Arduino - Through Library Manager](#install-through-library-manager)
+     - [Arduino - From Github](#checkout-from-github)
+     - [PlatformIO](#install-using-platformio)
+   - [Using](#using)
+ - [Documentation](#documentation)
+   - [Access Point Password](#password-protect-the-configuration-access-point)
+   - [Callbacks](#callbacks)
+   - [Configuration Portal Timeout](#configuration-portal-timeout)
+   - [On Demand Configuration](#on-demand-configuration-portal)
+   - [Custom Parameters](#custom-parameters)
+   - [Custom IP Configuration](#custom-ip-configuration)
+   - [Filter Low Quality Networks](#filter-networks)
+   - [Debug Output](#debug)
+ - [Troubleshooting](#troubleshooting)
+ - [Releases](#releases)
+ - [Contributors](#contributions-and-thanks)
+
+
+## How It Works
+- When your ESP starts up, it sets it up in Station mode and tries to connect to a previously saved Access Point
+- if this is unsuccessful (or no previous network saved) it moves the ESP into Access Point mode and spins up a DNS and WebServer (default ip 192.168.4.1)
+- using any wifi enabled device with a browser (computer, phone, tablet) connect to the newly created Access Point
+- because of the Captive Portal and the DNS server you will either get a 'Join to network' type of popup or get any domain you try to access redirected to the configuration portal
+- choose one of the access points scanned, enter password, click save
+- ESP will try to connect. If successful, it relinquishes control back to your app. If not, reconnect to AP and reconfigure.
+- There are options to change this behavior or manually start the configportal and webportal independantly as well as run them in non blocking mode.
+
+## How It Looks
+![ESP8266 WiFi Captive Portal Homepage](http://i.imgur.com/YPvW9eql.png) ![ESP8266 WiFi Captive Portal Configuration](http://i.imgur.com/oicWJ4gl.png)
+
+## Wishlist
+- [x] remove dependency on EEPROM library
+- [x] move HTML Strings to PROGMEM
+- [x] cleanup and streamline code (although this is ongoing)
+- [x] if timeout is set, extend it when a page is fetched in AP mode
+- [x] add ability to configure more parameters than ssid/password
+- [x] maybe allow setting ip of ESP after reboot
+- [x] add to Arduino Library Manager
+- [x] add to PlatformIO
+- [ ] add multiple sets of network credentials
+- [x] allow users to customize CSS
+- [ ] rewrite documentation for simplicity, based on scenarios/goals
+
+### Development
+- [x] ESP32 support
+- [x] rely on the SDK's built in auto connect more than forcing a connect
+- [x] add non blocking mode
+- [x] easy customization of strings
+- [x] hostname support
+- [x] fix various bugs and workarounds for esp SDK issues
+- [x] additional info page items
+- [x] last status display / faiilure reason
+- [x] customizeable menu
+- [x] seperate custom params page
+- [x] ondemand webportal
+- [x] complete refactor of code to segment functions
+- [x] wiif scan icons or percentage display
+- [x] invert class for dark mode
+- [x] more template tokens
+- [x] progmem for all strings
+- [ ] new callbacks
+- [ ] new callouts / filters
+- [ ] shared web server instance
+- [x] latest esp idf/sdk support
+- [x] wm is now non persistent, will not erase or change stored esp config on esp8266
+- [x] tons of debugging output / levels
+- [ ] disable captiveportal
+- [ ] preload wiifscans, faster page loads
+- [ ] softap stability fixes when sta is not connected
+
+
+## Quick Start
+
+### Installing
+You can either install through the Arduino Library Manager or checkout the latest changes or a release from github
+
+#### Install through Library Manager
+__Currently version 0.8+ works with release 2.4.0 or newer of the [ESP8266 core for Arduino](https://github.com/esp8266/Arduino)__
+ - in Arduino IDE got to Sketch/Include Library/Manage Libraries
+  ![Manage Libraries](http://i.imgur.com/9BkEBkR.png)
+
+ - search for WiFiManager
+  ![WiFiManager package](http://i.imgur.com/18yIai8.png)
+
+ - click Install and start [using it](#using)
+
+####  Checkout from github
+__Github version works with release 2.4.0 or newer of the [ESP8266 core for Arduino](https://github.com/esp8266/Arduino)__
+- Checkout library to your Arduino libraries folder
+
+### Using
+- Include in your sketch
+```cpp
+#include <WiFiManager.h>          //https://github.com/tzapu/WiFiManager WiFi Configuration Magic
+```
+
+- Initialize library, in your setup function add, NOTEif you are using non blocking you will make sure you create this in global scope or handle appropriatly , it will not work if in setup and using non blocking mode.
+```cpp
+WiFiManager wifiManager;
+```
+
+- Also in the setup function add
+```cpp
+//first parameter is name of access point, second is the password
+wifiManager.autoConnect("AP-NAME", "AP-PASSWORD");
+```
+if you just want an unsecured access point
+```cpp
+wifiManager.autoConnect("AP-NAME");
+```
+or if you want to use and auto generated name from 'ESP' and the esp's Chip ID use
+```cpp
+wifiManager.autoConnect();
+```
+
+After you write your sketch and start the ESP, it will try to connect to WiFi. If it fails it starts in Access Point mode.
+While in AP mode, connect to it then open a browser to the gateway IP, default 192.168.4.1, configure wifi, save and it should reboot and connect.
+
+Also see [examples](https://github.com/tzapu/WiFiManager/tree/master/examples).
+
+#### Install Using PlatformIO
+
+[PlatformIO](https://platformio.org/) is an emerging ecosystem for IoT development, and 
+is an alternative to using the Arduino IDE. Install `WiFiManager`
+using the platformio [library manager](https://docs.platformio.org/en/latest/librarymanager/index.htm) in your editor, 
+or using the [PlatformIO Core CLI](https://docs.platformio.org/en/latest/userguide/demo.html#library-manager),
+or by adding it to your `platformio.ini` as shown below (recommended approach).
+
+The simplest way is to open the `platformio.ini` file at the root of your project, and `WifiManager` to the common top-level env
+`lib_deps` key like so:
+
+```
+[env]
+lib_deps =
+	WiFiManager
+```
+
+If you want to install the development branch, then you'll need to use the `repository#tag` format instead:
+
+```
+[env]
+lib_deps =
+	https://github.com/tzapu/WiFiManager.git#development
+```
+
+## Documentation
+
+#### Password protect the configuration Access Point
+You can and should password protect the configuration access point.  Simply add the password as a second parameter to `autoConnect`.
+A short password seems to have unpredictable results so use one that's around 8 characters or more in length.
+The guidelines are that a wifi password must consist of 8 to 63 ASCII-encoded characters in the range of 32 to 126 (decimal)
+```cpp
+wifiManager.autoConnect("AutoConnectAP", "password")
+```
+
+#### Callbacks
+##### Enter Config mode
+Use this if you need to do something when your device enters configuration mode on failed WiFi connection attempt.
+Before `autoConnect()`
+```cpp
+wifiManager.setAPCallback(configModeCallback);
+```
+`configModeCallback` declaration and example
+```cpp
+void configModeCallback (WiFiManager *myWiFiManager) {
+  Serial.println("Entered config mode");
+  Serial.println(WiFi.softAPIP());
+
+  Serial.println(myWiFiManager->getConfigPortalSSID());
+}
+```
+
+##### Save settings
+This gets called when custom parameters have been set **AND** a connection has been established. Use it to set a flag, so when all the configuration finishes, you can save the extra parameters somewhere.
+
+See [AutoConnectWithFSParameters Example](https://github.com/tzapu/WiFiManager/tree/master/examples/AutoConnectWithFSParameters).
+```cpp
+wifiManager.setSaveConfigCallback(saveConfigCallback);
+```
+`saveConfigCallback` declaration and example
+```cpp
+//flag for saving data
+bool shouldSaveConfig = false;
+
+//callback notifying us of the need to save config
+void saveConfigCallback () {
+  Serial.println("Should save config");
+  shouldSaveConfig = true;
+}
+```
+
+#### Configuration Portal Timeout
+If you need to set a timeout so the ESP doesn't hang waiting to be configured, for instance after a power failure, you can add
+```cpp
+wifiManager.setConfigPortalTimeout(180);
+```
+which will wait 3 minutes (180 seconds). When the time passes, the autoConnect function will return, no matter the outcome.
+Check for connection and if it's still not established do whatever is needed (on some modules I restart them to retry, on others I enter deep sleep)
+
+#### On Demand Configuration Portal
+If you would rather start the configuration portal on demand rather than automatically on a failed connection attempt, then this is for you.
+
+Instead of calling `autoConnect()` which does all the connecting and failover configuration portal setup for you, you need to use `startConfigPortal()`. __Do not use BOTH.__
+
+Example usage
+```cpp
+void loop() {
+  // is configuration portal requested?
+  if ( digitalRead(TRIGGER_PIN) == LOW ) {
+    WiFiManager wifiManager;
+    wifiManager.startConfigPortal("OnDemandAP");
+    Serial.println("connected...yeey :)");
+  }
+}
+```
+See example for a more complex version. [OnDemandConfigPortal](https://github.com/tzapu/WiFiManager/tree/master/examples/OnDemandConfigPortal)
+
+#### Exiting from the Configuration Portal
+Normally, once entered, the configuration portal will continue to loop until WiFi credentials have been successfully entered or a timeout is reached.
+If you'd prefer to exit without joining a WiFi network, say becuase you're going to put the ESP into AP mode, then press the "Exit" button
+on the main webpage.
+If started via `autoConnect` or `startConfigPortal` then it will return `false (portalAbortResult)`
+
+#### Custom Parameters
+You can use WiFiManager to collect more parameters than just SSID and password.
+This could be helpful for configuring stuff like MQTT host and port, [blynk](http://www.blynk.cc) or [emoncms](http://emoncms.org) tokens, just to name a few.
+**You are responsible for saving and loading these custom values.** The library just collects and displays the data for you as a convenience.
+Usage scenario would be:
+- load values from somewhere (EEPROM/FS) or generate some defaults
+- add the custom parameters to WiFiManager using
+```cpp
+ // id/name, placeholder/prompt, default, length
+ WiFiManagerParameter custom_mqtt_server("server", "mqtt server", mqtt_server, 40);
+ wifiManager.addParameter(&custom_mqtt_server);
+
+```
+- if connection to AP fails, configuration portal starts and you can set /change the values (or use on demand configuration portal)
+- once configuration is done and connection is established [save config callback]() is called
+- once WiFiManager returns control to your application, read and save the new values using the `WiFiManagerParameter` object.
+```cpp
+ mqtt_server = custom_mqtt_server.getValue();
+```  
+This feature is a lot more involved than all the others, so here are some examples to fully show how it is done.
+You should also take a look at adding custom HTML to your form.
+
+- Save and load custom parameters to file system in json form [AutoConnectWithFSParameters](https://github.com/tzapu/WiFiManager/tree/master/examples/AutoConnectWithFSParameters)
+- *Save and load custom parameters to EEPROM* (not done yet)
+
+#### Custom IP Configuration
+You can set a custom IP for both AP (access point, config mode) and STA (station mode, client mode, normal project state)
+
+##### Custom Access Point IP Configuration
+This will set your captive portal to a specific IP should you need/want such a feature. Add the following snippet before `autoConnect()`
+```cpp
+//set custom ip for portal
+wifiManager.setAPStaticIPConfig(IPAddress(10,0,1,1), IPAddress(10,0,1,1), IPAddress(255,255,255,0));
+```
+
+##### Custom Station (client) Static IP Configuration
+This will make use the specified IP configuration instead of using DHCP in station mode.
+```cpp
+wifiManager.setSTAStaticIPConfig(IPAddress(192,168,0,99), IPAddress(192,168,0,1), IPAddress(255,255,255,0)); // optional DNS 4th argument
+```
+There are a couple of examples in the examples folder that show you how to set a static IP and even how to configure it through the web configuration portal.
+
+#### Custom HTML, CSS, Javascript
+There are various ways in which you can inject custom HTML, CSS or Javascript into the configuration portal.
+The options are:
+- inject custom head element
+You can use this to any html bit to the head of the configuration portal. If you add a `<style>` element, bare in mind it overwrites the included css, not replaces.
+```cpp
+wifiManager.setCustomHeadElement("<style>html{filter: invert(100%); -webkit-filter: invert(100%);}</style>");
+```
+- inject a custom bit of html in the configuration/param form
+```cpp
+WiFiManagerParameter custom_text("<p>This is just a text paragraph</p>");
+wifiManager.addParameter(&custom_text);
+```
+- inject a custom bit of html in a configuration form element
+Just add the bit you want added as the last parameter to the custom parameter constructor.
+```cpp
+WiFiManagerParameter custom_mqtt_server("server", "mqtt server", "iot.eclipse", 40, " readonly");
+wifiManager.addParameter(&custom_mqtt_server);
+```
+
+#### Theming
+You can customize certain elements of the default template with some builtin classes
+```CPP
+wifiManager.setClass("invert"); // dark theme
+wifiManager.setScanDispPerc(true); // display percentages instead of graphs for RSSI
+```
+There are additional classes in the css you can use in your custom html , see the example template.
+
+#### Filter Networks
+You can filter networks based on signal quality and show/hide duplicate networks.
+
+- If you would like to filter low signal quality networks you can tell WiFiManager to not show networks below an arbitrary quality %;
+```cpp
+wifiManager.setMinimumSignalQuality(10);
+```
+will not show networks under 10% signal quality. If you omit the parameter it defaults to 8%;
+
+- You can also remove or show duplicate networks (default is remove).
+Use this function to show (or hide) all networks.
+```cpp
+wifiManager.setRemoveDuplicateAPs(false);
+```
+
+#### Debug
+Debug is enabled by default on `Serial` in non-stable releases. To disable add before autoConnect/startConfigPortal
+```cpp
+wifiManager.setDebugOutput(false);
+```
+
+You can pass in a custom stream via constructor 
+```CPP
+WiFiManager wifiManager(Serial1);
+```
+
+You can customize the debug level by changing `_debugLevel` in source
+options are:
+* DEBUG_ERROR
+* DEBUG_NOTIFY
+* DEBUG_VERBOSE
+* DEBUG_DEV
+* DEBUG_MAX
+
+## Troubleshooting
+If you get compilation errors, more often than not, you may need to install a newer version of the ESP8266 core for Arduino.
+
+Changes added on 0.8 should make the latest trunk work without compilation errors. Tested down to ESP8266 core 2.0.0. **Please update to version 0.8**
+
+I am trying to keep releases working with release versions of the core, so they can be installed through boards manager, but if you checkout the latest version directly from github, sometimes, the library will only work if you update the ESP8266 core to the latest version because I am using some newly added function.
+
+If you connect to the created configuration Access Point but the configuration portal does not show up, just open a browser and type in the IP of the web portal, by default `192.168.4.1`.
+
+If trying to connect ends up in an endless loop, try to add `setConnectTimeout(60)` before `autoConnect();`. The parameter is timeout to try connecting in seconds.
+
+I get stuck in ap mode when the power goes out or modem resets, try a setConfigPortalTimeout(seconds). This will cause the configportal to close after no activity, and you can reboot or attempt reconnection in your code.
+
+## Releases
+### 1.0.1
+
+### Development Overview
+
+#### Added Public Methods
+`setConfigPortalBlocking`
+
+`setShowStaticFields`
+
+`setCaptivePortalEnable`
+
+`setRestorePersistent`
+
+`setCaptivePortalClientCheck`
+
+`setWebPortalClientCheck`
+
+`startWebPortal`
+
+`stopWebPortal`
+
+`process`
+
+`disconnect`
+
+`erase`
+
+` debugSoftAPConfig`
+
+` debugPlatformInfo`
+
+`setScanDispPerc`
+
+`setHostname`
+
+`setMenu(menu_page_t[])`
+
+`setWiFiAutoReconnect`
+
+` setSTAStaticIPConfig(..,dns)`
+
+`setShowDnsFields`
+
+`getLastConxResult`
+
+`getWLStatusString`
+
+`getModeString`
+
+`getWiFiIsSaved`
+
+`setShowInfoErase`
+
+`setEnableConfigPortal`
+
+`setCountry`
+
+`setClass`
+
+`htmleEtities`
+
+
+#### WiFiManagerParameter
+`WiFiManagerParameter(id,label)`
+
+`WiFiManagerParameter.setValue(value,length)`
+
+`getParameters`
+
+`getParametersCount`
+
+
+#### Constructors
+`WiFiManager(Stream& consolePort)`
+
+#### define flags
+❗️  **Defines cannot be set in user sketches**
+`#define WM_MDNS       // use MDNS`
+
+`#define WM_FIXERASECONFIG // use erase flash fix, esp8266 2.4.0`
+
+`#define WM_ERASE_NVS // esp32 erase(true) will erase NVS`
+
+`#include <rom/rtc.h> // esp32 info page will show last reset reasons if this file is included`
+
+#### Changes Overview
+- ESP32 support ( fairly stable )
+- complete refactor of strings `strings_en.h`
+- adds new tokens for wifiscan, and some classes (left , invert icons, MSG color)
+- adds status callout panel default, primary, special colors
+-  adds tons of info on info page, and erase capability
+- adds signal icons, replaces percentage ( has hover titles )
+- adds labels to all inputs (replaces placeholders)
+- all html ( and eventually all strings except debug) moved to `strings_en.h`
+- added additional debugging, compressed debug lines, debuglevels
+- persistent disabled, and restored via de/con-stuctor (uses `setRestorePersistent`)
+- should retain all user modes including AP, should not overwrite or persist user modes or configs,even STA (`storeSTAmode`) (BUGGY)
+- ⚠️ return values may have changed depending on portal abort, or timeout ( `portalTimeoutResult`,`portalAbortResult`)
+- params memory is auto allocated by increment of `WIFI_MANAGER_MAX_PARAMS(5)` when exceeded, user no longer needs to specify this at all.
+- addparameter now returns bool, and it returns false if param ID is not alphanum [0-9,A-Z,a-z,_]
+- param field ids allow {I} token to use param_n instead of string in case someones wants to change this due to i18n or character issues
+- provides `#DEFINE FIXERASECONFIG` to help deal with https://github.com/esp8266/Arduino/pull/3635
+- failure reason reporting on portal
+- set esp8266 sta hostname, esp32 sta+ap hostname ( DHCP client id)
+- pass in debug stream in constructor WiFiManager(Stream& consolePort)
+- you can force ip fields off with showxfields(false) if you set _disableIpFields=true
+- param menu/page (setup) added to separate params from wifi page, handled automatically by setMenu
+- set custom root menu
+- disable configportal on autoconnect
+- wm parameters init is now protected, allowing child classes, example included
+- wifiscans are precached and async for faster page loads, refresh forces rescan
+- adds esp32 gettemperature ( currently commented out, useful for relative measurement only )
+
+#### 0.12
+- removed 204 header response
+- fixed incompatibility with other libs using isnan and other std:: functions without namespace
+
+##### 0.11
+- a lot more reliable reconnecting to networks
+- custom html in custom parameters (for read only params)
+- custom html in custom parameter form (like labels)
+- custom head element (like custom css)
+- sort networks based on signal quality
+- remove duplicate networks
+
+##### 0.10
+- some css changes
+- bug fixes and speed improvements
+- added an alternative to waitForConnectResult() for debugging
+- changed `setTimeout(seconds)` to `setConfigPortalTimeout(seconds)`
+
+### Contributions and thanks
+The support and help I got from the community has been nothing short of phenomenal. I can't thank you guys enough. This is my first real attept in developing open source stuff and I must say, now I understand why people are so dedicated to it, it is because of all the wonderful people involved.
+
+__THANK YOU__
+
+The esp8266 and esp32 arduino and idf maintainers!
+
+[Shawn A aka tablatronix](https://github.com/tablatronix)
+
+[liebman](https://github.com/liebman)
+
+[Evgeny Dontsov](https://github.com/dontsovcmc)
+
+[Chris Marrin](https://github.com/cmarrin)
+
+[bbx10](https://github.com/bbx10)
+
+[kentaylor](https://github.com/kentaylor)
+
+[Maximiliano Duarte](https://github.com/domonetic)
+
+[alltheblinkythings](https://github.com/alltheblinkythings)
+
+[Niklas Wall](https://github.com/niklaswall)
+
+[Jakub Piasecki](https://github.com/zaporylie)
+
+[Peter Allan](https://github.com/alwynallan)
+
+[John Little](https://github.com/j0hnlittle)
+
+[markaswift](https://github.com/markaswift)
+
+[franklinvv](https://github.com/franklinvv)
+
+[Alberto Ricci Bitti](https://github.com/riccibitti)
+
+[SebiPanther](https://github.com/SebiPanther)
+
+[jonathanendersby](https://github.com/jonathanendersby)
+
+[walthercarsten](https://github.com/walthercarsten)
+
+And countless others
+
+#### Inspiration
+ * http://www.esp8266.com/viewtopic.php?f=29&t=2520
+ * https://github.com/chriscook8/esp-arduino-apboot
+ * https://github.com/esp8266/Arduino/tree/master/libraries/DNSServer/examples/CaptivePortalAdvanced
+ * Built by AlexT https://github.com/tzapu
+

+ 2906 - 0
lib/WiFiManager-development/WiFiManager.cpp

@@ -0,0 +1,2906 @@
+/**
+ * WiFiManager.cpp
+ * 
+ * WiFiManager, a library for the ESP8266/Arduino platform
+ * for configuration of WiFi credentials using a Captive Portal
+ * 
+ * @author Creator tzapu
+ * @author tablatronix
+ * @version 0.0.0
+ * @license MIT
+ */
+
+#include "WiFiManager.h"
+
+#if defined(ESP8266) || defined(ESP32)
+
+#ifdef ESP32
+uint8_t WiFiManager::_lastconxresulttmp = WL_IDLE_STATUS;
+#endif
+
+/**
+ * --------------------------------------------------------------------------------
+ *  WiFiManagerParameter
+ * --------------------------------------------------------------------------------
+**/
+
+WiFiManagerParameter::WiFiManagerParameter() {
+  WiFiManagerParameter("");
+}
+
+WiFiManagerParameter::WiFiManagerParameter(const char *custom) {
+  _id             = NULL;
+  _label          = NULL;
+  _length         = 1;
+  _value          = NULL;
+  _labelPlacement = WFM_LABEL_BEFORE;
+  _customHTML     = custom;
+}
+
+WiFiManagerParameter::WiFiManagerParameter(const char *id, const char *label) {
+  init(id, label, "", 0, "", WFM_LABEL_BEFORE);
+}
+
+WiFiManagerParameter::WiFiManagerParameter(const char *id, const char *label, const char *defaultValue, int length) {
+  init(id, label, defaultValue, length, "", WFM_LABEL_BEFORE);
+}
+
+WiFiManagerParameter::WiFiManagerParameter(const char *id, const char *label, const char *defaultValue, int length, const char *custom) {
+  init(id, label, defaultValue, length, custom, WFM_LABEL_BEFORE);
+}
+
+WiFiManagerParameter::WiFiManagerParameter(const char *id, const char *label, const char *defaultValue, int length, const char *custom, int labelPlacement) {
+  init(id, label, defaultValue, length, custom, labelPlacement);
+}
+
+void WiFiManagerParameter::init(const char *id, const char *label, const char *defaultValue, int length, const char *custom, int labelPlacement) {
+  _id             = id;
+  _label          = label;
+  _labelPlacement = labelPlacement;
+  _customHTML     = custom;
+  setValue(defaultValue,length);
+}
+
+WiFiManagerParameter::~WiFiManagerParameter() {
+  if (_value != NULL) {
+    delete[] _value;
+  }
+  _length=0; // setting length 0, ideally the entire parameter should be removed, or added to wifimanager scope so it follows
+}
+
+// @note debug is not available in wmparameter class
+void WiFiManagerParameter::setValue(const char *defaultValue, int length) {
+  if(!_id){
+    // Serial.println("cannot set value of this parameter");
+    return;
+  }
+  
+  // if(strlen(defaultValue) > length){
+  //   // Serial.println("defaultValue length mismatch");
+  //   // return false; //@todo bail 
+  // }
+
+  _length = length;
+  _value  = new char[_length + 1]; 
+  memset(_value, 0, _length + 1); // explicit null
+  
+  if (defaultValue != NULL) {
+    strncpy(_value, defaultValue, _length);
+  }
+}
+const char* WiFiManagerParameter::getValue() {
+  return _value;
+}
+const char* WiFiManagerParameter::getID() {
+  return _id;
+}
+const char* WiFiManagerParameter::getPlaceholder() {
+  return _label;
+}
+const char* WiFiManagerParameter::getLabel() {
+  return _label;
+}
+int WiFiManagerParameter::getValueLength() {
+  return _length;
+}
+int WiFiManagerParameter::getLabelPlacement() {
+  return _labelPlacement;
+}
+const char* WiFiManagerParameter::getCustomHTML() {
+  return _customHTML;
+}
+
+/**
+ * [addParameter description]
+ * @access public
+ * @param {[type]} WiFiManagerParameter *p [description]
+ */
+bool WiFiManager::addParameter(WiFiManagerParameter *p) {
+
+  // check param id is valid, unless null
+  if(p->getID()){
+    for (size_t i = 0; i < strlen(p->getID()); i++){
+       if(!(isAlphaNumeric(p->getID()[i])) && !(p->getID()[i]=='_')){
+        DEBUG_WM(DEBUG_ERROR,"[ERROR] parameter IDs can only contain alpha numeric chars");
+        return false;
+       }
+    }
+  }
+
+  // init params if never malloc
+  if(_params == NULL){
+    DEBUG_WM(DEBUG_DEV,"allocating params bytes:",_max_params * sizeof(WiFiManagerParameter*));        
+    _params = (WiFiManagerParameter**)malloc(_max_params * sizeof(WiFiManagerParameter*));
+  }
+
+  // resize the params array by increment of WIFI_MANAGER_MAX_PARAMS
+  if(_paramsCount == _max_params){
+    _max_params += WIFI_MANAGER_MAX_PARAMS;
+    DEBUG_WM(DEBUG_DEV,F("Updated _max_params:"),_max_params);
+    DEBUG_WM(DEBUG_DEV,"re-allocating params bytes:",_max_params * sizeof(WiFiManagerParameter*));    
+    WiFiManagerParameter** new_params = (WiFiManagerParameter**)realloc(_params, _max_params * sizeof(WiFiManagerParameter*));
+    // DEBUG_WM(WIFI_MANAGER_MAX_PARAMS);
+    // DEBUG_WM(_paramsCount);
+    // DEBUG_WM(_max_params);
+    if (new_params != NULL) {
+      _params = new_params;
+    } else {
+      DEBUG_WM(DEBUG_ERROR,"[ERROR] failed to realloc params, size not increased!");
+      return false;
+    }
+  }
+
+  _params[_paramsCount] = p;
+  _paramsCount++;
+  
+  DEBUG_WM(DEBUG_VERBOSE,"Added Parameter:",p->getID());
+  return true;
+}
+
+/**
+ * [getParameters description]
+ * @access public
+ */
+WiFiManagerParameter** WiFiManager::getParameters() {
+  return _params;
+}
+
+/**
+ * [getParametersCount description]
+ * @access public
+ */
+int WiFiManager::getParametersCount() {
+  return _paramsCount;
+}
+
+/**
+ * --------------------------------------------------------------------------------
+ *  WiFiManager 
+ * --------------------------------------------------------------------------------
+**/
+
+// constructors
+WiFiManager::WiFiManager(Stream& consolePort):_debugPort(consolePort){
+  WiFiManagerInit();
+}
+
+WiFiManager::WiFiManager() {
+  WiFiManagerInit();  
+}
+
+void WiFiManager::WiFiManagerInit(){
+  setMenu(_menuIdsDefault);
+  if(_debug && _debugLevel > DEBUG_DEV) debugPlatformInfo();
+  _max_params = WIFI_MANAGER_MAX_PARAMS;
+}
+
+// destructor
+WiFiManager::~WiFiManager() {
+  _end();
+  // parameters
+  // @todo below belongs to wifimanagerparameter
+  if (_params != NULL){
+    DEBUG_WM(DEBUG_DEV,F("freeing allocated params!"));
+    free(_params);
+    _params = NULL;
+  }
+
+  // @todo remove event
+  // #ifdef ESP32
+  // WiFi.removeEvent(std::bind(&WiFiManager::WiFiEvent,this));
+  // #endif
+
+  DEBUG_WM(DEBUG_DEV,F("unloading"));
+}
+
+void WiFiManager::_begin(){
+  if(_hasBegun) return;
+  _hasBegun = true;
+  _usermode = WiFi.getMode();
+
+  #ifndef ESP32
+  WiFi.persistent(false); // disable persistent so scannetworks and mode switching do not cause overwrites
+  #endif
+}
+
+void WiFiManager::_end(){
+  _hasBegun = false;
+  if(_userpersistent) WiFi.persistent(true); // reenable persistent, there is no getter we rely on _userpersistent
+  // if(_usermode != WIFI_OFF) WiFi.mode(_usermode);
+}
+
+// AUTOCONNECT
+
+boolean WiFiManager::autoConnect() {
+  String ssid = getDefaultAPName();
+  return autoConnect(ssid.c_str(), NULL);
+}
+
+/**
+ * [autoConnect description]
+ * @access public
+ * @param  {[type]} char const         *apName     [description]
+ * @param  {[type]} char const         *apPassword [description]
+ * @return {[type]}      [description]
+ */
+boolean WiFiManager::autoConnect(char const *apName, char const *apPassword) {
+  DEBUG_WM(F("AutoConnect"));
+  _begin();
+
+  // attempt to connect using saved settings, on fail fallback to AP config portal
+  if(!WiFi.enableSTA(true)){
+    // handle failure mode Brownout detector etc.
+    DEBUG_WM(DEBUG_ERROR,"[FATAL] Unable to enable wifi!");
+    return false;
+  }
+  
+  WiFiSetCountry();
+
+  #ifdef ESP32
+  if(esp32persistent) WiFi.persistent(false); // disable persistent for esp32 after esp_wifi_start or else saves wont work
+  #endif
+
+  _usermode = WIFI_STA;
+
+  // no getter for autoreconnectpolicy before this
+  // https://github.com/esp8266/Arduino/pull/4359
+  // so we must force it on else, if not connectimeout then waitforconnectionresult gets stuck endless loop
+  WiFi_autoReconnect();
+
+  // set hostname before stating
+  if((String)_hostname != ""){
+    DEBUG_WM(DEBUG_VERBOSE,"Setting hostname:",_hostname);
+    bool res = true;
+    #ifdef ESP8266
+      res = WiFi.hostname(_hostname);
+      #ifdef ESP8266MDNS_H
+        DEBUG_WM(DEBUG_VERBOSE,"Setting MDNS hostname");
+        if(MDNS.begin(_hostname)){
+          MDNS.addService("http", "tcp", 80);
+        }
+      #endif
+    #elif defined(ESP32)
+      // @note hostname must be set after STA_START
+      delay(200); // do not remove, give time for STA_START
+      res = WiFi.setHostname(_hostname);
+      #ifdef ESP32MDNS_H
+        DEBUG_WM(DEBUG_VERBOSE,"Setting MDNS hostname");
+        if(MDNS.begin(_hostname)){
+          MDNS.addService("http", "tcp", 80);
+        }
+      #endif
+    #endif
+    
+    if(!res)DEBUG_WM(DEBUG_ERROR,F("[ERROR] hostname: set failed!"));
+    
+    if(WiFi.status() == WL_CONNECTED){
+      DEBUG_WM(DEBUG_VERBOSE,F("reconnecting to set new hostname"));
+      // WiFi.reconnect(); // This does not reset dhcp
+      WiFi_Disconnect();
+      delay(200); // do not remove, need a delay for disconnect to change status()
+    }
+  }
+
+  // if already connected, or try stored connect 
+  // @note @todo ESP32 has no autoconnect, so connectwifi will always be called unless user called begin etc before
+  // @todo check if correct ssid == saved ssid when already connected
+  bool connected = false;
+  if (WiFi.status() == WL_CONNECTED){
+    connected = true;
+    DEBUG_WM(F("AutoConnect: ESP Already Connected"));
+    setSTAConfig();
+  }
+
+  if(connected || connectWifi("", "") == WL_CONNECTED){
+    //connected
+    DEBUG_WM(F("AutoConnect: SUCCESS"));
+    DEBUG_WM(F("STA IP Address:"),WiFi.localIP());
+    _lastconxresult = WL_CONNECTED;
+
+    if((String)_hostname != ""){
+      #ifdef ESP8266
+        DEBUG_WM(DEBUG_DEV,"hostname: STA",WiFi.hostname());
+      #elif defined(ESP32)
+        DEBUG_WM(DEBUG_DEV,"hostname: STA",WiFi.getHostname());
+      #endif
+    }
+    return true;
+  }
+
+  // possibly skip the config portal
+  if (!_enableConfigPortal) {
+    return false;
+  }
+
+  DEBUG_WM(F("AutoConnect: FAILED"));
+
+  // not connected start configportal
+  return startConfigPortal(apName, apPassword);
+}
+
+// CONFIG PORTAL
+bool WiFiManager::startAP(){
+  bool ret = true;
+  DEBUG_WM(F("StartAP with SSID: "),_apName);
+
+  #ifdef ESP8266
+    // @bug workaround for bug #4372 https://github.com/esp8266/Arduino/issues/4372
+    if(!WiFi.enableAP(true)) {
+      DEBUG_WM(DEBUG_ERROR,"[ERROR] enableAP failed!");
+      return false;
+    }
+    delay(500); // workaround delay
+  #endif
+
+  // setup optional soft AP static ip config
+  if (_ap_static_ip) {
+    DEBUG_WM(F("Custom AP IP/GW/Subnet:"));
+    if(!WiFi.softAPConfig(_ap_static_ip, _ap_static_gw, _ap_static_sn)){
+      DEBUG_WM(DEBUG_ERROR,"[ERROR] softAPConfig failed!");
+    }
+  }
+
+  //@todo add callback here if needed to modify ap but cannot use setAPStaticIPConfig
+  //@todo rework wifi channelsync as it will work unpredictably when not connected in sta
+ 
+  int32_t channel = 0;
+  if(_channelSync) channel = WiFi.channel();
+  else channel = _apChannel;
+
+  if(channel>0){
+    DEBUG_WM(DEBUG_VERBOSE,"Starting AP on channel:",channel);
+  }
+
+  // start soft AP with password or anonymous
+  // default channel is 1 here and in esplib, @todo just change to default remove conditionals
+  if (_apPassword != "") {
+    if(channel>0){
+      ret = WiFi.softAP(_apName.c_str(), _apPassword.c_str(),channel,_apHidden);
+    }  
+    else{
+      ret = WiFi.softAP(_apName.c_str(), _apPassword.c_str(),1,_apHidden);//password option
+    }
+  } else {
+    DEBUG_WM(DEBUG_VERBOSE,F("AP has anonymous access!"));    
+    if(channel>0){
+      ret = WiFi.softAP(_apName.c_str(),"",channel,_apHidden);
+    }  
+    else{
+      ret = WiFi.softAP(_apName.c_str(),"",1,_apHidden);
+    }  
+  }
+
+  if(_debugLevel >= DEBUG_DEV) debugSoftAPConfig();
+
+  if(!ret) DEBUG_WM(DEBUG_ERROR,"[ERROR] There was a problem starting the AP");
+  // @todo add softAP retry here
+  
+  delay(500); // slight delay to make sure we get an AP IP
+  DEBUG_WM(F("AP IP address:"),WiFi.softAPIP());
+
+  // set ap hostname
+  #ifdef ESP32
+    if(ret && (String)_hostname != ""){
+      DEBUG_WM(DEBUG_VERBOSE,"setting softAP Hostname:",_hostname);
+      bool res =  WiFi.softAPsetHostname(_hostname);
+      if(!res)DEBUG_WM(DEBUG_ERROR,F("[ERROR] hostname: AP set failed!"));
+      DEBUG_WM(DEBUG_DEV,F("hostname: AP"),WiFi.softAPgetHostname());
+   }
+  #endif
+
+  return ret;
+}
+
+/**
+ * [startWebPortal description]
+ * @access public
+ * @return {[type]} [description]
+ */
+void WiFiManager::startWebPortal() {
+  if(configPortalActive || webPortalActive) return;
+  setupConfigPortal();
+  webPortalActive = true;
+}
+
+/**
+ * [stopWebPortal description]
+ * @access public
+ * @return {[type]} [description]
+ */
+void WiFiManager::stopWebPortal() {
+  if(!configPortalActive && !webPortalActive) return;
+  DEBUG_WM(DEBUG_VERBOSE,F("Stopping Web Portal"));  
+  webPortalActive = false;
+  shutdownConfigPortal();
+}
+
+boolean WiFiManager::configPortalHasTimeout(){
+
+    if(_configPortalTimeout == 0 || (_apClientCheck && (WiFi_softap_num_stations() > 0))){
+      if(millis() - timer > 30000){
+        timer = millis();
+        DEBUG_WM(DEBUG_VERBOSE,"NUM CLIENTS: " + (String)WiFi_softap_num_stations());
+      }
+      _configPortalStart = millis(); // kludge, bump configportal start time to skew timeouts
+      return false;
+    }
+    // handle timeout
+    if(_webClientCheck && (_webPortalAccessed>_configPortalStart)>0) _configPortalStart = _webPortalAccessed;
+
+    if(millis() > _configPortalStart + _configPortalTimeout){
+      DEBUG_WM(F("config portal has timed out"));
+      return true;
+    } else if(_debugLevel > 0) {
+      // log timeout
+      if(_debug){
+        uint16_t logintvl = 30000; // how often to emit timeing out counter logging
+        if((millis() - timer) > logintvl){
+          timer = millis();
+          DEBUG_WM(DEBUG_VERBOSE,F("Portal Timeout In"),(String)((_configPortalStart + _configPortalTimeout-millis())/1000) + (String)F(" seconds"));
+        }
+      }
+    }
+
+    return false;
+}
+
+void WiFiManager::setupConfigPortal() {
+
+  DEBUG_WM(F("Starting Web Portal"));
+
+  // setup dns and web servers
+  dnsServer.reset(new DNSServer());
+  server.reset(new WM_WebServer(80));
+
+  /* Setup the DNS server redirecting all the domains to the apIP */
+  dnsServer->setErrorReplyCode(DNSReplyCode::NoError);
+  // DEBUG_WM("dns server started port: ",DNS_PORT);
+  DEBUG_WM(DEBUG_DEV,"dns server started with ip: ",WiFi.softAPIP());
+  dnsServer->start(DNS_PORT, F("*"), WiFi.softAPIP());
+
+  // @todo new callback, webserver started, callback cannot override handlers, but can grab them first
+
+  if ( _webservercallback != NULL) {
+    _webservercallback();
+  }
+
+  /* Setup httpd callbacks, web pages: root, wifi config pages, SO captive portal detectors and not found. */
+  server->on(String(FPSTR(R_root)).c_str(),       std::bind(&WiFiManager::handleRoot, this));
+  server->on(String(FPSTR(R_wifi)).c_str(),       std::bind(&WiFiManager::handleWifi, this, true));
+  server->on(String(FPSTR(R_wifinoscan)).c_str(), std::bind(&WiFiManager::handleWifi, this, false));
+  server->on(String(FPSTR(R_wifisave)).c_str(),   std::bind(&WiFiManager::handleWifiSave, this));
+  server->on(String(FPSTR(R_info)).c_str(),       std::bind(&WiFiManager::handleInfo, this));
+  server->on(String(FPSTR(R_param)).c_str(),      std::bind(&WiFiManager::handleParam, this));
+  server->on(String(FPSTR(R_paramsave)).c_str(),  std::bind(&WiFiManager::handleParamSave, this));
+  server->on(String(FPSTR(R_restart)).c_str(),    std::bind(&WiFiManager::handleReset, this));
+  server->on(String(FPSTR(R_exit)).c_str(),       std::bind(&WiFiManager::handleExit, this));
+  server->on(String(FPSTR(R_close)).c_str(),      std::bind(&WiFiManager::handleClose, this));
+  server->on(String(FPSTR(R_erase)).c_str(),      std::bind(&WiFiManager::handleErase, this, false));
+  server->on(String(FPSTR(R_status)).c_str(),     std::bind(&WiFiManager::handleWiFiStatus, this));
+  server->onNotFound (std::bind(&WiFiManager::handleNotFound, this));
+  
+  server->begin(); // Web server start
+  DEBUG_WM(DEBUG_VERBOSE,F("HTTP server started"));
+
+  if(_preloadwifiscan) WiFi_scanNetworks(true,true); // preload wifiscan , async
+}
+
+boolean WiFiManager::startConfigPortal() {
+  String ssid = getDefaultAPName();
+  return startConfigPortal(ssid.c_str(), NULL);
+}
+
+/**
+ * [startConfigPortal description]
+ * @access public
+ * @param  {[type]} char const         *apName     [description]
+ * @param  {[type]} char const         *apPassword [description]
+ * @return {[type]}      [description]
+ */
+boolean  WiFiManager::startConfigPortal(char const *apName, char const *apPassword) {
+  _begin();
+
+  //setup AP
+  _apName     = apName; // @todo check valid apname ?
+  _apPassword = apPassword;
+  
+  DEBUG_WM(DEBUG_VERBOSE,F("Starting Config Portal"));
+
+  if(_apName == "") _apName = getDefaultAPName();
+
+  if(!validApPassword()) return false;
+  
+  // HANDLE issues with STA connections, shutdown sta if not connected, or else this will hang channel scanning and softap will not respond
+  // @todo sometimes still cannot connect to AP for no known reason, no events in log either
+  if(_disableSTA || (!WiFi.isConnected() && _disableSTAConn)){
+    // this fixes most ap problems, however, simply doing mode(WIFI_AP) does not work if sta connection is hanging, must `wifi_station_disconnect` 
+    WiFi_Disconnect();
+    WiFi_enableSTA(false);
+    DEBUG_WM(DEBUG_VERBOSE,F("Disabling STA"));
+  }
+  else {
+    // @todo even if sta is connected, it is possible that softap connections will fail, IOS says "invalid password", windows says "cannot connect to this network" researching
+    WiFi_enableSTA(true);
+  }
+
+  // init configportal globals to known states
+  configPortalActive = true;
+  bool result = connect = abort = false; // loop flags, connect true success, abort true break
+  uint8_t state;
+
+  _configPortalStart = millis();
+
+  // start access point
+  DEBUG_WM(DEBUG_VERBOSE,F("Enabling AP"));
+  startAP();
+  WiFiSetCountry();
+
+  // do AP callback if set
+  if ( _apcallback != NULL) {
+    _apcallback(this);
+  }
+
+  // init configportal
+  DEBUG_WM(DEBUG_DEV,F("setupConfigPortal"));
+  setupConfigPortal();
+
+  if(!_configPortalIsBlocking){
+    DEBUG_WM(DEBUG_VERBOSE,F("Config Portal Running, non blocking/processing"));
+    return result;
+  }
+
+  DEBUG_WM(DEBUG_VERBOSE,F("Config Portal Running, blocking, waiting for clients..."));
+  // blocking loop waiting for config
+  while(1){
+
+    // if timed out or abort, break
+    if(configPortalHasTimeout() || abort){
+      DEBUG_WM(DEBUG_DEV,F("configportal abort"));
+      shutdownConfigPortal();
+      result = abort ? portalAbortResult : portalTimeoutResult; // false, false
+      break;
+    }
+
+    state = processConfigPortal();
+
+    // status change, break
+    if(state != WL_IDLE_STATUS){
+        result = (state == WL_CONNECTED); // true if connected
+        break;
+    }
+
+    yield(); // watchdog
+  }
+
+  DEBUG_WM(DEBUG_NOTIFY,F("config portal exiting"));
+  return result;
+}
+
+/**
+ * [process description]
+ * @access public
+ * @return {[type]} [description]
+ */
+boolean WiFiManager::process(){
+    if(webPortalActive || (configPortalActive && !_configPortalIsBlocking)){
+        uint8_t state = processConfigPortal();
+        return state == WL_CONNECTED;
+    }
+    return false;
+}
+
+//using esp enums returns for now, should be fine
+uint8_t WiFiManager::processConfigPortal(){
+    //DNS handler
+    dnsServer->processNextRequest();
+    //HTTP handler
+    server->handleClient();
+
+    // Waiting for save...
+    if(connect) {
+      connect = false;
+      DEBUG_WM(DEBUG_VERBOSE,F("process connect"));
+      if(_enableCaptivePortal) delay(_cpclosedelay); // keeps the captiveportal from closing to fast.
+
+      // skip wifi if no ssid
+      if(_ssid == ""){
+        DEBUG_WM(DEBUG_VERBOSE,F("No ssid, skipping wifi save"));
+      }
+      else{
+        // attempt sta connection to submitted _ssid, _pass
+        if (connectWifi(_ssid, _pass) == WL_CONNECTED) {
+          
+          DEBUG_WM(F("Connect to new AP [SUCCESS]"));
+          DEBUG_WM(F("Got IP Address:"));
+          DEBUG_WM(WiFi.localIP());
+
+          if ( _savewificallback != NULL) {
+            _savewificallback();
+          }
+          shutdownConfigPortal();
+          return WL_CONNECTED; // CONNECT SUCCESS
+        }
+        DEBUG_WM(DEBUG_ERROR,F("[ERROR] Connect to new AP Failed"));
+      }
+ 
+      if (_shouldBreakAfterConfig) {
+        // do save callback
+        // @todo this is more of an exiting callback than a save, clarify when this should actually occur
+        // confirm or verify data was saved to make this more accurate callback
+        if ( _savewificallback != NULL) {
+          _savewificallback();
+        }
+        shutdownConfigPortal();
+        return WL_CONNECT_FAILED; // CONNECT FAIL
+      }
+      else{
+        // clear save strings
+        _ssid = "";
+        _pass = "";
+        // if connect fails, turn sta off to stabilize AP
+        WiFi_Disconnect();
+        WiFi_enableSTA(false);
+        DEBUG_WM(DEBUG_VERBOSE,F("Disabling STA"));
+      }
+    }
+
+    return WL_IDLE_STATUS;
+}
+
+/**
+ * [shutdownConfigPortal description]
+ * @access public
+ * @return bool success (softapdisconnect)
+ */
+bool WiFiManager::shutdownConfigPortal(){
+  if(webPortalActive) return false;
+
+  //DNS handler
+  dnsServer->processNextRequest();
+  //HTTP handler
+  server->handleClient();
+
+  // @todo what is the proper way to shutdown and free the server up
+  server->stop();
+  server.reset();
+  dnsServer->stop(); //  free heap ?
+  dnsServer.reset();
+
+  WiFi.scanDelete(); // free wifi scan results
+
+  if(!configPortalActive) return false;
+
+  // turn off AP
+  // @todo bug workaround
+  // https://github.com/esp8266/Arduino/issues/3793
+  // [APdisconnect] set_config failed! *WM: disconnect configportal - softAPdisconnect failed
+  // still no way to reproduce reliably
+  DEBUG_WM(DEBUG_VERBOSE,F("disconnect configportal"));
+  bool ret = false;
+  ret = WiFi.softAPdisconnect(false);
+  if(!ret)DEBUG_WM(DEBUG_ERROR,F("[ERROR] disconnect configportal - softAPdisconnect FAILED"));
+  delay(1000);
+  DEBUG_WM(DEBUG_VERBOSE,"restoring usermode",getModeString(_usermode));
+  WiFi_Mode(_usermode); // restore users wifi mode, BUG https://github.com/esp8266/Arduino/issues/4372
+  if(WiFi.status()==WL_IDLE_STATUS){
+    WiFi.reconnect(); // restart wifi since we disconnected it in startconfigportal
+    DEBUG_WM(DEBUG_VERBOSE,"WiFi Reconnect, was idle");
+  }
+  DEBUG_WM(DEBUG_VERBOSE,"wifi status:",getWLStatusString(WiFi.status()));
+  DEBUG_WM(DEBUG_VERBOSE,"wifi mode:",getModeString(WiFi.getMode()));
+  configPortalActive = false;
+  _end();
+  return ret;
+}
+
+// @todo refactor this up into seperate functions
+// one for connecting to flash , one for new client
+// clean up, flow is convoluted, and causes bugs
+uint8_t WiFiManager::connectWifi(String ssid, String pass) {
+  DEBUG_WM(DEBUG_VERBOSE,F("Connecting as wifi client..."));
+  
+  uint8_t connRes = (uint8_t)WL_NO_SSID_AVAIL;
+
+  setSTAConfig();
+  //@todo catch failures in set_config
+  
+  // make sure sta is on before `begin` so it does not call enablesta->mode while persistent is ON ( which would save WM AP state to eeprom !)
+  
+  if(_cleanConnect) WiFi_Disconnect(); // disconnect before begin, in case anything is hung, this causes a 2 seconds delay for connect
+  // @todo find out what status is when this is needed, can we detect it and handle it, say in between states or idle_status
+
+  // if ssid argument provided connect to that
+  if (ssid != "") {
+    wifiConnectNew(ssid,pass);
+    if(_saveTimeout > 0){
+      connRes = waitForConnectResult(_saveTimeout); // use default save timeout for saves to prevent bugs in esp->waitforconnectresult loop
+    }  
+    else {
+       connRes = waitForConnectResult(0);
+    }
+  }
+  else {
+    // connect using saved ssid if there is one
+    if (WiFi_hasAutoConnect()) {
+      wifiConnectDefault();
+      connRes = waitForConnectResult();
+    }
+    else {
+      DEBUG_WM(F("No saved credentials, skipping wifi"));
+    }
+  }
+
+  DEBUG_WM(DEBUG_VERBOSE,F("Connection result:"),getWLStatusString(connRes));
+
+// WPS enabled? https://github.com/esp8266/Arduino/pull/4889
+#ifdef NO_EXTRA_4K_HEAP
+  // do WPS, if WPS options enabled and not connected and no password was supplied
+  // @todo this seems like wrong place for this, is it a fallback or option?
+  if (_tryWPS && connRes != WL_CONNECTED && pass == "") {
+    startWPS();
+    // should be connected at the end of WPS
+    connRes = waitForConnectResult();
+  }
+#endif
+
+  if(connRes != WL_SCAN_COMPLETED){
+    updateConxResult(connRes);
+  }
+
+  return connRes;
+}
+
+/**
+ * connect to a new wifi ap
+ * @since $dev
+ * @param  String ssid 
+ * @param  String pass 
+ * @return bool success
+ */
+bool WiFiManager::wifiConnectNew(String ssid, String pass){
+  bool ret = false;
+  DEBUG_WM(F("CONNECTED:"),WiFi.status() == WL_CONNECTED);
+  DEBUG_WM(F("Connecting to NEW AP:"),ssid);
+  DEBUG_WM(DEBUG_DEV,F("Using Password:"),pass);
+  WiFi_enableSTA(true,storeSTAmode); // storeSTAmode will also toggle STA on in default opmode (persistent) if true (default)
+  WiFi.persistent(true);
+  ret = WiFi.begin(ssid.c_str(), pass.c_str());
+  WiFi.persistent(false);
+  if(!ret) DEBUG_WM(DEBUG_ERROR,"[ERROR] wifi begin failed");
+  return ret;
+}
+
+/**
+ * connect to stored wifi
+ * @since dev
+ * @return bool success
+ */
+bool WiFiManager::wifiConnectDefault(){
+  bool ret = false;
+  DEBUG_WM(F("Connecting to SAVED AP:"),WiFi_SSID(true));
+  DEBUG_WM(DEBUG_DEV,F("Using Password:"),WiFi_psk(true));
+  ret = WiFi_enableSTA(true,storeSTAmode);
+  if(!ret) DEBUG_WM(DEBUG_ERROR,"[ERROR] wifi enableSta failed");
+  ret = WiFi.begin();
+  if(!ret) DEBUG_WM(DEBUG_ERROR,"[ERROR] wifi begin failed");
+  return ret;
+}
+
+
+/**
+ * set sta config if set
+ * @since $dev
+ * @return bool success
+ */
+bool WiFiManager::setSTAConfig(){
+  DEBUG_WM(DEBUG_DEV,F("STA static IP:"),_sta_static_ip);  
+  bool ret = true;
+  if (_sta_static_ip) {
+      DEBUG_WM(DEBUG_VERBOSE,F("Custom static IP/GW/Subnet/DNS"));
+    if(_sta_static_dns) {
+      DEBUG_WM(DEBUG_VERBOSE,F("Custom static DNS"));
+      ret = WiFi.config(_sta_static_ip, _sta_static_gw, _sta_static_sn, _sta_static_dns);
+    }
+    else {
+      DEBUG_WM(DEBUG_VERBOSE,F("Custom STA IP/GW/Subnet"));
+      ret = WiFi.config(_sta_static_ip, _sta_static_gw, _sta_static_sn);
+    }
+
+    if(!ret) DEBUG_WM(DEBUG_ERROR,"[ERROR] wifi config failed");
+    else DEBUG_WM(F("STA IP set:"),WiFi.localIP());
+  } else {
+      DEBUG_WM(DEBUG_VERBOSE,F("setSTAConfig static ip not set, skipping"));
+  }
+  return ret;
+}
+
+// @todo change to getLastFailureReason and do not touch conxresult
+void WiFiManager::updateConxResult(uint8_t status){
+  // hack in wrong password detection
+  _lastconxresult = status;
+    #ifdef ESP8266
+      if(_lastconxresult == WL_CONNECT_FAILED){
+        if(wifi_station_get_connect_status() == STATION_WRONG_PASSWORD){
+          _lastconxresult = WL_STATION_WRONG_PASSWORD;
+        }
+      }
+    #elif defined(ESP32)
+      // if(_lastconxresult == WL_CONNECT_FAILED){
+      if(_lastconxresult == WL_CONNECT_FAILED || _lastconxresult == WL_DISCONNECTED){
+        DEBUG_WM(DEBUG_DEV,"lastconxresulttmp:",getWLStatusString(_lastconxresulttmp));            
+        if(_lastconxresulttmp != WL_IDLE_STATUS){
+          _lastconxresult    = _lastconxresulttmp;
+          // _lastconxresulttmp = WL_IDLE_STATUS;
+        }
+      }
+    #endif
+    DEBUG_WM(DEBUG_DEV,"lastconxresult:",getWLStatusString(_lastconxresult));
+}
+
+ 
+uint8_t WiFiManager::waitForConnectResult() {
+  if(_connectTimeout > 0) DEBUG_WM(DEBUG_VERBOSE,_connectTimeout,F("ms connectTimeout set")); 
+  return waitForConnectResult(_connectTimeout);
+}
+
+/**
+ * waitForConnectResult
+ * @param  uint16_t timeout  in seconds
+ * @return uint8_t  WL Status
+ */
+uint8_t WiFiManager::waitForConnectResult(uint16_t timeout) {
+  if (timeout == 0){
+    DEBUG_WM(F("connectTimeout not set, ESP waitForConnectResult..."));
+    return WiFi.waitForConnectResult();
+  }
+
+  unsigned long timeoutmillis = millis() + timeout;
+  DEBUG_WM(DEBUG_VERBOSE,timeout,F("ms timeout, waiting for connect..."));
+  uint8_t status = WiFi.status();
+  
+  while(millis() < timeoutmillis) {
+    status = WiFi.status();
+    // @todo detect additional states, connect happens, then dhcp then get ip, there is some delay here, make sure not to timeout if waiting on IP
+    if (status == WL_CONNECTED || status == WL_CONNECT_FAILED) {
+      return status;
+    }
+    DEBUG_WM (DEBUG_VERBOSE,F("."));
+    delay(100);
+  }
+  return status;
+}
+
+// WPS enabled? https://github.com/esp8266/Arduino/pull/4889
+#ifdef NO_EXTRA_4K_HEAP
+void WiFiManager::startWPS() {
+  DEBUG_WM(F("START WPS"));
+  #ifdef ESP8266  
+    WiFi.beginWPSConfig();
+  #else
+    // @todo
+  #endif
+  DEBUG_WM(F("END WPS"));
+}
+#endif
+
+String WiFiManager::getHTTPHead(String title){
+  String page;
+  page += FPSTR(HTTP_HEAD_START);
+  page.replace(FPSTR(T_v), title);
+  page += FPSTR(HTTP_SCRIPT);
+  page += FPSTR(HTTP_STYLE);
+  page += _customHeadElement;
+
+  if(_bodyClass != ""){
+    String p = FPSTR(HTTP_HEAD_END);
+    p.replace(FPSTR(T_c), _bodyClass); // add class str
+    page += p;
+  }
+  else {
+    page += FPSTR(HTTP_HEAD_END);
+  } 
+
+  return page;
+}
+
+/** 
+ * HTTPD handler for page requests
+ */
+void WiFiManager::handleRequest() {
+  _webPortalAccessed = millis();
+}
+
+/** 
+ * HTTPD CALLBACK root or redirect to captive portal
+ */
+void WiFiManager::handleRoot() {
+  DEBUG_WM(DEBUG_VERBOSE,F("<- HTTP Root"));
+  if (captivePortal()) return; // If captive portal redirect instead of displaying the page
+  handleRequest();
+  String page = getHTTPHead(FPSTR(S_options)); // @token options
+  String str  = FPSTR(HTTP_ROOT_MAIN);
+  str.replace(FPSTR(T_v),configPortalActive ? _apName : WiFi.localIP().toString()); // use ip if ap is not active for heading
+  page += str;
+  page += FPSTR(HTTP_PORTAL_OPTIONS);
+  page += getMenuOut();
+  reportStatus(page);
+  page += FPSTR(HTTP_END);
+
+  server->sendHeader(FPSTR(HTTP_HEAD_CL), String(page.length()));
+  server->send(200, FPSTR(HTTP_HEAD_CT), page);
+  // server->close(); // testing reliability fix for content length mismatches during mutiple flood hits  WiFi_scanNetworks(); // preload wifiscan 
+  if(_preloadwifiscan) WiFi_scanNetworks(_scancachetime,true); // preload wifiscan throttled, async
+  // @todo buggy, captive portals make a query on every page load, causing this to run every time in addition to the real page load
+  // I dont understand why, when you are already in the captive portal, I guess they want to know that its still up and not done or gone
+  // if we can detect these and ignore them that would be great, since they come from the captive portal redirect maybe there is a refferer
+}
+
+/**
+ * HTTPD CALLBACK Wifi config page handler
+ */
+void WiFiManager::handleWifi(boolean scan) {
+  DEBUG_WM(DEBUG_VERBOSE,F("<- HTTP Wifi"));
+  handleRequest();
+  String page = getHTTPHead(FPSTR(S_titlewifi)); // @token titlewifi
+  if (scan) {
+    // DEBUG_WM(DEBUG_DEV,"refresh flag:",server->hasArg(F("refresh")));
+    WiFi_scanNetworks(server->hasArg(F("refresh")),false); //wifiscan, force if arg refresh
+    page += getScanItemOut();
+  }
+  String pitem = "";
+
+  pitem = FPSTR(HTTP_FORM_START);
+  pitem.replace(FPSTR(T_v), F("wifisave")); // set form action
+  page += pitem;
+
+  pitem = FPSTR(HTTP_FORM_WIFI);
+  pitem.replace(FPSTR(T_v), WiFi_SSID());
+
+  if(_showPassword){
+    pitem.replace(FPSTR(T_p), WiFi_psk());
+  }
+  else {
+    pitem.replace(FPSTR(T_p),FPSTR(S_passph));    
+  }
+  page += pitem;
+
+  page += getStaticOut();
+  page += FPSTR(HTTP_FORM_WIFI_END);
+  if(_paramsInWifi && _paramsCount>0){
+    page += FPSTR(HTTP_FORM_PARAM_HEAD);
+    page += getParamOut();
+  }
+  page += FPSTR(HTTP_FORM_END);
+  page += FPSTR(HTTP_SCAN_LINK);
+  reportStatus(page);
+  page += FPSTR(HTTP_END);
+
+  server->sendHeader(FPSTR(HTTP_HEAD_CL), String(page.length()));
+  server->send(200, FPSTR(HTTP_HEAD_CT), page);
+  // server->close(); // testing reliability fix for content length mismatches during mutiple flood hits
+
+  DEBUG_WM(DEBUG_DEV,F("Sent config page"));
+}
+
+/**
+ * HTTPD CALLBACK Wifi param page handler
+ */
+void WiFiManager::handleParam(){
+  DEBUG_WM(DEBUG_VERBOSE,F("<- HTTP Param"));
+  handleRequest();
+  String page = getHTTPHead(FPSTR(S_titleparam)); // @token titlewifi
+
+  String pitem = "";
+
+  pitem = FPSTR(HTTP_FORM_START);
+  pitem.replace(FPSTR(T_v), F("paramsave"));
+  page += pitem;
+
+  page += getParamOut();
+  page += FPSTR(HTTP_FORM_END);
+  reportStatus(page);
+  page += FPSTR(HTTP_END);
+
+  server->sendHeader(FPSTR(HTTP_HEAD_CL), String(page.length()));
+  server->send(200, FPSTR(HTTP_HEAD_CT), page);
+
+  DEBUG_WM(DEBUG_DEV,F("Sent param page"));
+}
+
+
+String WiFiManager::getMenuOut(){
+  String page;  
+
+  for(auto menuId :_menuIds ){
+    if(((String)menuId == "param") && (_paramsCount == 0)) continue; // no params set, omit params from menu, @todo this may be undesired by someone
+    page += HTTP_PORTAL_MENU[menuId];
+  }
+
+  return page;
+}
+
+// // is it possible in softap mode to detect aps without scanning
+// bool WiFiManager::WiFi_scanNetworksForAP(bool force){
+//   WiFi_scanNetworks(force);
+// }
+
+void WiFiManager::WiFi_scanComplete(int networksFound){
+  _lastscan = millis();
+  _numNetworks = networksFound;
+  DEBUG_WM(DEBUG_VERBOSE,F("WiFi Scan ASYNC completed"), "in "+(String)(_lastscan - _startscan)+" ms");  
+  DEBUG_WM(DEBUG_VERBOSE,F("WiFi Scan ASYNC found:"),_numNetworks);
+}
+
+bool WiFiManager::WiFi_scanNetworks(){
+  return WiFi_scanNetworks(false,false);
+}
+
+bool WiFiManager::WiFi_scanNetworks(unsigned int cachetime,bool async){
+    return WiFi_scanNetworks(millis()-_lastscan > cachetime,async);
+}
+bool WiFiManager::WiFi_scanNetworks(unsigned int cachetime){
+    return WiFi_scanNetworks(millis()-_lastscan > cachetime,false);
+}
+bool WiFiManager::WiFi_scanNetworks(bool force,bool async){
+    // DEBUG_WM(DEBUG_DEV,"scanNetworks async:",async == true);
+    // DEBUG_WM(DEBUG_DEV,_numNetworks,(millis()-_lastscan ));
+    // DEBUG_WM(DEBUG_DEV,"scanNetworks force:",force == true);
+    if(force || _numNetworks == 0 || (millis()-_lastscan > 60000)){
+      int8_t res;
+      _startscan = millis();
+      if(async && _asyncScan){
+        #ifdef ESP8266
+          #ifndef WM_NOASYNC // no async available < 2.4.0
+          DEBUG_WM(DEBUG_VERBOSE,F("WiFi Scan ASYNC started"));
+          using namespace std::placeholders; // for `_1`
+          WiFi.scanNetworksAsync(std::bind(&WiFiManager::WiFi_scanComplete,this,_1));
+          #else
+          res = WiFi.scanNetworks();
+          #endif
+        #else
+          DEBUG_WM(DEBUG_VERBOSE,F("WiFi Scan ASYNC started"));
+          res = WiFi.scanNetworks(true);
+        #endif
+        return false;
+      }
+      else{
+        res = WiFi.scanNetworks();
+      }
+      if(res == WIFI_SCAN_FAILED) DEBUG_WM(DEBUG_ERROR,"[ERROR] scan failed");
+      else if(res == WIFI_SCAN_RUNNING){
+        DEBUG_WM(DEBUG_ERROR,"[ERROR] scan waiting");
+        while(WiFi.scanComplete() == WIFI_SCAN_RUNNING){
+          DEBUG_WM(DEBUG_ERROR,".");
+          delay(100);
+        }
+        _numNetworks = WiFi.scanComplete();
+      }
+      else if(res >=0 ) _numNetworks = res;
+      _lastscan = millis();
+      DEBUG_WM(DEBUG_VERBOSE,F("WiFi Scan completed"), "in "+(String)(_lastscan - _startscan)+" ms");
+      return true;
+    } else DEBUG_WM(DEBUG_VERBOSE,"Scan is cached",(String)(millis()-_lastscan )+" ms ago");
+    return false;
+}
+
+String WiFiManager::WiFiManager::getScanItemOut(){
+    String page;
+
+    if(!_numNetworks) WiFi_scanNetworks(); // scan in case this gets called before any scans
+
+    int n = _numNetworks;
+    if (n == 0) {
+      DEBUG_WM(F("No networks found"));
+      page += FPSTR(S_nonetworks); // @token nonetworks
+    } 
+    else {
+      DEBUG_WM(n,F("networks found"));
+      //sort networks
+      int indices[n];
+      for (int i = 0; i < n; i++) {
+        indices[i] = i;
+      }
+
+      // RSSI SORT
+      for (int i = 0; i < n; i++) {
+        for (int j = i + 1; j < n; j++) {
+          if (WiFi.RSSI(indices[j]) > WiFi.RSSI(indices[i])) {
+            std::swap(indices[i], indices[j]);
+          }
+        }
+      }
+
+      /* test std:sort
+        std::sort(indices, indices + n, [](const int & a, const int & b) -> bool
+        {
+        return WiFi.RSSI(a) > WiFi.RSSI(b);
+        });
+       */
+
+      // remove duplicates ( must be RSSI sorted )
+      if (_removeDuplicateAPs) {
+        String cssid;
+        for (int i = 0; i < n; i++) {
+          if (indices[i] == -1) continue;
+          cssid = WiFi.SSID(indices[i]);
+          for (int j = i + 1; j < n; j++) {
+            if (cssid == WiFi.SSID(indices[j])) {
+              DEBUG_WM(DEBUG_VERBOSE,F("DUP AP:"),WiFi.SSID(indices[j]));
+              indices[j] = -1; // set dup aps to index -1
+            }
+          }
+        }
+      }
+
+      // token precheck, to speed up replacements on large ap lists
+      String HTTP_ITEM_STR = FPSTR(HTTP_ITEM);
+
+      // toggle icons with percentage
+      HTTP_ITEM_STR.replace("{qp}", FPSTR(HTTP_ITEM_QP));
+      HTTP_ITEM_STR.replace("{h}",_scanDispOptions ? "" : "h");
+      HTTP_ITEM_STR.replace("{qi}", FPSTR(HTTP_ITEM_QI));
+      HTTP_ITEM_STR.replace("{h}",_scanDispOptions ? "h" : "");
+ 
+      // set token precheck flags
+      bool tok_r = HTTP_ITEM_STR.indexOf(FPSTR(T_r)) > 0;
+      bool tok_R = HTTP_ITEM_STR.indexOf(FPSTR(T_R)) > 0;
+      bool tok_e = HTTP_ITEM_STR.indexOf(FPSTR(T_e)) > 0;
+      bool tok_q = HTTP_ITEM_STR.indexOf(FPSTR(T_q)) > 0;
+      bool tok_i = HTTP_ITEM_STR.indexOf(FPSTR(T_i)) > 0;
+      
+      //display networks in page
+      for (int i = 0; i < n; i++) {
+        if (indices[i] == -1) continue; // skip dups
+
+        DEBUG_WM(DEBUG_VERBOSE,F("AP: "),(String)WiFi.RSSI(indices[i]) + " " + (String)WiFi.SSID(indices[i]));
+
+        int rssiperc = getRSSIasQuality(WiFi.RSSI(indices[i]));
+        uint8_t enc_type = WiFi.encryptionType(indices[i]);
+
+        if (_minimumQuality == -1 || _minimumQuality < rssiperc) {
+          String item = HTTP_ITEM_STR;
+          item.replace(FPSTR(T_v), htmlEntities(WiFi.SSID(indices[i]))); // ssid no encoding
+          if(tok_e) item.replace(FPSTR(T_e), encryptionTypeStr(enc_type));
+          if(tok_r) item.replace(FPSTR(T_r), (String)rssiperc); // rssi percentage 0-100
+          if(tok_R) item.replace(FPSTR(T_R), (String)WiFi.RSSI(indices[i])); // rssi db
+          if(tok_q) item.replace(FPSTR(T_q), (String)int(round(map(rssiperc,0,100,1,4)))); //quality icon 1-4
+          if(tok_i){
+            if (enc_type != WM_WIFIOPEN) {
+              item.replace(FPSTR(T_i), F("l"));
+            } else {
+              item.replace(FPSTR(T_i), "");
+            }
+          }
+          //DEBUG_WM(item);
+          page += item;
+          delay(0);
+        } else {
+          DEBUG_WM(DEBUG_VERBOSE,F("Skipping , does not meet _minimumQuality"));
+        }
+
+      }
+      page += FPSTR(HTTP_BR);
+    }
+
+    return page;
+}
+
+String WiFiManager::getIpForm(String id, String title, String value){
+    String item = FPSTR(HTTP_FORM_LABEL);
+    item += FPSTR(HTTP_FORM_PARAM);
+    item.replace(FPSTR(T_i), id);
+    item.replace(FPSTR(T_n), id);
+    item.replace(FPSTR(T_p), FPSTR(T_t));
+    // item.replace(FPSTR(T_p), default);
+    item.replace(FPSTR(T_t), title);
+    item.replace(FPSTR(T_l), F("15"));
+    item.replace(FPSTR(T_v), value);
+    item.replace(FPSTR(T_c), "");
+    return item;  
+}
+
+String WiFiManager::getStaticOut(){
+  String page;
+  if ((_staShowStaticFields || _sta_static_ip) && _staShowStaticFields>=0) {
+    DEBUG_WM(DEBUG_DEV,"_staShowStaticFields");
+    page += FPSTR(HTTP_FORM_STATIC_HEAD);
+    // @todo how can we get these accurate settings from memory , wifi_get_ip_info does not seem to reveal if struct ip_info is static or not
+    page += getIpForm(FPSTR(S_ip),FPSTR(S_staticip),(_sta_static_ip ? _sta_static_ip.toString() : "")); // @token staticip
+    // WiFi.localIP().toString();
+    page += getIpForm(FPSTR(S_gw),FPSTR(S_staticgw),(_sta_static_gw ? _sta_static_gw.toString() : "")); // @token staticgw
+    // WiFi.gatewayIP().toString();
+    page += getIpForm(FPSTR(S_sn),FPSTR(S_subnet),(_sta_static_sn ? _sta_static_sn.toString() : "")); // @token subnet
+    // WiFi.subnetMask().toString();
+  }
+
+  if((_staShowDns || _sta_static_dns) && _staShowDns>=0){
+    page += getIpForm(FPSTR(S_dns),FPSTR(S_staticdns),(_sta_static_dns ? _sta_static_dns.toString() : "")); // @token dns
+  }
+
+  if(page!="") page += FPSTR(HTTP_BR); // @todo remove these, use css
+
+  return page;
+}
+
+String WiFiManager::getParamOut(){
+  String page;
+
+  if(_paramsCount > 0){
+
+    String HTTP_PARAM_temp = FPSTR(HTTP_FORM_LABEL);
+    HTTP_PARAM_temp += FPSTR(HTTP_FORM_PARAM);
+    bool tok_I = HTTP_PARAM_temp.indexOf(FPSTR(T_I)) > 0;
+    bool tok_i = HTTP_PARAM_temp.indexOf(FPSTR(T_i)) > 0;
+    bool tok_n = HTTP_PARAM_temp.indexOf(FPSTR(T_n)) > 0;
+    bool tok_p = HTTP_PARAM_temp.indexOf(FPSTR(T_p)) > 0;
+    bool tok_t = HTTP_PARAM_temp.indexOf(FPSTR(T_t)) > 0;
+    bool tok_l = HTTP_PARAM_temp.indexOf(FPSTR(T_l)) > 0;
+    bool tok_v = HTTP_PARAM_temp.indexOf(FPSTR(T_v)) > 0;
+    bool tok_c = HTTP_PARAM_temp.indexOf(FPSTR(T_c)) > 0;
+
+    char valLength[5];
+    // add the extra parameters to the form
+    for (int i = 0; i < _paramsCount; i++) {
+      if (_params[i] == NULL || _params[i]->_length == 0) {
+        DEBUG_WM(DEBUG_ERROR,"[ERROR] WiFiManagerParameter is out of scope");
+        break;
+      }
+
+     // label before or after, @todo this could be done via floats or CSS and eliminated
+     String pitem;
+      switch (_params[i]->getLabelPlacement()) {
+        case WFM_LABEL_BEFORE:
+          pitem = FPSTR(HTTP_FORM_LABEL);
+          pitem += FPSTR(HTTP_FORM_PARAM);
+          break;
+        case WFM_LABEL_AFTER:
+          pitem = FPSTR(HTTP_FORM_PARAM);
+          pitem += FPSTR(HTTP_FORM_LABEL);
+          break;
+        default:
+          // WFM_NO_LABEL
+          pitem = FPSTR(HTTP_FORM_PARAM);
+          break;
+      }
+
+      // Input templating
+      // "<br/><input id='{i}' name='{n}' maxlength='{l}' value='{v}' {c}>";
+      // if no ID use customhtml for item, else generate from param string
+      if (_params[i]->getID() != NULL) {
+        if(tok_I)pitem.replace(FPSTR(T_I), (String)FPSTR(S_parampre)+(String)i); // T_I id number
+        if(tok_i)pitem.replace(FPSTR(T_i), _params[i]->getID()); // T_i id name
+        if(tok_n)pitem.replace(FPSTR(T_n), _params[i]->getID()); // T_n id name alias
+        if(tok_p)pitem.replace(FPSTR(T_p), FPSTR(T_t)); // T_p replace legacy placeholder token
+        if(tok_t)pitem.replace(FPSTR(T_t), _params[i]->getLabel()); // T_t title/label
+        snprintf(valLength, 5, "%d", _params[i]->getValueLength());
+        if(tok_l)pitem.replace(FPSTR(T_l), valLength); // T_l value length
+        if(tok_v)pitem.replace(FPSTR(T_v), _params[i]->getValue()); // T_v value
+        if(tok_c)pitem.replace(FPSTR(T_c), _params[i]->getCustomHTML()); // T_c meant for additional attributes, not html, but can stuff
+      } else {
+        pitem = _params[i]->getCustomHTML();
+      }
+
+      page += pitem;
+    }
+  }
+
+  return page;
+}
+
+void WiFiManager::handleWiFiStatus(){
+  DEBUG_WM(DEBUG_VERBOSE,F("<- HTTP WiFi status "));
+  handleRequest();
+  String page;
+  // String page = "{\"result\":true,\"count\":1}";
+  #ifdef JSTEST
+    page = FPSTR(HTTP_JS);
+  #endif
+  server->sendHeader(FPSTR(HTTP_HEAD_CL), String(page.length()));
+  server->send(200, FPSTR(HTTP_HEAD_CT), page);
+}
+
+/** 
+ * HTTPD CALLBACK save form and redirect to WLAN config page again
+ */
+void WiFiManager::handleWifiSave() {
+  DEBUG_WM(DEBUG_VERBOSE,F("<- HTTP WiFi save "));
+  DEBUG_WM(DEBUG_DEV,F("Method:"),server->method() == HTTP_GET  ? (String)FPSTR(S_GET) : (String)FPSTR(S_POST));
+  handleRequest();
+
+ // @todo use new callback for before paramsaves
+  if ( _presavecallback != NULL) {
+    _presavecallback();
+  }
+
+  //SAVE/connect here
+  _ssid = server->arg(F("s")).c_str();
+  _pass = server->arg(F("p")).c_str();
+
+  if(_paramsInWifi) doParamSave();
+
+  if (server->arg(FPSTR(S_ip)) != "") {
+    //_sta_static_ip.fromString(server->arg(FPSTR(S_ip));
+    String ip = server->arg(FPSTR(S_ip));
+    optionalIPFromString(&_sta_static_ip, ip.c_str());
+    DEBUG_WM(DEBUG_DEV,F("static ip:"),ip);
+  }
+  if (server->arg(FPSTR(S_gw)) != "") {
+    String gw = server->arg(FPSTR(S_gw));
+    optionalIPFromString(&_sta_static_gw, gw.c_str());
+    DEBUG_WM(DEBUG_DEV,F("static gateway:"),gw);
+  }
+  if (server->arg(FPSTR(S_sn)) != "") {
+    String sn = server->arg(FPSTR(S_sn));
+    optionalIPFromString(&_sta_static_sn, sn.c_str());
+    DEBUG_WM(DEBUG_DEV,F("static netmask:"),sn);
+  }
+  if (server->arg(FPSTR(S_dns)) != "") {
+    String dns = server->arg(FPSTR(S_dns));
+    optionalIPFromString(&_sta_static_dns, dns.c_str());
+    DEBUG_WM(DEBUG_DEV,F("static DNS:"),dns);
+  }
+
+  String page;
+
+  if(_ssid == ""){
+    page = getHTTPHead(FPSTR(S_titlewifisettings)); // @token titleparamsaved
+    page += FPSTR(HTTP_PARAMSAVED);
+  }
+  else {
+    page = getHTTPHead(FPSTR(S_titlewifisaved)); // @token titlewifisaved
+    page += FPSTR(HTTP_SAVED);
+  }
+  page += FPSTR(HTTP_END);
+
+  server->sendHeader(FPSTR(HTTP_HEAD_CL), String(page.length()));
+  server->sendHeader(FPSTR(HTTP_HEAD_CORS), FPSTR(HTTP_HEAD_CORS_ALLOW_ALL));
+  server->send(200, FPSTR(HTTP_HEAD_CT), page);
+
+  DEBUG_WM(DEBUG_DEV,F("Sent wifi save page"));
+
+  connect = true; //signal ready to connect/reset process in processConfigPortal
+}
+
+void WiFiManager::handleParamSave() {
+
+  DEBUG_WM(DEBUG_VERBOSE,F("<- HTTP WiFi save "));
+  DEBUG_WM(DEBUG_DEV,F("Method:"),server->method() == HTTP_GET  ? (String)FPSTR(S_GET) : (String)FPSTR(S_POST));
+  handleRequest();
+
+  doParamSave();
+
+  String page = getHTTPHead(FPSTR(S_titleparamsaved)); // @token titleparamsaved
+  page += FPSTR(HTTP_PARAMSAVED);
+  page += FPSTR(HTTP_END);
+
+  server->sendHeader(FPSTR(HTTP_HEAD_CL), String(page.length()));
+  server->send(200, FPSTR(HTTP_HEAD_CT), page);
+
+  DEBUG_WM(DEBUG_DEV,F("Sent param save page"));
+}
+
+void WiFiManager::doParamSave(){
+   // @todo use new callback for before paramsaves, is this really needed?
+  if ( _presavecallback != NULL) {
+    _presavecallback();
+  }
+
+  //parameters
+  if(_paramsCount > 0){
+    DEBUG_WM(DEBUG_VERBOSE,F("Parameters"));
+    DEBUG_WM(DEBUG_VERBOSE,FPSTR(D_HR));
+
+    for (int i = 0; i < _paramsCount; i++) {
+      if (_params[i] == NULL || _params[i]->_length == 0) {
+        DEBUG_WM(DEBUG_ERROR,"[ERROR] WiFiManagerParameter is out of scope");
+        break; // @todo might not be needed anymore
+      }
+      //read parameter from server
+      String name = (String)FPSTR(S_parampre)+(String)i;
+      String value;
+      if(server->hasArg(name)) {
+        value = server->arg(name);
+      } else {
+        value = server->arg(_params[i]->getID());
+      }
+
+      //store it in params array
+      value.toCharArray(_params[i]->_value, _params[i]->_length+1); // length+1 null terminated
+      DEBUG_WM(DEBUG_VERBOSE,(String)_params[i]->getID() + ":",value);
+    }
+    DEBUG_WM(DEBUG_VERBOSE,FPSTR(D_HR));
+  }
+
+   if ( _saveparamscallback != NULL) {
+    _saveparamscallback();
+  }
+   
+}
+
+/** 
+ * HTTPD CALLBACK info page
+ */
+void WiFiManager::handleInfo() {
+  DEBUG_WM(DEBUG_VERBOSE,F("<- HTTP Info"));
+  handleRequest();
+  String page = getHTTPHead(FPSTR(S_titleinfo)); // @token titleinfo
+  reportStatus(page);
+
+  uint16_t infos = 0;
+
+  //@todo convert to enum or refactor to strings
+  //@todo wrap in build flag to remove all info code for memory saving
+  #ifdef ESP8266
+    infos = 27;
+    String infoids[] = {
+      F("esphead"),
+      F("uptime"),
+      F("chipid"),
+      F("fchipid"),
+      F("idesize"),
+      F("flashsize"),
+      F("sdkver"),
+      F("corever"),
+      F("bootver"),
+      F("cpufreq"),
+      F("freeheap"),
+      F("memsketch"),
+      F("memsmeter"),
+      F("lastreset"),
+      F("wifihead"),
+      F("apip"),
+      F("apmac"),
+      F("apssid"),
+      F("apbssid"),
+      F("staip"),
+      F("stagw"),
+      F("stasub"),
+      F("dnss"),
+      F("host"),
+      F("stamac"),
+      F("conx"),
+      F("autoconx")
+    };
+
+  #elif defined(ESP32)
+    infos = 22;
+    String infoids[] = {
+      F("esphead"),
+      F("uptime"),
+      F("chipid"),
+      F("chiprev"),
+      F("idesize"),
+      F("sdkver"),
+      F("cpufreq"),
+      F("freeheap"),
+      F("lastreset"),
+      // F("temp"),
+      F("wifihead"),
+      F("apip"),
+      F("apmac"),
+      F("aphost"),
+      F("apssid"),
+      F("apbssid"),
+      F("staip"),
+      F("stagw"),
+      F("stasub"),
+      F("dnss"),
+      F("host"),
+      F("stamac"),
+      F("conx")
+    };
+  #endif
+
+  for(size_t i=0; i<infos;i++){
+    if(infoids[i] != NULL) page += getInfoData(infoids[i]);
+  }
+  page += F("</dl>");
+  if(_showInfoErase) page += FPSTR(HTTP_ERASEBTN);
+  page += FPSTR(HTTP_HELP);
+  page += FPSTR(HTTP_END);
+
+  server->sendHeader(FPSTR(HTTP_HEAD_CL), String(page.length()));
+  server->send(200, FPSTR(HTTP_HEAD_CT), page);
+
+  DEBUG_WM(DEBUG_DEV,F("Sent info page"));
+}
+
+String WiFiManager::getInfoData(String id){
+
+  String p;
+  // @todo add WM versioning
+  if(id==F("esphead"))p = FPSTR(HTTP_INFO_esphead);
+  else if(id==F("wifihead"))p = FPSTR(HTTP_INFO_wifihead);
+  else if(id==F("uptime")){
+    // subject to rollover!
+    p = FPSTR(HTTP_INFO_uptime);
+    p.replace(FPSTR(T_1),(String)(millis() / 1000 / 60));
+    p.replace(FPSTR(T_2),(String)((millis() / 1000) % 60));
+  }
+  else if(id==F("chipid")){
+    p = FPSTR(HTTP_INFO_chipid);
+    p.replace(FPSTR(T_1),String(WIFI_getChipId(),HEX));
+  }
+  #ifdef ESP32
+  else if(id==F("chiprev")){
+      p = FPSTR(HTTP_INFO_chiprev);
+      String rev = (String)ESP.getChipRevision();
+      #ifdef _SOC_EFUSE_REG_H_
+        String revb = (String)(REG_READ(EFUSE_BLK0_RDATA3_REG) >> (EFUSE_RD_CHIP_VER_RESERVE_S)&&EFUSE_RD_CHIP_VER_RESERVE_V);
+        p.replace(FPSTR(T_1),rev+"<br/>"+revb);
+      #else
+        p.replace(FPSTR(T_1),rev);
+      #endif
+  }
+  #endif
+  #ifdef ESP8266
+  else if(id==F("fchipid")){
+      p = FPSTR(HTTP_INFO_fchipid);
+      p.replace(FPSTR(T_1),(String)ESP.getFlashChipId());
+  }
+  #endif
+  else if(id==F("idesize")){
+    p = FPSTR(HTTP_INFO_idesize);
+    p.replace(FPSTR(T_1),(String)ESP.getFlashChipSize());
+  }
+  else if(id==F("flashsize")){
+    #ifdef ESP8266
+      p = FPSTR(HTTP_INFO_flashsize);
+      p.replace(FPSTR(T_1),(String)ESP.getFlashChipRealSize());
+    #endif
+  }
+  else if(id==F("sdkver")){
+    p = FPSTR(HTTP_INFO_sdkver);
+    #ifdef ESP32
+      p.replace(FPSTR(T_1),(String)esp_get_idf_version());
+    #else
+    p.replace(FPSTR(T_1),(String)system_get_sdk_version());
+    #endif
+  }
+  else if(id==F("corever")){
+    #ifdef ESP8266
+      p = FPSTR(HTTP_INFO_corever);
+      p.replace(FPSTR(T_1),(String)ESP.getCoreVersion());
+    #endif      
+  }
+  #ifdef ESP8266
+  else if(id==F("bootver")){
+      p = FPSTR(HTTP_INFO_bootver);
+      p.replace(FPSTR(T_1),(String)system_get_boot_version());
+  }
+  #endif  
+  else if(id==F("cpufreq")){
+    p = FPSTR(HTTP_INFO_cpufreq);
+    p.replace(FPSTR(T_1),(String)ESP.getCpuFreqMHz());
+  }
+  else if(id==F("freeheap")){
+    p = FPSTR(HTTP_INFO_freeheap);
+    p.replace(FPSTR(T_1),(String)ESP.getFreeHeap());
+  }
+  #ifdef ESP8266
+  else if(id==F("memsketch")){
+    p = FPSTR(HTTP_INFO_memsketch);
+    p.replace(FPSTR(T_1),(String)(ESP.getSketchSize()));
+    p.replace(FPSTR(T_2),(String)(ESP.getSketchSize()+ESP.getFreeSketchSpace()));
+  }
+  #endif  
+  #ifdef ESP8266
+  else if(id==F("memsmeter")){
+    p = FPSTR(HTTP_INFO_memsmeter);
+    p.replace(FPSTR(T_1),(String)(ESP.getSketchSize()));
+    p.replace(FPSTR(T_2),(String)(ESP.getSketchSize()+ESP.getFreeSketchSpace()));
+  }
+  #endif 
+  else if(id==F("lastreset")){
+    #ifdef ESP8266
+      p = FPSTR(HTTP_INFO_lastreset);
+      p.replace(FPSTR(T_1),(String)ESP.getResetReason());
+    #elif defined(ESP32) && defined(_ROM_RTC_H_)
+      // requires #include <rom/rtc.h>
+      p = FPSTR(HTTP_INFO_lastreset);
+      for(int i=0;i<2;i++){
+        int reason = rtc_get_reset_reason(i);
+        String tok = (String)T_ss+(String)(i+1)+(String)T_es;
+        switch (reason)
+        {
+          //@todo move to array
+          case 1  : p.replace(tok,F("Vbat power on reset"));break;
+          case 3  : p.replace(tok,F("Software reset digital core"));break;
+          case 4  : p.replace(tok,F("Legacy watch dog reset digital core"));break;
+          case 5  : p.replace(tok,F("Deep Sleep reset digital core"));break;
+          case 6  : p.replace(tok,F("Reset by SLC module, reset digital core"));break;
+          case 7  : p.replace(tok,F("Timer Group0 Watch dog reset digital core"));break;
+          case 8  : p.replace(tok,F("Timer Group1 Watch dog reset digital core"));break;
+          case 9  : p.replace(tok,F("RTC Watch dog Reset digital core"));break;
+          case 10 : p.replace(tok,F("Instrusion tested to reset CPU"));break;
+          case 11 : p.replace(tok,F("Time Group reset CPU"));break;
+          case 12 : p.replace(tok,F("Software reset CPU"));break;
+          case 13 : p.replace(tok,F("RTC Watch dog Reset CPU"));break;
+          case 14 : p.replace(tok,F("for APP CPU, reseted by PRO CPU"));break;
+          case 15 : p.replace(tok,F("Reset when the vdd voltage is not stable"));break;
+          case 16 : p.replace(tok,F("RTC Watch dog reset digital core and rtc module"));break;
+          default : p.replace(tok,F("NO_MEAN"));
+        }
+      }
+    #endif
+  }
+  else if(id==F("apip")){
+    p = FPSTR(HTTP_INFO_apip);
+    p.replace(FPSTR(T_1),WiFi.softAPIP().toString());
+  }
+  else if(id==F("apmac")){
+    p = FPSTR(HTTP_INFO_apmac);
+    p.replace(FPSTR(T_1),(String)WiFi.softAPmacAddress());
+  }
+  #ifdef ESP32
+  else if(id==F("aphost")){
+      p = FPSTR(HTTP_INFO_aphost);
+      p.replace(FPSTR(T_1),WiFi.softAPgetHostname());
+  }
+  #endif
+  else if(id==F("apssid")){
+    p = FPSTR(HTTP_INFO_apssid);
+    p.replace(FPSTR(T_1),htmlEntities((String)WiFi_SSID()));
+  }
+  else if(id==F("apbssid")){
+    p = FPSTR(HTTP_INFO_apbssid);
+    p.replace(FPSTR(T_1),(String)WiFi.BSSIDstr());
+  }
+  else if(id==F("staip")){
+    p = FPSTR(HTTP_INFO_staip);
+    p.replace(FPSTR(T_1),WiFi.localIP().toString());
+  }
+  else if(id==F("stagw")){
+    p = FPSTR(HTTP_INFO_stagw);
+    p.replace(FPSTR(T_1),WiFi.gatewayIP().toString());
+  }
+  else if(id==F("stasub")){
+    p = FPSTR(HTTP_INFO_stasub);
+    p.replace(FPSTR(T_1),WiFi.subnetMask().toString());
+  }
+  else if(id==F("dnss")){
+    p = FPSTR(HTTP_INFO_dnss);
+    p.replace(FPSTR(T_1),WiFi.dnsIP().toString());
+  }
+  else if(id==F("host")){
+    p = FPSTR(HTTP_INFO_host);
+    #ifdef ESP32
+      p.replace(FPSTR(T_1),WiFi.getHostname());
+    #else
+    p.replace(FPSTR(T_1),WiFi.hostname());
+    #endif
+  }
+  else if(id==F("stamac")){
+    p = FPSTR(HTTP_INFO_stamac);
+    p.replace(FPSTR(T_1),WiFi.macAddress());
+  }
+  else if(id==F("conx")){
+    p = FPSTR(HTTP_INFO_conx);
+    p.replace(FPSTR(T_1),WiFi.isConnected() ? FPSTR(S_y) : FPSTR(S_n));
+  }
+  #ifdef ESP8266
+  else if(id==F("autoconx")){
+    p = FPSTR(HTTP_INFO_autoconx);
+    p.replace(FPSTR(T_1),WiFi.getAutoConnect() ? FPSTR(S_enable) : FPSTR(S_disable));
+  }
+  #endif
+  #ifdef ESP32
+  else if(id==F("temp")){
+    // temperature is not calibrated, varying large offsets are present, use for relative temp changes only
+    p = FPSTR(HTTP_INFO_temp);
+    p.replace(FPSTR(T_1),(String)temperatureRead());
+    p.replace(FPSTR(T_2),(String)((temperatureRead()+32)*1.8));
+  }
+  #endif
+  return p;
+}
+
+/** 
+ * HTTPD CALLBACK root or redirect to captive portal
+ */
+void WiFiManager::handleExit() {
+  DEBUG_WM(DEBUG_VERBOSE,F("<- HTTP Exit"));
+  handleRequest();
+  String page = getHTTPHead(FPSTR(S_titleexit)); // @token titleexit
+  page += FPSTR(S_exiting); // @token exiting
+  server->sendHeader(FPSTR(HTTP_HEAD_CL), String(page.length()));
+  server->send(200, FPSTR(HTTP_HEAD_CT), page);
+  abort = true;
+}
+
+/** 
+ * HTTPD CALLBACK reset page
+ */
+void WiFiManager::handleReset() {
+  DEBUG_WM(DEBUG_VERBOSE,F("<- HTTP Reset"));
+  handleRequest();
+  String page = getHTTPHead(FPSTR(S_titlereset)); //@token titlereset
+  page += FPSTR(S_resetting); //@token resetting
+  page += FPSTR(HTTP_END);
+
+  server->sendHeader(FPSTR(HTTP_HEAD_CL), String(page.length()));
+  server->send(200, FPSTR(HTTP_HEAD_CT), page);
+
+  DEBUG_WM(F("RESETTING ESP"));
+  delay(1000);
+  reboot();
+}
+
+/** 
+ * HTTPD CALLBACK erase page
+ */
+
+// void WiFiManager::handleErase() {
+//   handleErase(false);
+// }
+void WiFiManager::handleErase(boolean opt) {
+  DEBUG_WM(DEBUG_VERBOSE,F("<- HTTP Erase"));
+  handleRequest();
+  String page = getHTTPHead(FPSTR(S_titleerase)); // @token titleerase
+
+  bool ret = erase(opt);
+
+  if(ret) page += FPSTR(S_resetting); // @token resetting
+  else {
+    page += FPSTR(S_error); // @token erroroccur
+    DEBUG_WM(DEBUG_ERROR,F("[ERROR] WiFi EraseConfig failed"));
+  }
+
+  page += FPSTR(HTTP_END);
+  server->sendHeader(FPSTR(HTTP_HEAD_CL), String(page.length()));
+  server->send(200, FPSTR(HTTP_HEAD_CT), page);
+
+  if(ret){
+    delay(2000);
+  	DEBUG_WM(F("RESETTING ESP"));
+  	reboot();
+  }	
+}
+
+/** 
+ * HTTPD CALLBACK 404
+ */
+void WiFiManager::handleNotFound() {
+  if (captivePortal()) return; // If captive portal redirect instead of displaying the page
+  handleRequest();
+  String message = FPSTR(S_notfound); // @token notfound
+  message += FPSTR(S_uri); // @token uri
+  message += server->uri();
+  message += FPSTR(S_method); // @token method
+  message += ( server->method() == HTTP_GET ) ? FPSTR(S_GET) : FPSTR(S_POST);
+  message += FPSTR(S_args); // @token args
+  message += server->args();
+  message += F("\n");
+
+  for ( uint8_t i = 0; i < server->args(); i++ ) {
+    message += " " + server->argName ( i ) + ": " + server->arg ( i ) + "\n";
+  }
+  server->sendHeader(F("Cache-Control"), F("no-cache, no-store, must-revalidate"));
+  server->sendHeader(F("Pragma"), F("no-cache"));
+  server->sendHeader(F("Expires"), F("-1"));
+  server->sendHeader(FPSTR(HTTP_HEAD_CL), String(message.length()));
+  server->send ( 404, FPSTR(HTTP_HEAD_CT2), message );
+}
+
+/**
+ * HTTPD redirector
+ * Redirect to captive portal if we got a request for another domain. 
+ * Return true in that case so the page handler do not try to handle the request again. 
+ */
+boolean WiFiManager::captivePortal() {
+  DEBUG_WM(DEBUG_DEV,"-> " + server->hostHeader());
+  
+  if(!_enableCaptivePortal) return false; // skip redirections
+
+  if (!isIp(server->hostHeader())) {
+    DEBUG_WM(DEBUG_VERBOSE,F("<- Request redirected to captive portal"));
+    server->sendHeader(F("Location"), (String)F("http://") + toStringIp(server->client().localIP()), true);
+    server->send ( 302, FPSTR(HTTP_HEAD_CT2), ""); // Empty content inhibits Content-length header so we have to close the socket ourselves.
+    server->client().stop(); // Stop is needed because we sent no content length
+    return true;
+  }
+  return false;
+}
+
+void WiFiManager::stopCaptivePortal(){
+  _enableCaptivePortal= false;
+  // @todo maybe disable configportaltimeout(optional), or just provide callback for user
+}
+
+void WiFiManager::handleClose(){
+  stopCaptivePortal();
+  DEBUG_WM(DEBUG_VERBOSE,F("<- HTTP close"));
+  handleRequest();
+  String page = getHTTPHead(FPSTR(S_titleclose)); // @token titleclose
+  page += FPSTR(S_closing); // @token closing
+  server->sendHeader(FPSTR(HTTP_HEAD_CL), String(page.length()));
+  server->send(200, FPSTR(HTTP_HEAD_CT), page);
+}
+
+void WiFiManager::reportStatus(String &page){
+  updateConxResult(WiFi.status());
+  String str;
+  if (WiFi_SSID() != ""){
+    if (WiFi.status()==WL_CONNECTED){
+      str = FPSTR(HTTP_STATUS_ON);
+      str.replace(FPSTR(T_i),WiFi.localIP().toString());
+      str.replace(FPSTR(T_v),htmlEntities(WiFi_SSID()));
+    }
+    else {
+      str = FPSTR(HTTP_STATUS_OFF);
+      str.replace(FPSTR(T_v),htmlEntities(WiFi_SSID()));
+      if(_lastconxresult == WL_STATION_WRONG_PASSWORD){
+        // wrong password
+        str.replace(FPSTR(T_c),"D"); // class
+        str.replace(FPSTR(T_r),FPSTR(HTTP_STATUS_OFFPW));
+      }
+      else if(_lastconxresult == WL_NO_SSID_AVAIL){
+        // connect failed, or ap not found
+        str.replace(FPSTR(T_c),"D");
+        str.replace(FPSTR(T_r),FPSTR(HTTP_STATUS_OFFNOAP));
+      }
+      else if(_lastconxresult == WL_CONNECT_FAILED){
+        // connect failed
+        str.replace(FPSTR(T_c),"D");
+        str.replace(FPSTR(T_r),FPSTR(HTTP_STATUS_OFFFAIL));
+      }
+      else{
+        str.replace(FPSTR(T_c),"");
+        str.replace(FPSTR(T_r),"");
+      } 
+    }
+  }
+  else {
+    str = FPSTR(HTTP_STATUS_NONE);
+  }
+  page += str;
+}
+
+// PUBLIC
+
+// METHODS
+
+/**
+ * reset wifi settings, clean stored ap password
+ */
+
+/**
+ * [stopConfigPortal description]
+ * @return {[type]} [description]
+ */
+bool WiFiManager::stopConfigPortal(){
+  if(_configPortalIsBlocking){
+    abort = true;
+    return true;
+  }
+  return shutdownConfigPortal();  
+}
+
+/**
+ * disconnect
+ * @access public
+ * @since $dev
+ * @return bool success
+ */
+bool WiFiManager::disconnect(){
+  if(WiFi.status() != WL_CONNECTED){
+    DEBUG_WM(DEBUG_VERBOSE,"Disconnecting: Not connected");
+    return false;
+  }  
+  DEBUG_WM("Disconnecting");
+  return WiFi_Disconnect();
+}
+
+/**
+ * reboot the device
+ * @access public
+ */
+void WiFiManager::reboot(){
+  DEBUG_WM("Restarting");
+  ESP.restart();
+}
+
+/**
+ * reboot the device
+ * @access public
+ */
+bool WiFiManager::erase(){
+  return erase(false);
+}
+
+bool WiFiManager::erase(bool opt){
+  DEBUG_WM("Erasing");
+
+  #if defined(ESP32) && ((defined(WM_ERASE_NVS) || defined(nvs_flash_h)))
+    // if opt true, do nvs erase
+    if(opt){
+      DEBUG_WM("Erasing NVS");
+      int err;
+      esp_err_t err;
+      err = nvs_flash_init();
+      DEBUG_WM(DEBUG_VERBOSE,"nvs_flash_init: ",err!=ESP_OK ? (String)err : "Success");
+      err = nvs_flash_erase();
+      DEBUG_WM(DEBUG_VERBOSE,"nvs_flash_erase: ", err!=ESP_OK ? (String)err : "Success");
+      return err == ESP_OK;
+    }
+  #elif defined(ESP8266) && defined(spiffs_api_h)
+    if(opt){
+      bool ret = false;
+      if(SPIFFS.begin()){
+        DEBUG_WM("Erasing SPIFFS");
+        bool ret = SPIFFS.format();
+        DEBUG_WM(DEBUG_VERBOSE,"spiffs erase: ",ret ? "Success" : "ERROR");
+      } else DEBUG_WM("[ERROR] Could not start SPIFFS");
+      return ret;
+    }
+  #else
+    (void)opt;
+  #endif
+
+  DEBUG_WM("Erasing WiFi Config");
+  return WiFi_eraseConfig();
+}
+
+/**
+ * [resetSettings description]
+ * ERASES STA CREDENTIALS
+ * @access public
+ */
+void WiFiManager::resetSettings() {
+  DEBUG_WM(F("SETTINGS ERASED"));
+  WiFi_enableSTA(true,true); // must be sta to disconnect erase
+  
+  if (_resetcallback != NULL)
+      _resetcallback();
+  
+  #ifdef ESP32
+    WiFi.disconnect(true,true);
+  #else
+    WiFi.persistent(true);
+    WiFi.disconnect(true);
+    WiFi.persistent(false);
+  #endif  
+}
+
+// SETTERS
+
+/**
+ * [setTimeout description]
+ * @access public
+ * @param {[type]} unsigned long seconds [description]
+ */
+void WiFiManager::setTimeout(unsigned long seconds) {
+  setConfigPortalTimeout(seconds);
+}
+
+/**
+ * [setConfigPortalTimeout description]
+ * @access public
+ * @param {[type]} unsigned long seconds [description]
+ */
+void WiFiManager::setConfigPortalTimeout(unsigned long seconds) {
+  _configPortalTimeout = seconds * 1000;
+}
+
+/**
+ * [setConnectTimeout description]
+ * @access public
+ * @param {[type]} unsigned long seconds [description]
+ */
+void WiFiManager::setConnectTimeout(unsigned long seconds) {
+  _connectTimeout = seconds * 1000;
+}
+/**
+ * toggle _cleanconnect, always disconnect before connecting
+ * @param {[type]} bool enable [description]
+ */
+void WiFiManager::setCleanConnect(bool enable){
+  _cleanConnect = enable;
+}
+
+/**
+ * [setConnectTimeout description
+ * @access public
+ * @param {[type]} unsigned long seconds [description]
+ */
+void WiFiManager::setSaveConnectTimeout(unsigned long seconds) {
+  _saveTimeout = seconds * 1000;
+}
+
+/**
+ * [setDebugOutput description]
+ * @access public
+ * @param {[type]} boolean debug [description]
+ */
+void WiFiManager::setDebugOutput(boolean debug) {
+  _debug = debug;
+  if(_debug && _debugLevel == DEBUG_DEV) debugPlatformInfo();
+}
+
+/**
+ * [setAPStaticIPConfig description]
+ * @access public
+ * @param {[type]} IPAddress ip [description]
+ * @param {[type]} IPAddress gw [description]
+ * @param {[type]} IPAddress sn [description]
+ */
+void WiFiManager::setAPStaticIPConfig(IPAddress ip, IPAddress gw, IPAddress sn) {
+  _ap_static_ip = ip;
+  _ap_static_gw = gw;
+  _ap_static_sn = sn;
+}
+
+/**
+ * [setSTAStaticIPConfig description]
+ * @access public
+ * @param {[type]} IPAddress ip [description]
+ * @param {[type]} IPAddress gw [description]
+ * @param {[type]} IPAddress sn [description]
+ */
+void WiFiManager::setSTAStaticIPConfig(IPAddress ip, IPAddress gw, IPAddress sn) {
+  _sta_static_ip = ip;
+  _sta_static_gw = gw;
+  _sta_static_sn = sn;
+}
+
+/**
+ * [setSTAStaticIPConfig description]
+ * @since $dev
+ * @access public
+ * @param {[type]} IPAddress ip [description]
+ * @param {[type]} IPAddress gw [description]
+ * @param {[type]} IPAddress sn [description]
+ * @param {[type]} IPAddress dns [description]
+ */
+void WiFiManager::setSTAStaticIPConfig(IPAddress ip, IPAddress gw, IPAddress sn, IPAddress dns) {
+  setSTAStaticIPConfig(ip,gw,sn);
+  _sta_static_dns = dns;
+}
+
+/**
+ * [setMinimumSignalQuality description]
+ * @access public
+ * @param {[type]} int quality [description]
+ */
+void WiFiManager::setMinimumSignalQuality(int quality) {
+  _minimumQuality = quality;
+}
+
+/**
+ * [setBreakAfterConfig description]
+ * @access public
+ * @param {[type]} boolean shouldBreak [description]
+ */
+void WiFiManager::setBreakAfterConfig(boolean shouldBreak) {
+  _shouldBreakAfterConfig = shouldBreak;
+}
+
+/**
+ * setAPCallback, set a callback when softap is started
+ * @access public 
+ * @param {[type]} void (*func)(WiFiManager* wminstance)
+ */
+void WiFiManager::setAPCallback( std::function<void(WiFiManager*)> func ) {
+  _apcallback = func;
+}
+
+/**
+ * setWebServerCallback, set a callback after webserver is reset, and before routes are setup
+ * if we set webserver handlers before wm, they are used and wm is not by esp webserver
+ * on events cannot be overrided once set, and are not mutiples
+ * @access public 
+ * @param {[type]} void (*func)(void)
+ */
+void WiFiManager::setWebServerCallback( std::function<void()> func ) {
+  _webservercallback = func;
+}
+
+/**
+ * setSaveConfigCallback, set a save config callback after closing configportal
+ * @note calls only if wifi is saved or changed, or setBreakAfterConfig(true)
+ * @access public
+ * @param {[type]} void (*func)(void)
+ */
+void WiFiManager::setSaveConfigCallback( std::function<void()> func ) {
+  _savewificallback = func;
+}
+
+/**
+ * setConfigResetCallback, set a callback to occur when a resetSettings() occurs
+ * @access public
+ * @param {[type]} void(*func)(void)
+ */
+void WiFiManager::setConfigResetCallback( std::function<void()> func ) {
+    _resetcallback = func;
+}
+
+/**
+ * setSaveParamsCallback, set a save params callback on params save in wifi or params pages
+ * @access public
+ * @param {[type]} void (*func)(void)
+ */
+void WiFiManager::setSaveParamsCallback( std::function<void()> func ) {
+  _saveparamscallback = func;
+}
+
+/**
+ * setPreSaveConfigCallback, set a callback to fire before saving wifi or params
+ * @access public
+ * @param {[type]} void (*func)(void)
+ */
+void WiFiManager::setPreSaveConfigCallback( std::function<void()> func ) {
+  _presavecallback = func;
+}
+
+/**
+ * set custom head html
+ * custom element will be added to head, eg. new style tag etc.
+ * @access public
+ * @param char element
+ */
+void WiFiManager::setCustomHeadElement(const char* element) {
+  _customHeadElement = element;
+}
+
+/**
+ * toggle wifiscan hiding of duplicate ssid names
+ * if this is false, wifiscan will remove duplicat Access Points - defaut true
+ * @access public
+ * @param boolean removeDuplicates [true]
+ */
+void WiFiManager::setRemoveDuplicateAPs(boolean removeDuplicates) {
+  _removeDuplicateAPs = removeDuplicates;
+}
+
+/**
+ * toggle configportal blocking loop
+ * if enabled, then the configportal will enter a blocking loop and wait for configuration
+ * if disabled use with process() to manually process webserver
+ * @since $dev
+ * @access public
+ * @param boolean shoudlBlock [false]
+ */
+void WiFiManager::setConfigPortalBlocking(boolean shoudlBlock) {
+  _configPortalIsBlocking = shoudlBlock;
+}
+
+/**
+ * toggle restore persistent, track internally
+ * sets ESP wifi.persistent so we can remember it and restore user preference on destruct
+ * there is no getter in esp8266 platform prior to https://github.com/esp8266/Arduino/pull/3857
+ * @since $dev
+ * @access public
+ * @param boolean persistent [true]
+ */
+void WiFiManager::setRestorePersistent(boolean persistent) {
+  _userpersistent = persistent;
+  if(!persistent) DEBUG_WM(F("persistent is off"));
+}
+
+/**
+ * toggle showing static ip form fields
+ * if enabled, then the static ip, gateway, subnet fields will be visible, even if not set in code
+ * @since $dev
+ * @access public
+ * @param boolean alwaysShow [false]
+ */
+void WiFiManager::setShowStaticFields(boolean alwaysShow){
+  if(_disableIpFields) _staShowStaticFields = alwaysShow ? 1 : -1;
+  else _staShowStaticFields = alwaysShow ? 1 : 0;
+}
+
+/**
+ * toggle showing dns fields
+ * if enabled, then the dns1 field will be visible, even if not set in code
+ * @since $dev
+ * @access public
+ * @param boolean alwaysShow [false]
+ */
+void WiFiManager::setShowDnsFields(boolean alwaysShow){
+  if(_disableIpFields) _staShowDns = alwaysShow ? 1 : -1;
+  _staShowDns = alwaysShow ? 1 : 0;
+}
+
+/**
+ * toggle showing password in wifi password field
+ * if not enabled, placeholder will be S_passph
+ * @since $dev
+ * @access public
+ * @param boolean alwaysShow [false]
+ */
+void WiFiManager::setShowPassword(boolean show){
+  _showPassword = show;
+}
+
+/**
+ * toggle captive portal
+ * if enabled, then devices that use captive portal checks will be redirected to root
+ * if not you will automatically have to navigate to ip [192.168.4.1]
+ * @since $dev
+ * @access public
+ * @param boolean enabled [true]
+ */
+void WiFiManager::setCaptivePortalEnable(boolean enabled){
+  _enableCaptivePortal = enabled;
+}
+
+/**
+ * toggle wifi autoreconnect policy
+ * if enabled, then wifi will autoreconnect automatically always
+ * On esp8266 we force this on when autoconnect is called, see notes
+ * On esp32 this is handled on SYSTEM_EVENT_STA_DISCONNECTED since it does not exist in core yet
+ * @since $dev
+ * @access public
+ * @param boolean enabled [true]
+ */
+void WiFiManager::setWiFiAutoReconnect(boolean enabled){
+  _wifiAutoReconnect = enabled;
+}
+
+/**
+ * toggle configportal timeout wait for station client
+ * if enabled, then the configportal will start timeout when no stations are connected to softAP
+ * disabled by default as rogue stations can keep it open if there is no auth
+ * @since $dev
+ * @access public
+ * @param boolean enabled [false]
+ */
+void WiFiManager::setAPClientCheck(boolean enabled){
+  _apClientCheck = enabled;
+}
+
+/**
+ * toggle configportal timeout wait for web client
+ * if enabled, then the configportal will restart timeout when client requests come in
+ * @since $dev
+ * @access public
+ * @param boolean enabled [true]
+ */
+void WiFiManager::setWebPortalClientCheck(boolean enabled){
+  _webClientCheck = enabled;
+}
+
+/**
+ * toggle wifiscan percentages or quality icons
+ * @since $dev
+ * @access public
+ * @param boolean enabled [false]
+ */
+void WiFiManager::setScanDispPerc(boolean enabled){
+  _scanDispOptions = enabled;
+}
+
+/**
+ * toggle configportal if autoconnect failed
+ * if enabled, then the configportal will be activated on autoconnect failure
+ * @since $dev
+ * @access public
+ * @param boolean enabled [true]
+ */
+void WiFiManager::setEnableConfigPortal(boolean enable)
+{
+    _enableConfigPortal = enable;
+}
+
+
+/**
+ * set the hostname (dhcp client id)
+ * @since $dev
+ * @access public
+ * @param  char* hostname 32 character hostname to use for sta+ap in esp32, sta in esp8266
+ * @return bool false if hostname is not valid
+ */
+bool  WiFiManager::setHostname(const char * hostname){
+  //@todo max length 32
+  _hostname = hostname;
+  return true;
+}
+
+/**
+ * set the soft ao channel, ignored if channelsync is true and connected
+ * @param int32_t   wifi channel, 0 to disable
+ */
+void WiFiManager::setWiFiAPChannel(int32_t channel){
+  _apChannel = channel;
+}
+
+/**
+ * set the soft ap hidden
+ * @param bool   wifi ap hidden, default is false
+ */
+void WiFiManager::setWiFiAPHidden(bool hidden){
+  _apHidden = hidden;
+}
+
+
+/**
+ * toggle showing erase wifi config button on info page
+ * @param boolean enabled
+ */
+void WiFiManager::setShowInfoErase(boolean enabled){
+  _showInfoErase = enabled;
+}
+
+/**
+ * set menu items and order
+ * if param is present in menu , params will be removed from wifi page automatically
+ * eg.
+ *  const char * menu[] = {"wifi","setup","sep","info","exit"};
+ *  WiFiManager.setMenu(menu);
+ * @since $dev
+ * @param uint8_t menu[] array of menu ids
+ */
+void WiFiManager::setMenu(const char * menu[], uint8_t size){
+  // DEBUG_WM(DEBUG_VERBOSE,"setmenu array");
+  _menuIds.clear();
+  for(size_t i = 0; i < size; i++){
+    for(size_t j = 0; j < _nummenutokens; j++){
+      if(menu[i] == _menutokens[j]){
+        if((String)menu[i] == "param") _paramsInWifi = false; // param auto flag
+        _menuIds.push_back(j);
+      }
+    }
+  }
+  DEBUG_WM(getMenuOut());
+}
+
+/**
+ * setMenu with vector
+ * eg.
+ * std::vector<const char *> menu = {"wifi","setup","sep","info","exit"};
+ * WiFiManager.setMenu(menu);
+ * tokens can be found in _menutokens array in strings_en.h
+ * @shiftIncrement $dev
+ * @param {[type]} std::vector<const char *>& menu [description]
+ */
+void WiFiManager::setMenu(std::vector<const char *>& menu){
+  // DEBUG_WM(DEBUG_VERBOSE,"setmenu vector");
+  _menuIds.clear();
+  for(auto menuitem : menu ){
+    for(size_t j = 0; j < _nummenutokens; j++){
+      if(menuitem == _menutokens[j]){
+        if((String)menuitem == "param") _paramsInWifi = false; // param auto flag
+        _menuIds.push_back(j);
+      }
+    }
+  }
+  DEBUG_WM(getMenuOut());
+}
+
+
+/**
+ * set params as sperate page not in wifi
+ * NOT COMPATIBLE WITH setMenu! @todo scan menuids and insert param after wifi or something
+ * @param bool enable 
+ * @since $dev
+ */
+void WiFiManager::setParamsPage(bool enable){
+  _paramsInWifi  = !enable;
+  setMenu(enable ? _menuIdsParams : _menuIdsDefault);
+}
+
+// GETTERS
+
+/**
+ * get config portal AP SSID
+ * @since 0.0.1
+ * @access public
+ * @return String the configportal ap name
+ */
+String WiFiManager::getConfigPortalSSID() {
+  return _apName;
+}
+
+/**
+ * return the last known connection result
+ * logged on autoconnect and wifisave, can be used to check why failed
+ * get as readable string with getWLStatusString(getLastConxResult);
+ * @since $dev
+ * @access public
+ * @return bool return wl_status codes
+ */
+uint8_t WiFiManager::getLastConxResult(){
+  return _lastconxresult;
+}
+
+/**
+ * check if wifi has a saved ap or not
+ * @since $dev
+ * @access public
+ * @return bool true if a saved ap config exists
+ */
+bool WiFiManager::getWiFiIsSaved(){
+  return WiFi_hasAutoConnect();
+}
+
+String WiFiManager::getDefaultAPName(){
+  String hostString = String(WIFI_getChipId(),HEX);
+  hostString.toUpperCase();
+  // char hostString[16] = {0};
+  // sprintf(hostString, "%06X", ESP.getChipId());  
+  return _wifissidprefix + "_" + hostString;
+}
+
+/**
+ * setCountry
+ * @since $dev
+ * @param String cc country code, must be defined in WiFiSetCountry, US, JP, CN
+ */
+void WiFiManager::setCountry(String cc){
+  _wificountry = cc;
+}
+
+/**
+ * setClass
+ * @param String str body class string
+ */
+void WiFiManager::setClass(String str){
+  _bodyClass = str;
+}
+
+// HELPERS
+
+/**
+ * getWiFiSSID
+ * @since $dev
+ * @param bool persistent
+ * @return String
+ */
+String WiFiManager::getWiFiSSID(bool persistent){
+  return WiFi_SSID(persistent);
+}
+
+/**
+ * getWiFiPass
+ * @since $dev
+ * @param bool persistent
+ * @return String
+ */
+String WiFiManager::getWiFiPass(bool persistent){
+  return WiFi_psk(persistent);
+} 
+
+// DEBUG
+// @todo fix DEBUG_WM(0,0);
+template <typename Generic>
+void WiFiManager::DEBUG_WM(Generic text) {
+  DEBUG_WM(DEBUG_NOTIFY,text,"");
+}
+
+template <typename Generic>
+void WiFiManager::DEBUG_WM(wm_debuglevel_t level,Generic text) {
+  if(_debugLevel >= level) DEBUG_WM(level,text,"");
+}
+
+template <typename Generic, typename Genericb>
+void WiFiManager::DEBUG_WM(Generic text,Genericb textb) {
+  DEBUG_WM(DEBUG_NOTIFY,text,textb);
+}
+
+template <typename Generic, typename Genericb>
+void WiFiManager::DEBUG_WM(wm_debuglevel_t level,Generic text,Genericb textb) {
+  if(!_debug || _debugLevel < level) return;
+
+  if(_debugLevel >= DEBUG_MAX){
+    uint32_t free;
+    uint16_t max;
+    uint8_t frag;
+    #ifdef ESP8266
+    ESP.getHeapStats(&free, &max, &frag);
+    _debugPort.printf("[MEM] free: %5d | max: %5d | frag: %3d%% \n", free, max, frag);
+    #elif defined ESP32
+    // total_free_bytes;      ///<  Total free bytes in the heap. Equivalent to multi_free_heap_size().
+    // total_allocated_bytes; ///<  Total bytes allocated to data in the heap.
+    // largest_free_block;    ///<  Size of largest free block in the heap. This is the largest malloc-able size.
+    // minimum_free_bytes;    ///<  Lifetime minimum free heap size. Equivalent to multi_minimum_free_heap_size().
+    // allocated_blocks;      ///<  Number of (variable size) blocks allocated in the heap.
+    // free_blocks;           ///<  Number of (variable size) free blocks in the heap.
+    // total_blocks;          ///<  Total number of (variable size) blocks in the heap.
+    multi_heap_info_t info;
+    heap_caps_get_info(&info, MALLOC_CAP_INTERNAL);
+    free = info.total_free_bytes;
+    max  = info.largest_free_block;
+    frag = 100 - (max * 100) / free;
+    _debugPort.printf("[MEM] free: %5d | max: %5d | frag: %3d%% \n", free, max, frag);    
+    #endif
+  }
+  _debugPort.print("*WM: ");
+  if(_debugLevel == DEBUG_DEV) _debugPort.print("["+(String)level+"] ");
+  _debugPort.print(text);
+  if(textb){
+    _debugPort.print(" ");
+    _debugPort.print(textb);
+  }
+  _debugPort.println();
+}
+
+/**
+ * [debugSoftAPConfig description]
+ * @access public
+ * @return {[type]} [description]
+ */
+void WiFiManager::debugSoftAPConfig(){
+    wifi_country_t country;
+    
+    #ifdef ESP8266
+      softap_config config;
+      wifi_softap_get_config(&config);
+      wifi_get_country(&country);
+    #elif defined(ESP32)
+      wifi_config_t conf_config;
+      esp_wifi_get_config(WIFI_IF_AP, &conf_config); // == ESP_OK
+      wifi_ap_config_t config = conf_config.ap;
+      esp_wifi_get_country(&country);
+    #endif
+
+    DEBUG_WM(F("SoftAP Configuration"));
+    DEBUG_WM(FPSTR(D_HR));
+    DEBUG_WM(F("ssid:            "),(char *) config.ssid);
+    DEBUG_WM(F("password:        "),(char *) config.password);
+    DEBUG_WM(F("ssid_len:        "),config.ssid_len);
+    DEBUG_WM(F("channel:         "),config.channel);
+    DEBUG_WM(F("authmode:        "),config.authmode);
+    DEBUG_WM(F("ssid_hidden:     "),config.ssid_hidden);
+    DEBUG_WM(F("max_connection:  "),config.max_connection);
+    DEBUG_WM(F("country:         "),(String)country.cc);
+    DEBUG_WM(F("beacon_interval: "),(String)config.beacon_interval + "(ms)");
+    DEBUG_WM(FPSTR(D_HR));
+}
+
+/**
+ * [debugPlatformInfo description]
+ * @access public
+ * @return {[type]} [description]
+ */
+void WiFiManager::debugPlatformInfo(){
+  #ifdef ESP8266
+    system_print_meminfo();
+    DEBUG_WM(F("getCoreVersion():         "),ESP.getCoreVersion());
+    DEBUG_WM(F("system_get_sdk_version(): "),system_get_sdk_version());
+    DEBUG_WM(F("system_get_boot_version():"),system_get_boot_version());
+    DEBUG_WM(F("getFreeHeap():            "),(String)ESP.getFreeHeap());
+  #elif defined(ESP32)
+    size_t freeHeap = heap_caps_get_free_size(MALLOC_CAP_8BIT);
+    DEBUG_WM("Free heap:       ", freeHeap);
+    DEBUG_WM("ESP-IDF version: ", esp_get_idf_version());
+  #endif
+}
+
+int WiFiManager::getRSSIasQuality(int RSSI) {
+  int quality = 0;
+
+  if (RSSI <= -100) {
+    quality = 0;
+  } else if (RSSI >= -50) {
+    quality = 100;
+  } else {
+    quality = 2 * (RSSI + 100);
+  }
+  return quality;
+}
+
+/** Is this an IP? */
+boolean WiFiManager::isIp(String str) {
+  for (size_t i = 0; i < str.length(); i++) {
+    int c = str.charAt(i);
+    if (c != '.' && (c < '0' || c > '9')) {
+      return false;
+    }
+  }
+  return true;
+}
+
+/** IP to String? */
+String WiFiManager::toStringIp(IPAddress ip) {
+  String res = "";
+  for (int i = 0; i < 3; i++) {
+    res += String((ip >> (8 * i)) & 0xFF) + ".";
+  }
+  res += String(((ip >> 8 * 3)) & 0xFF);
+  return res;
+}
+
+boolean WiFiManager::validApPassword(){
+  // check that ap password is valid, return false
+  if (_apPassword == NULL) _apPassword = "";
+  if (_apPassword != "") {
+    if (_apPassword.length() < 8 || _apPassword.length() > 63) {
+      DEBUG_WM(F("AccessPoint set password is INVALID or <8 chars"));
+      _apPassword = "";
+      return false; // @todo FATAL or fallback to empty ?
+    }
+    DEBUG_WM(DEBUG_VERBOSE,F("AccessPoint set password is VALID"));
+    DEBUG_WM(_apPassword);
+  }
+  return true;
+}
+
+/**
+ * encode htmlentities
+ * @since $dev
+ * @param  string str  string to replace entities
+ * @return string      encoded string
+ */
+String WiFiManager::htmlEntities(String str) {
+  str.replace("&","&amp;");
+  str.replace("<","&lt;");
+  str.replace(">","&gt;");
+  // str.replace("'","&#39;");
+  // str.replace("\"","&quot;");
+  // str.replace("/": "&#x2F;");
+  // str.replace("`": "&#x60;");
+  // str.replace("=": "&#x3D;");
+return str;
+}
+
+/**
+ * [getWLStatusString description]
+ * @access public
+ * @param  {[type]} uint8_t status        [description]
+ * @return {[type]}         [description]
+ */
+String WiFiManager::getWLStatusString(uint8_t status){
+  if(status <= 7) return WIFI_STA_STATUS[status];
+  return FPSTR(S_NA);
+}
+
+String WiFiManager::encryptionTypeStr(uint8_t authmode) {
+  // DEBUG_WM("enc_tye: ",authmode);
+  return AUTH_MODE_NAMES[authmode];
+}
+
+String WiFiManager::getModeString(uint8_t mode){
+  if(mode <= 3) return WIFI_MODES[mode];
+  return FPSTR(S_NA);
+}
+
+bool WiFiManager::WiFiSetCountry(){
+  if(_wificountry == "") return false; // skip not set
+  bool ret = false;
+  #ifdef ESP32
+  // @todo check if wifi is init, no idea how, doesnt seem to be exposed atm ( might be now! )
+       if(WiFi.getMode() == WIFI_MODE_NULL); // exception if wifi not init!
+  else if(_wificountry == "US") ret = esp_wifi_set_country(&WM_COUNTRY_US) == ESP_OK;
+  else if(_wificountry == "JP") ret = esp_wifi_set_country(&WM_COUNTRY_JP) == ESP_OK;
+  else if(_wificountry == "CN") ret = esp_wifi_set_country(&WM_COUNTRY_CN) == ESP_OK;
+  else DEBUG_WM(DEBUG_ERROR,"[ERROR] country code not found");
+  
+  #elif defined(ESP8266)
+       // if(WiFi.getMode() == WIFI_OFF); // exception if wifi not init!
+       if(_wificountry == "US") ret = wifi_set_country((wifi_country_t*)&WM_COUNTRY_US);
+  else if(_wificountry == "JP") ret = wifi_set_country((wifi_country_t*)&WM_COUNTRY_JP);
+  else if(_wificountry == "CN") ret = wifi_set_country((wifi_country_t*)&WM_COUNTRY_CN);
+  else DEBUG_WM(DEBUG_ERROR,"[ERROR] country code not found");
+  #endif
+  
+  if(ret) DEBUG_WM(DEBUG_VERBOSE,"esp_wifi_set_country: " + _wificountry);
+  else DEBUG_WM(DEBUG_ERROR,"[ERROR] esp_wifi_set_country failed");  
+  return ret;
+}
+
+// set mode ignores WiFi.persistent 
+bool WiFiManager::WiFi_Mode(WiFiMode_t m,bool persistent) {
+    bool ret;
+    #ifdef ESP8266
+      if((wifi_get_opmode() == (uint8) m ) && !persistent) {
+          return true;
+      }
+      ETS_UART_INTR_DISABLE();
+      if(persistent) ret = wifi_set_opmode(m);
+      else ret = wifi_set_opmode_current(m);
+      ETS_UART_INTR_ENABLE();
+    return ret;
+    #elif defined(ESP32)
+      if(persistent && esp32persistent) WiFi.persistent(true);
+      ret = WiFi.mode(m); // @todo persistent check persistant mode , NI
+      if(persistent && esp32persistent) WiFi.persistent(false);
+      return ret;
+    #endif
+}
+bool WiFiManager::WiFi_Mode(WiFiMode_t m) {
+	return WiFi_Mode(m,false);
+}
+
+// sta disconnect without persistent
+bool WiFiManager::WiFi_Disconnect() {
+    #ifdef ESP8266
+      if((WiFi.getMode() & WIFI_STA) != 0) {
+          bool ret;
+          DEBUG_WM(DEBUG_DEV,F("WIFI station disconnect"));
+          ETS_UART_INTR_DISABLE(); // @todo probably not needed
+          ret = wifi_station_disconnect();
+          ETS_UART_INTR_ENABLE();        
+          return ret;
+      }
+    #elif defined(ESP32)
+      DEBUG_WM(DEBUG_DEV,F("WIFI station disconnect"));
+      return WiFi.disconnect(); // not persistent atm
+    #endif
+    return false;
+}
+
+// toggle STA without persistent
+bool WiFiManager::WiFi_enableSTA(bool enable,bool persistent) {
+    DEBUG_WM(DEBUG_DEV,F("WiFi station enable"));
+    #ifdef ESP8266
+      WiFiMode_t newMode;
+      WiFiMode_t currentMode = WiFi.getMode();
+      bool isEnabled         = (currentMode & WIFI_STA) != 0;
+      if(enable) newMode     = (WiFiMode_t)(currentMode | WIFI_STA);
+      else newMode           = (WiFiMode_t)(currentMode & (~WIFI_STA));
+
+      if((isEnabled != enable) || persistent) {
+          if(enable) {
+          	if(persistent) DEBUG_WM(DEBUG_DEV,F("enableSTA PERSISTENT ON"));
+              return WiFi_Mode(newMode,persistent);
+          }
+          else {
+              return WiFi_Mode(newMode,persistent);
+          }
+      } else {
+          return true;
+      }
+    #elif defined(ESP32)
+      bool ret;
+      if(persistent && esp32persistent) WiFi.persistent(true);
+      ret =  WiFi.enableSTA(enable); // @todo handle persistent when it is implemented in platform
+      if(persistent && esp32persistent) WiFi.persistent(false);
+      return ret;
+    #endif
+}
+bool WiFiManager::WiFi_enableSTA(bool enable) {
+	return WiFi_enableSTA(enable,false);
+}
+
+bool WiFiManager::WiFi_eraseConfig() {
+    #ifdef ESP8266
+      #ifndef WM_FIXERASECONFIG 
+        return ESP.eraseConfig();
+      #else
+        // erase config BUG replacement
+        // https://github.com/esp8266/Arduino/pull/3635
+        const size_t cfgSize = 0x4000;
+        size_t cfgAddr = ESP.getFlashChipSize() - cfgSize;
+
+        for (size_t offset = 0; offset < cfgSize; offset += SPI_FLASH_SEC_SIZE) {
+            if (!ESP.flashEraseSector((cfgAddr + offset) / SPI_FLASH_SEC_SIZE)) {
+                return false;
+            }
+        }
+        return true;
+      #endif
+    #elif defined(ESP32)
+      bool ret;
+      WiFi.mode(WIFI_AP_STA); // cannot erase if not in STA mode !
+      WiFi.persistent(true);
+      ret = WiFi.disconnect(true,true);
+      WiFi.persistent(false);
+      return ret;
+    #endif
+}
+
+uint8_t WiFiManager::WiFi_softap_num_stations(){
+  #ifdef ESP8266
+    return wifi_softap_get_station_num();
+  #elif defined(ESP32)
+    return WiFi.softAPgetStationNum();
+  #endif
+}
+
+bool WiFiManager::WiFi_hasAutoConnect(){
+  return WiFi_SSID(true) != "";
+}
+
+String WiFiManager::WiFi_SSID(bool persistent) const{
+
+    #ifdef ESP8266
+    struct station_config conf;
+    if(persistent) wifi_station_get_config_default(&conf);
+    else wifi_station_get_config(&conf);
+
+    char tmp[33]; //ssid can be up to 32chars, => plus null term
+    memcpy(tmp, conf.ssid, sizeof(conf.ssid));
+    tmp[32] = 0; //nullterm in case of 32 char ssid
+    return String(reinterpret_cast<char*>(tmp));
+    
+    #elif defined(ESP32)
+    if(persistent){
+      wifi_config_t conf;
+      esp_wifi_get_config(WIFI_IF_STA, &conf);
+      return String(reinterpret_cast<const char*>(conf.sta.ssid));
+    }
+    else {
+      if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
+          return String();
+      }
+      wifi_ap_record_t info;
+      if(!esp_wifi_sta_get_ap_info(&info)) {
+          return String(reinterpret_cast<char*>(info.ssid));
+      }
+      return String();
+    }
+    #endif
+}
+
+String WiFiManager::WiFi_psk(bool persistent) const {
+    #ifdef ESP8266
+    struct station_config conf;
+
+    if(persistent) wifi_station_get_config_default(&conf);
+    else wifi_station_get_config(&conf);
+
+    char tmp[65]; //psk is 64 bytes hex => plus null term
+    memcpy(tmp, conf.password, sizeof(conf.password));
+    tmp[64] = 0; //null term in case of 64 byte psk
+    return String(reinterpret_cast<char*>(tmp));
+    
+    #elif defined(ESP32)
+    // only if wifi is init
+    if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
+      return String();
+    }
+    wifi_config_t conf;
+    esp_wifi_get_config(WIFI_IF_STA, &conf);
+    return String(reinterpret_cast<char*>(conf.sta.password));
+    #endif
+}
+
+#ifdef ESP32
+void WiFiManager::WiFiEvent(WiFiEvent_t event,system_event_info_t info){
+    if(!_hasBegun){
+      // DEBUG_WM(DEBUG_VERBOSE,"[ERROR] WiFiEvent, not ready");
+      return;
+    } 
+    // DEBUG_WM(DEBUG_VERBOSE,"[EVENT]",event);
+    if(event == SYSTEM_EVENT_STA_DISCONNECTED){
+      DEBUG_WM(DEBUG_VERBOSE,"[EVENT] WIFI_REASON:",info.disconnected.reason);
+      if(info.disconnected.reason == WIFI_REASON_AUTH_EXPIRE || info.disconnected.reason == WIFI_REASON_AUTH_FAIL){
+        _lastconxresulttmp = 7; // hack in wrong password internally, sdk emit WIFI_REASON_AUTH_EXPIRE on some routers on auth_fail
+      } else _lastconxresulttmp = WiFi.status();
+      if(info.disconnected.reason == WIFI_REASON_NO_AP_FOUND) DEBUG_WM(DEBUG_VERBOSE,"[EVENT] WIFI_REASON: NO_AP_FOUND");
+      #ifdef esp32autoreconnect
+        DEBUG_WM(DEBUG_VERBOSE,"[Event] SYSTEM_EVENT_STA_DISCONNECTED, reconnecting");
+        WiFi.reconnect();
+      #endif
+  }
+  else if(event == SYSTEM_EVENT_SCAN_DONE){
+    uint16_t scans = WiFi.scanComplete();
+    WiFi_scanComplete(scans);
+  }
+}
+#endif
+
+void WiFiManager::WiFi_autoReconnect(){
+  #ifdef ESP8266
+    WiFi.setAutoReconnect(_wifiAutoReconnect);
+  #elif defined(ESP32)
+    // if(_wifiAutoReconnect){
+      // @todo move to seperate method, used for event listener now
+      DEBUG_WM(DEBUG_VERBOSE,"ESP32 event handler enabled");
+      using namespace std::placeholders;
+      WiFi.onEvent(std::bind(&WiFiManager::WiFiEvent,this,_1,_2));
+    // }
+  #endif
+}
+
+#endif

+ 549 - 0
lib/WiFiManager-development/WiFiManager.h

@@ -0,0 +1,549 @@
+/**
+ * WiFiManager.h
+ * 
+ * WiFiManager, a library for the ESP8266/Arduino platform
+ * for configuration of WiFi credentials using a Captive Portal
+ * 
+ * @author Creator tzapu
+ * @author tablatronix
+ * @version 0.0.0
+ * @license MIT
+ */
+
+
+#ifndef WiFiManager_h
+#define WiFiManager_h
+
+#if defined(ESP8266) || defined(ESP32)
+
+#ifdef ESP8266
+#include <core_version.h>
+#endif
+
+#include <vector>
+
+// #define WM_MDNS            // also set MDNS with sethostname
+// #define WM_FIXERASECONFIG  // use erase flash fix
+// #define WM_ERASE_NVS       // esp32 erase(true) will erase NVS 
+// #define WM_RTC             // esp32 info page will include reset reasons
+
+#ifdef ARDUINO_ESP8266_RELEASE_2_3_0
+#warning "ARDUINO_ESP8266_RELEASE_2_3_0, some WM features disabled" 
+#define WM_NOASYNC         // esp8266 no async scan wifi
+#endif
+
+// #include "soc/efuse_reg.h" // include to add efuse chip rev to info, getChipRevision() is almost always the same though, so not sure why it matters.
+
+// #define esp32autoreconnect    // implement esp32 autoreconnect event listener kludge, @DEPRECATED
+// autoreconnect is WORKING https://github.com/espressif/arduino-esp32/issues/653#issuecomment-405604766
+
+#define WM_WEBSERVERSHIM      // use webserver shim lib
+
+#ifdef ESP8266
+
+    extern "C" {
+      #include "user_interface.h"
+    }
+    #include <ESP8266WiFi.h>
+    #include <ESP8266WebServer.h>
+
+    #ifdef WM_MDNS
+        #include <ESP8266mDNS.h>
+    #endif
+
+    #define WIFI_getChipId() ESP.getChipId()
+    #define WM_WIFIOPEN   ENC_TYPE_NONE
+
+#elif defined(ESP32)
+
+    #include <WiFi.h>
+    #include <esp_wifi.h>  
+    
+    #define WIFI_getChipId() (uint32_t)ESP.getEfuseMac()
+    #define WM_WIFIOPEN   WIFI_AUTH_OPEN
+
+    #ifndef WEBSERVER_H
+        #ifdef WM_WEBSERVERSHIM
+            #include <WebServer.h>
+        #else
+            #include <ESP8266WebServer.h>
+            // Forthcoming official ?
+            // https://github.com/esp8266/ESPWebServer
+        #endif
+    #endif
+
+    #ifdef WM_ERASE_NVS
+       #include <nvs.h>
+       #include <nvs_flash.h>
+    #endif
+
+    #ifdef WM_MDNS
+        #include <ESPmDNS.h>
+    #endif
+
+    #ifdef WM_RTC
+        #include <rom/rtc.h>
+    #endif
+
+
+#else
+#endif
+
+#include <DNSServer.h>
+#include <memory>
+#include "strings_en.h"
+
+#ifndef WIFI_MANAGER_MAX_PARAMS
+    #define WIFI_MANAGER_MAX_PARAMS 5 // params will autoincrement and realloc by this amount when max is reached
+#endif
+
+#define WFM_LABEL_BEFORE 1
+#define WFM_LABEL_AFTER 2
+#define WFM_NO_LABEL 0
+
+class WiFiManagerParameter {
+  public:
+    /** 
+        Create custom parameters that can be added to the WiFiManager setup web page
+        @id is used for HTTP queries and must not contain spaces nor other special characters
+    */
+    WiFiManagerParameter();
+    WiFiManagerParameter(const char *custom);
+    WiFiManagerParameter(const char *id, const char *label);
+    WiFiManagerParameter(const char *id, const char *label, const char *defaultValue, int length);
+    WiFiManagerParameter(const char *id, const char *label, const char *defaultValue, int length, const char *custom);
+    WiFiManagerParameter(const char *id, const char *label, const char *defaultValue, int length, const char *custom, int labelPlacement);
+    ~WiFiManagerParameter();
+
+    const char *getID();
+    const char *getValue();
+    const char *getLabel();
+    const char *getPlaceholder(); // @deprecated, use getLabel
+    int         getValueLength();
+    int         getLabelPlacement();
+    const char *getCustomHTML();
+    void        setValue(const char *defaultValue, int length);
+
+  protected:
+    void init(const char *id, const char *label, const char *defaultValue, int length, const char *custom, int labelPlacement);
+
+  private:
+    const char *_id;
+    const char *_label;
+    char       *_value;
+    int         _length;
+    int         _labelPlacement;
+    const char *_customHTML;
+
+    friend class WiFiManager;
+};
+
+
+class WiFiManager
+{
+  public:
+    WiFiManager(Stream& consolePort);
+    WiFiManager();
+    ~WiFiManager();
+    void WiFiManagerInit();
+
+    // auto connect to saved wifi, or custom, and start config portal on failures
+    boolean       autoConnect();
+    boolean       autoConnect(char const *apName, char const *apPassword = NULL);
+
+    //manually start the config portal, autoconnect does this automatically on connect failure
+    boolean       startConfigPortal(); // auto generates apname
+    boolean       startConfigPortal(char const *apName, char const *apPassword = NULL);
+
+    //manually stop the config portal if started manually, stop immediatly if non blocking, flag abort if blocking
+    bool          stopConfigPortal();
+    
+    //manually start the web portal, autoconnect does this automatically on connect failure    
+    void          startWebPortal();
+    //manually stop the web portal if started manually
+    void          stopWebPortal();
+    // Run webserver processing, if setConfigPortalBlocking(false)
+    boolean       process();
+
+    // get the AP name of the config portal, so it can be used in the callback
+    String        getConfigPortalSSID();
+    int           getRSSIasQuality(int RSSI);
+
+    // erase wifi credentials
+    void          resetSettings();
+    // reboot esp
+    void          reboot();
+    // disconnect wifi, without persistent saving or erasing
+    bool          disconnect();
+    // erase esp
+    bool          erase();
+    bool          erase(bool opt);
+
+    //adds a custom parameter, returns false on failure
+    bool          addParameter(WiFiManagerParameter *p);
+    //returns the list of Parameters
+    WiFiManagerParameter** getParameters();
+    // returns the Parameters Count
+    int           getParametersCount();
+
+
+    // SET CALLBACKS
+
+    //called after AP mode and config portal has started
+    void          setAPCallback( std::function<void(WiFiManager*)> func );
+    //called after webserver has started
+    void          setWebServerCallback( std::function<void()> func );
+    //called when settings reset have been triggered
+    void          setConfigResetCallback( std::function<void()> func );
+    //called when wifi settings have been changed and connection was successful ( or setBreakAfterConfig(true) )
+    void          setSaveConfigCallback( std::function<void()> func );
+    //called when settings have been changed and connection was successful
+    void          setSaveParamsCallback( std::function<void()> func );
+    //called when settings before have been changed and connection was successful
+    void          setPreSaveConfigCallback( std::function<void()> func );
+
+
+    //sets timeout before AP,webserver loop ends and exits even if there has been no setup.
+    //useful for devices that failed to connect at some point and got stuck in a webserver loop
+    //in seconds setConfigPortalTimeout is a new name for setTimeout, ! not used if setConfigPortalBlocking
+    void          setConfigPortalTimeout(unsigned long seconds);
+    void          setTimeout(unsigned long seconds); // @deprecated, alias
+
+    //sets timeout for which to attempt connecting, useful if you get a lot of failed connects
+    void          setConnectTimeout(unsigned long seconds);
+    //sets timeout for which to attempt connecting on saves, useful if there are bugs in esp waitforconnectloop
+    void          setSaveConnectTimeout(unsigned long seconds);
+    // toggle debug output
+    void          setDebugOutput(boolean debug);
+    //set min quality percentage to include in scan, defaults to 8% if not specified
+    void          setMinimumSignalQuality(int quality = 8);
+    //sets a custom ip /gateway /subnet configuration
+    void          setAPStaticIPConfig(IPAddress ip, IPAddress gw, IPAddress sn);
+    //sets config for a static IP
+    void          setSTAStaticIPConfig(IPAddress ip, IPAddress gw, IPAddress sn);
+    //sets config for a static IP with DNS
+    void          setSTAStaticIPConfig(IPAddress ip, IPAddress gw, IPAddress sn, IPAddress dns);
+    //if this is set, it will exit after config, even if connection is unsuccessful.
+    void          setBreakAfterConfig(boolean shouldBreak);
+    // if this is set, portal will be blocking and wait until save or exit, 
+    // is false user must manually `process()` to handle config portal,
+    // setConfigPortalTimeout is ignored in this mode, user is responsible for closing configportal
+    void          setConfigPortalBlocking(boolean shouldBlock);
+    //if this is set, customise style
+    void          setCustomHeadElement(const char* element);
+    //if this is true, remove duplicated Access Points - defaut true
+    void          setRemoveDuplicateAPs(boolean removeDuplicates);
+    //setter for ESP wifi.persistent so we can remember it and restore user preference, as WIFi._persistent is protected
+    void          setRestorePersistent(boolean persistent);
+    //if true, always show static net inputs, IP, subnet, gateway, else only show if set via setSTAStaticIPConfig
+    void          setShowStaticFields(boolean alwaysShow);
+    //if true, always show static dns, esle only show if set via setSTAStaticIPConfig
+    void          setShowDnsFields(boolean alwaysShow);
+    // toggle showing the saved wifi password in wifi form, could be a security issue.
+    void          setShowPassword(boolean show);
+    //if false, disable captive portal redirection
+    void          setCaptivePortalEnable(boolean enabled);
+    //if false, timeout captive portal even if a STA client connected to softAP (false), suggest disabling if captiveportal is open
+    void          setAPClientCheck(boolean enabled);
+    //if true, reset timeout when webclient connects (true), suggest disabling if captiveportal is open    
+    void          setWebPortalClientCheck(boolean enabled);
+    // if true, enable autoreconnecting
+    void          setWiFiAutoReconnect(boolean enabled);
+    // if true, wifiscan will show percentage instead of quality icons, until we have better templating
+    void          setScanDispPerc(boolean enabled);
+    // if true (default) then start the config portal from autoConnect if connection failed
+    void          setEnableConfigPortal(boolean enable);
+    // set a custom hostname, sets sta and ap dhcp client id for esp32, and sta for esp8266
+    bool          setHostname(const char * hostname);
+    // show erase wifi onfig button on info page, true
+    void          setShowInfoErase(boolean enabled);
+    // set ap channel
+    void          setWiFiAPChannel(int32_t channel);
+    // set ap hidden
+    void          setWiFiAPHidden(bool hidden); // default false
+    // clean connect, always disconnect before connecting
+    void          setCleanConnect(bool enable); // default false
+
+    // set custom menu
+    // set custom menu items and order
+    void          setMenu(std::vector<const char*>& menu);
+    void          setMenu(const char* menu[], uint8_t size);
+    
+    // add params to its own menu page and remove from wifi, NOT TO BE COMBINED WITH setMenu!
+    void          setParamsPage(bool enable);
+
+    // get last connection result, includes autoconnect and wifisave
+    uint8_t       getLastConxResult();
+    // get a status as string
+    String        getWLStatusString(uint8_t status);    
+    String        getModeString(uint8_t mode);
+    // check if the module has a saved ap to connect to
+    bool          getWiFiIsSaved();
+
+    // helper to get saved ssid, if persistent get stored, else get current if connected
+    String        getWiFiPass(bool persistent = false);
+    // helper to get saved password, if persistent get stored, else get current if connected
+    String        getWiFiSSID(bool persistent = false);
+
+    // debug output the softap config
+    void          debugSoftAPConfig();
+    // debug output platform info and versioning
+    void          debugPlatformInfo();
+    String        htmlEntities(String str);
+    
+    // set the country code for wifi settings
+    void          setCountry(String cc);
+    // set body class (invert)
+    void          setClass(String str);
+    String        getDefaultAPName();
+    
+    std::unique_ptr<DNSServer>        dnsServer;
+
+    #if defined(ESP32) && defined(WM_WEBSERVERSHIM)
+        using WM_WebServer = WebServer;
+    #else
+        using WM_WebServer = ESP8266WebServer;
+    #endif
+    
+    std::unique_ptr<WM_WebServer> server;
+
+  private:
+    std::vector<uint8_t> _menuIds;
+    std::vector<const char *> _menuIdsParams  = {"wifi","param","info","exit"};
+    std::vector<const char *> _menuIdsDefault = {"wifi","info","exit"};
+
+    // ip configs @todo struct ?
+    IPAddress     _ap_static_ip;
+    IPAddress     _ap_static_gw;
+    IPAddress     _ap_static_sn;
+    IPAddress     _sta_static_ip;
+    IPAddress     _sta_static_gw;
+    IPAddress     _sta_static_sn;
+    IPAddress     _sta_static_dns;
+
+    // defaults
+    const byte    DNS_PORT                = 53;
+    const byte    HTTP_PORT               = 80;
+    String        _apName                 = "no-net";
+    String        _apPassword             = "";
+    String        _ssid                   = "";
+    String        _pass                   = "";
+    
+    // options flags
+    unsigned long _configPortalTimeout    = 0; // ms close config portal loop if set (depending on  _cp/webClientCheck options)
+    unsigned long _connectTimeout         = 0; // ms stop trying to connect to ap if set
+    unsigned long _saveTimeout            = 0; // ms stop trying to connect to ap on saves, in case bugs in esp waitforconnectresult
+    unsigned long _configPortalStart      = 0; // ms config portal start time (updated for timeouts)
+    unsigned long _webPortalAccessed      = 0; // ms last web access time
+    WiFiMode_t    _usermode               = WIFI_OFF;
+    String        _wifissidprefix         = FPSTR(S_ssidpre); // auto apname prefix prefix+chipid
+    uint8_t       _lastconxresult         = WL_IDLE_STATUS;
+    int           _numNetworks            = 0;
+    unsigned long _lastscan               = 0; // ms for timing wifi scans
+    unsigned long _startscan              = 0; // ms for timing wifi scans
+    int           _cpclosedelay           = 2000; // delay before wifisave, prevents captive portal from closing to fast.
+    bool          _cleanConnect           = false; // disconnect before connect in connectwifi, increases stability on connects
+   
+    bool          _disableSTA             = false; // disable sta when starting ap, always
+    bool          _disableSTAConn         = true;  // disable sta when starting ap, if sta is not connected ( stability )
+    bool          _channelSync            = false; // use same wifi sta channel when starting ap
+    int32_t       _apChannel              = 0; // channel to use for ap
+    bool          _apHidden               = false; // store softap hidden value
+
+    #ifdef ESP32
+    static uint8_t _lastconxresulttmp; // tmp var for esp32 callback
+    #endif
+
+    #ifndef WL_STATION_WRONG_PASSWORD
+    uint8_t WL_STATION_WRONG_PASSWORD     = 7; // @kludge define a WL status for wrong password
+    #endif
+
+    // parameter options
+    int           _minimumQuality         = -1;    // filter wifiscan ap by this rssi
+    int            _staShowStaticFields   = 0;     // ternary 1=always show static ip fields, 0=only if set, -1=never(cannot change ips via web!)
+    int            _staShowDns            = 0;     // ternary 1=always show dns, 0=only if set, -1=never(cannot change dns via web!)
+    boolean       _removeDuplicateAPs     = true;  // remove dup aps from wifiscan
+    boolean       _showPassword           = false; // show or hide saved password on wifi form, might be a security issue!
+    boolean       _shouldBreakAfterConfig = false; // stop configportal on save failure
+    boolean       _configPortalIsBlocking = true;  // configportal enters blocking loop 
+    boolean       _enableCaptivePortal    = true;  // enable captive portal redirection
+    boolean       _userpersistent         = true;  // users preffered persistence to restore
+    boolean       _wifiAutoReconnect      = true;  // there is no platform getter for this, we must assume its true and make it so
+    boolean       _apClientCheck          = false; // keep cp alive if ap have station
+    boolean       _webClientCheck         = true;  // keep cp alive if web have client
+    boolean       _scanDispOptions        = false; // show percentage in scans not icons
+    boolean       _paramsInWifi           = true;  // show custom parameters on wifi page
+    boolean       _showInfoErase          = true;  // info page erase button
+    boolean       _enableConfigPortal     = true;  // use config portal if autoconnect failed
+    const char *  _hostname               = "";
+
+    const char*   _customHeadElement      = ""; // store custom head element html from user
+    String        _bodyClass              = ""; // class to add to body
+
+    // internal options
+    boolean       _preloadwifiscan        = true;  // preload wifiscan if true
+    boolean       _asyncScan              = false;
+    unsigned int  _scancachetime          = 30000; // ms cache time for background scans
+    boolean       _disableIpFields        = false; // modify function of setShow_X_Fields(false), forces ip fields off instead of default show if set, eg. _staShowStaticFields=-1
+
+    String        _wificountry            = "";  // country code, @todo define in strings lang
+
+    // wrapper functions for handling setting and unsetting persistent for now.
+    bool          esp32persistent         = false;
+    bool          _hasBegun               = false;
+    void          _begin();
+    void          _end();
+
+    void          setupConfigPortal();
+    bool          shutdownConfigPortal();
+
+#ifdef NO_EXTRA_4K_HEAP
+    boolean       _tryWPS                 = false; // try WPS on save failure, unsupported
+    void          startWPS();
+#endif
+
+    bool          startAP();
+
+    uint8_t       connectWifi(String ssid, String pass);
+    bool          setSTAConfig();
+    bool          wifiConnectDefault();
+    bool          wifiConnectNew(String ssid, String pass);
+
+    uint8_t       waitForConnectResult();
+    uint8_t       waitForConnectResult(uint16_t timeout);
+    void          updateConxResult(uint8_t status);
+
+    // webserver handlers
+    void          handleRoot();
+    void          handleWifi(boolean scan);
+    void          handleWifiSave();
+    void          handleInfo();
+    void          handleReset();
+    void          handleNotFound();
+    void          handleExit();
+    void          handleClose();
+    // void          handleErase();
+    void          handleErase(boolean opt);
+    void          handleParam();
+    void          handleWiFiStatus();
+    void          handleRequest();
+    void          handleParamSave();
+    void          doParamSave();
+
+    boolean       captivePortal();
+    boolean       configPortalHasTimeout();
+    uint8_t       processConfigPortal();
+    void          stopCaptivePortal();
+
+    // wifi platform abstractions
+    bool          WiFi_Mode(WiFiMode_t m);
+    bool          WiFi_Mode(WiFiMode_t m,bool persistent);
+    bool          WiFi_Disconnect();
+    bool          WiFi_enableSTA(bool enable);
+    bool          WiFi_enableSTA(bool enable,bool persistent);
+    bool          WiFi_eraseConfig();
+    uint8_t       WiFi_softap_num_stations();
+    bool          WiFi_hasAutoConnect();
+    void          WiFi_autoReconnect();
+    String        WiFi_SSID(bool persistent = false) const;
+    String        WiFi_psk(bool persistent = false) const;
+    bool          WiFi_scanNetworks();
+    bool          WiFi_scanNetworks(bool force,bool async);
+    bool          WiFi_scanNetworks(unsigned int cachetime,bool async);
+    bool          WiFi_scanNetworks(unsigned int cachetime);
+    void          WiFi_scanComplete(int networksFound);
+    bool          WiFiSetCountry();
+
+    #ifdef ESP32
+    void   WiFiEvent(WiFiEvent_t event, system_event_info_t info);
+    #endif
+
+    // output helpers
+    String        getParamOut();
+    String        getIpForm(String id, String title, String value);
+    String        getScanItemOut();
+    String        getStaticOut();
+    String        getHTTPHead(String title);
+    String        getMenuOut();
+    //helpers
+    boolean       isIp(String str);
+    String        toStringIp(IPAddress ip);
+    boolean       validApPassword();
+    String        encryptionTypeStr(uint8_t authmode);
+    void          reportStatus(String &page);
+    String        getInfoData(String id);
+
+    // flags
+    boolean       connect;
+    boolean       abort;
+    boolean       reset               = false;
+    boolean       configPortalActive  = false;
+    boolean       webPortalActive     = false;
+    boolean       portalTimeoutResult = false;
+    boolean       portalAbortResult   = false;
+    boolean       storeSTAmode        = true; // option store persistent STA mode in connectwifi 
+    int           timer               = 0;
+    
+    // WiFiManagerParameter
+    int         _paramsCount          = 0;
+    int         _max_params;
+    WiFiManagerParameter** _params    = NULL;
+
+    // debugging
+    typedef enum {
+        DEBUG_ERROR     = 0,
+        DEBUG_NOTIFY    = 1, // default stable
+        DEBUG_VERBOSE   = 2,
+        DEBUG_DEV       = 3, // default dev
+        DEBUG_MAX       = 4
+    } wm_debuglevel_t;
+
+    boolean _debug  = true;
+    
+    // build debuglevel support
+    // @todo use DEBUG_ESP_x?
+    #ifdef WM_DEBUG_LEVEL
+    uint8_t _debugLevel = (uint8_t)WM_DEBUG_LEVEL;
+    #else 
+    uint8_t _debugLevel = DEBUG_DEV; // default debug level
+    #endif
+
+    // @todo use DEBUG_ESP_PORT ?
+    #ifdef WM_DEBUG_PORT
+    Stream& _debugPort = WM_DEBUG_PORT;
+    #else
+    Stream& _debugPort = Serial; // debug output stream ref
+    #endif
+
+    template <typename Generic>
+    void        DEBUG_WM(Generic text);
+
+    template <typename Generic>
+    void        DEBUG_WM(wm_debuglevel_t level,Generic text);
+    template <typename Generic, typename Genericb>
+    void        DEBUG_WM(Generic text,Genericb textb);
+    template <typename Generic, typename Genericb>
+    void        DEBUG_WM(wm_debuglevel_t level, Generic text,Genericb textb);
+
+    // callbacks
+    // @todo use cb list (vector) maybe event ids, allow no return value
+    std::function<void(WiFiManager*)> _apcallback;
+    std::function<void()> _webservercallback;
+    std::function<void()> _savewificallback;
+    std::function<void()> _presavecallback;
+    std::function<void()> _saveparamscallback;
+    std::function<void()> _resetcallback;
+
+    template <class T>
+    auto optionalIPFromString(T *obj, const char *s) -> decltype(  obj->fromString(s)  ) {
+      return  obj->fromString(s);
+    }
+    auto optionalIPFromString(...) -> bool {
+      // DEBUG_WM("NO fromString METHOD ON IPAddress, you need ESP8266 core 2.1.0 or newer for Custom IP configuration to work.");
+      return false;
+    }
+};
+
+#endif
+
+#endif

+ 134 - 0
lib/WiFiManager-development/examples/Advanced/Advanced.ino

@@ -0,0 +1,134 @@
+/**
+ * WiFiManager advanced demo, contains advanced configurartion options
+ * Implements TRIGGEN_PIN button press, press for ondemand configportal, hold for 3 seconds for reset settings.
+ */
+#include <WiFiManager.h> // https://github.com/tzapu/WiFiManager
+
+#define TRIGGER_PIN 0
+
+WiFiManager wm; // global wm instance
+WiFiManagerParameter custom_field; // global param ( for non blocking w params )
+
+void setup() {
+  WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP  
+  Serial.begin(115200);
+  Serial.setDebugOutput(true);  
+  delay(3000);
+  Serial.println("\n Starting");
+
+  pinMode(TRIGGER_PIN, INPUT);
+  
+  // wm.resetSettings(); // wipe settings
+
+  // add a custom input field
+  int customFieldLength = 40;
+
+
+  // new (&custom_field) WiFiManagerParameter("customfieldid", "Custom Field Label", "Custom Field Value", customFieldLength,"placeholder=\"Custom Field Placeholder\"");
+  
+  // test custom html input type(checkbox)
+  // new (&custom_field) WiFiManagerParameter("customfieldid", "Custom Field Label", "Custom Field Value", customFieldLength,"placeholder=\"Custom Field Placeholder\" type=\"checkbox\""); // custom html type
+  
+  // test custom html(radio)
+  const char* custom_radio_str = "<br/><label for='customfieldid'>Custom Field Label</label><input type='radio' name='customfieldid' value='1' checked> One<br><input type='radio' name='customfieldid' value='2'> Two<br><input type='radio' name='customfieldid' value='3'> Three";
+  new (&custom_field) WiFiManagerParameter(custom_radio_str); // custom html input
+  
+  wm.addParameter(&custom_field);
+  wm.setSaveParamsCallback(saveParamCallback);
+
+  // custom menu via array or vector
+  // 
+  // menu tokens, "wifi","wifinoscan","info","param","close","sep","erase","restart","exit" (sep is seperator) (if param is in menu, params will not show up in wifi page!)
+  // const char* menu[] = {"wifi","info","param","sep","restart","exit"}; 
+  // wm.setMenu(menu,6);
+  std::vector<const char *> menu = {"wifi","info","param","sep","restart","exit"};
+  wm.setMenu(menu);
+
+  // set dark theme
+  wm.setClass("invert");
+
+
+  //set static ip
+  // wm.setSTAStaticIPConfig(IPAddress(10,0,1,99), IPAddress(10,0,1,1), IPAddress(255,255,255,0)); // set static ip,gw,sn
+  // wm.setShowStaticFields(true); // force show static ip fields
+  // wm.setShowDnsFields(true);    // force show dns field always
+
+  // wm.setConnectTimeout(20); // how long to try to connect for before continuing
+  wm.setConfigPortalTimeout(30); // auto close configportal after n seconds
+  // wm.setCaptivePortalEnable(false); // disable captive portal redirection
+  // wm.setAPClientCheck(true); // avoid timeout if client connected to softap
+
+  // wifi scan settings
+  // wm.setRemoveDuplicateAPs(false); // do not remove duplicate ap names (true)
+  // wm.setMinimumSignalQuality(20);  // set min RSSI (percentage) to show in scans, null = 8%
+  // wm.setShowInfoErase(false);      // do not show erase button on info page
+  // wm.setScanDispPerc(true);       // show RSSI as percentage not graph icons
+  
+  // wm.setBreakAfterConfig(true);   // always exit configportal even if wifi save fails
+
+  bool res;
+  // res = wm.autoConnect(); // auto generated AP name from chipid
+  // res = wm.autoConnect("AutoConnectAP"); // anonymous ap
+  res = wm.autoConnect("AutoConnectAP","password"); // password protected ap
+
+  if(!res) {
+    Serial.println("Failed to connect or hit timeout");
+    // ESP.restart();
+  } 
+  else {
+    //if you get here you have connected to the WiFi    
+    Serial.println("connected...yeey :)");
+  }
+}
+
+void checkButton(){
+  // check for button press
+  if ( digitalRead(TRIGGER_PIN) == LOW ) {
+    // poor mans debounce/press-hold, code not ideal for production
+    delay(50);
+    if( digitalRead(TRIGGER_PIN) == LOW ){
+      Serial.println("Button Pressed");
+      // still holding button for 3000 ms, reset settings, code not ideaa for production
+      delay(3000); // reset delay hold
+      if( digitalRead(TRIGGER_PIN) == LOW ){
+        Serial.println("Button Held");
+        Serial.println("Erasing Config, restarting");
+        wm.resetSettings();
+        ESP.restart();
+      }
+      
+      // start portal w delay
+      Serial.println("Starting config portal");
+      wm.setConfigPortalTimeout(120);
+      
+      if (!wm.startConfigPortal("OnDemandAP","password")) {
+        Serial.println("failed to connect or hit timeout");
+        delay(3000);
+        // ESP.restart();
+      } else {
+        //if you get here you have connected to the WiFi
+        Serial.println("connected...yeey :)");
+      }
+    }
+  }
+}
+
+
+String getParam(String name){
+  //read parameter from server, for customhmtl input
+  String value;
+  if(wm.server->hasArg(name)) {
+    value = wm.server->arg(name);
+  }
+  return value;
+}
+
+void saveParamCallback(){
+  Serial.println("[CALLBACK] saveParamCallback fired");
+  Serial.println("PARAM customfieldid = " + getParam("customfieldid"));
+}
+
+void loop() {
+  checkButton();
+  // put your main code here, to run repeatedly:
+}

+ 175 - 0
lib/WiFiManager-development/examples/AutoConnect/AutoConnectWithFSParameters/AutoConnectWithFSParameters.ino

@@ -0,0 +1,175 @@
+#include <FS.h>          // this needs to be first, or it all crashes and burns...
+#include <WiFiManager.h> // https://github.com/tzapu/WiFiManager
+#include <ArduinoJson.h> // https://github.com/bblanchon/ArduinoJson
+
+#ifdef ESP32
+  #include <SPIFFS.h>
+#endif
+
+//define your default values here, if there are different values in config.json, they are overwritten.
+char mqtt_server[40];
+char mqtt_port[6]  = "8080";
+char api_token[32] = "YOUR_API_TOKEN";
+
+//default custom static IP
+char static_ip[16] = "10.0.1.56";
+char static_gw[16] = "10.0.1.1";
+char static_sn[16] = "255.255.255.0";
+
+//flag for saving data
+bool shouldSaveConfig = false;
+
+//callback notifying us of the need to save config
+void saveConfigCallback () {
+  Serial.println("Should save config");
+  shouldSaveConfig = true;
+}
+
+void setupSpiffs(){
+  //clean FS, for testing
+  // SPIFFS.format();
+
+  //read configuration from FS json
+  Serial.println("mounting FS...");
+
+  if (SPIFFS.begin()) {
+    Serial.println("mounted file system");
+    if (SPIFFS.exists("/config.json")) {
+      //file exists, reading and loading
+      Serial.println("reading config file");
+      File configFile = SPIFFS.open("/config.json", "r");
+      if (configFile) {
+        Serial.println("opened config file");
+        size_t size = configFile.size();
+        // Allocate a buffer to store contents of the file.
+        std::unique_ptr<char[]> buf(new char[size]);
+
+        configFile.readBytes(buf.get(), size);
+        DynamicJsonBuffer jsonBuffer;
+        JsonObject& json = jsonBuffer.parseObject(buf.get());
+        json.printTo(Serial);
+        if (json.success()) {
+          Serial.println("\nparsed json");
+
+          strcpy(mqtt_server, json["mqtt_server"]);
+          strcpy(mqtt_port, json["mqtt_port"]);
+          strcpy(api_token, json["api_token"]);
+
+          // if(json["ip"]) {
+          //   Serial.println("setting custom ip from config");
+          //   strcpy(static_ip, json["ip"]);
+          //   strcpy(static_gw, json["gateway"]);
+          //   strcpy(static_sn, json["subnet"]);
+          //   Serial.println(static_ip);
+          // } else {
+          //   Serial.println("no custom ip in config");
+          // }
+
+        } else {
+          Serial.println("failed to load json config");
+        }
+      }
+    }
+  } else {
+    Serial.println("failed to mount FS");
+  }
+  //end read
+}
+
+void setup() {
+  // put your setup code here, to run once:
+  Serial.begin(115200);
+  Serial.println();
+
+  setupSpiffs();
+
+  // WiFiManager, Local intialization. Once its business is done, there is no need to keep it around
+  WiFiManager wm;
+
+  //set config save notify callback
+  wm.setSaveConfigCallback(saveConfigCallback);
+
+  // setup custom parameters
+  // 
+  // The extra parameters to be configured (can be either global or just in the setup)
+  // After connecting, parameter.getValue() will get you the configured value
+  // id/name placeholder/prompt default length
+  WiFiManagerParameter custom_mqtt_server("server", "mqtt server", mqtt_server, 40);
+  WiFiManagerParameter custom_mqtt_port("port", "mqtt port", mqtt_port, 6);
+  WiFiManagerParameter custom_api_token("api", "api token", "", 32);
+
+  //add all your parameters here
+  wm.addParameter(&custom_mqtt_server);
+  wm.addParameter(&custom_mqtt_port);
+  wm.addParameter(&custom_api_token);
+
+  // set static ip
+  // IPAddress _ip,_gw,_sn;
+  // _ip.fromString(static_ip);
+  // _gw.fromString(static_gw);
+  // _sn.fromString(static_sn);
+  // wm.setSTAStaticIPConfig(_ip, _gw, _sn);
+
+  //reset settings - wipe credentials for testing
+  //wm.resetSettings();
+
+  //automatically connect using saved credentials if they exist
+  //If connection fails it starts an access point with the specified name
+  //here  "AutoConnectAP" if empty will auto generate basedcon chipid, if password is blank it will be anonymous
+  //and goes into a blocking loop awaiting configuration
+  if (!wm.autoConnect("AutoConnectAP", "password")) {
+    Serial.println("failed to connect and hit timeout");
+    delay(3000);
+    // if we still have not connected restart and try all over again
+    ESP.restart();
+    delay(5000);
+  }
+
+  // always start configportal for a little while
+  // wm.setConfigPortalTimeout(60);
+  // wm.startConfigPortal("AutoConnectAP","password");
+
+  //if you get here you have connected to the WiFi
+  Serial.println("connected...yeey :)");
+
+  //read updated parameters
+  strcpy(mqtt_server, custom_mqtt_server.getValue());
+  strcpy(mqtt_port, custom_mqtt_port.getValue());
+  strcpy(api_token, custom_api_token.getValue());
+
+  //save the custom parameters to FS
+  if (shouldSaveConfig) {
+    Serial.println("saving config");
+    DynamicJsonBuffer jsonBuffer;
+    JsonObject& json = jsonBuffer.createObject();
+    json["mqtt_server"] = mqtt_server;
+    json["mqtt_port"]   = mqtt_port;
+    json["api_token"]   = api_token;
+
+    // json["ip"]          = WiFi.localIP().toString();
+    // json["gateway"]     = WiFi.gatewayIP().toString();
+    // json["subnet"]      = WiFi.subnetMask().toString();
+
+    File configFile = SPIFFS.open("/config.json", "w");
+    if (!configFile) {
+      Serial.println("failed to open config file for writing");
+    }
+
+    json.prettyPrintTo(Serial);
+    json.printTo(configFile);
+    configFile.close();
+    //end save
+    shouldSaveConfig = false;
+  }
+
+  Serial.println("local ip");
+  Serial.println(WiFi.localIP());
+  Serial.println(WiFi.gatewayIP());
+  Serial.println(WiFi.subnetMask());
+}
+
+void loop() {
+  // put your main code here, to run repeatedly:
+
+
+}

+ 172 - 0
lib/WiFiManager-development/examples/AutoConnect/AutoConnectWithFSParametersAndCustomIP/AutoConnectWithFSParametersAndCustomIP.ino

@@ -0,0 +1,172 @@
+#include <FS.h>          // this needs to be first, or it all crashes and burns...
+#include <WiFiManager.h> // https://github.com/tzapu/WiFiManager
+#include <ArduinoJson.h> // https://github.com/bblanchon/ArduinoJson
+
+#ifdef ESP32
+  #include <SPIFFS.h>
+#endif
+
+//define your default values here, if there are different values in config.json, they are overwritten.
+char mqtt_server[40];
+char mqtt_port[6]  = "8080";
+char api_token[32] = "YOUR_API_TOKEN";
+
+//default custom static IP
+char static_ip[16] = "10.0.1.56";
+char static_gw[16] = "10.0.1.1";
+char static_sn[16] = "255.255.255.0";
+
+//flag for saving data
+bool shouldSaveConfig = false;
+
+//callback notifying us of the need to save config
+void saveConfigCallback () {
+  Serial.println("Should save config");
+  shouldSaveConfig = true;
+}
+
+void setupSpiffs(){
+  //clean FS, for testing
+  // SPIFFS.format();
+
+  //read configuration from FS json
+  Serial.println("mounting FS...");
+
+  if (SPIFFS.begin()) {
+    Serial.println("mounted file system");
+    if (SPIFFS.exists("/config.json")) {
+      //file exists, reading and loading
+      Serial.println("reading config file");
+      File configFile = SPIFFS.open("/config.json", "r");
+      if (configFile) {
+        Serial.println("opened config file");
+        size_t size = configFile.size();
+        // Allocate a buffer to store contents of the file.
+        std::unique_ptr<char[]> buf(new char[size]);
+
+        configFile.readBytes(buf.get(), size);
+        DynamicJsonBuffer jsonBuffer;
+        JsonObject& json = jsonBuffer.parseObject(buf.get());
+        json.printTo(Serial);
+        if (json.success()) {
+          Serial.println("\nparsed json");
+
+          strcpy(mqtt_server, json["mqtt_server"]);
+          strcpy(mqtt_port, json["mqtt_port"]);
+          strcpy(api_token, json["api_token"]);
+
+          if(json["ip"]) {
+            Serial.println("setting custom ip from config");
+            strcpy(static_ip, json["ip"]);
+            strcpy(static_gw, json["gateway"]);
+            strcpy(static_sn, json["subnet"]);
+            Serial.println(static_ip);
+          } else {
+            Serial.println("no custom ip in config");
+          }
+
+        } else {
+          Serial.println("failed to load json config");
+        }
+      }
+    }
+  } else {
+    Serial.println("failed to mount FS");
+  }
+  //end read
+}
+
+void setup() {
+  WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP  
+  // put your setup code here, to run once:
+  Serial.begin(115200);
+  Serial.println();
+
+  setupSpiffs();
+
+  // WiFiManager, Local intialization. Once its business is done, there is no need to keep it around
+  WiFiManager wm;
+
+  //set config save notify callback
+  wm.setSaveConfigCallback(saveConfigCallback);
+
+  // setup custom parameters
+  // 
+  // The extra parameters to be configured (can be either global or just in the setup)
+  // After connecting, parameter.getValue() will get you the configured value
+  // id/name placeholder/prompt default length
+  WiFiManagerParameter custom_mqtt_server("server", "mqtt server", mqtt_server, 40);
+  WiFiManagerParameter custom_mqtt_port("port", "mqtt port", mqtt_port, 6);
+  WiFiManagerParameter custom_api_token("api", "api token", "", 32);
+
+  //add all your parameters here
+  wm.addParameter(&custom_mqtt_server);
+  wm.addParameter(&custom_mqtt_port);
+  wm.addParameter(&custom_api_token);
+
+  // set static ip
+  IPAddress _ip,_gw,_sn;
+  _ip.fromString(static_ip);
+  _gw.fromString(static_gw);
+  _sn.fromString(static_sn);
+  wm.setSTAStaticIPConfig(_ip, _gw, _sn);
+
+  //reset settings - wipe credentials for testing
+  //wm.resetSettings();
+
+  //automatically connect using saved credentials if they exist
+  //If connection fails it starts an access point with the specified name
+  //here  "AutoConnectAP" if empty will auto generate basedcon chipid, if password is blank it will be anonymous
+  //and goes into a blocking loop awaiting configuration
+  if (!wm.autoConnect("AutoConnectAP", "password")) {
+    Serial.println("failed to connect and hit timeout");
+    delay(3000);
+    // if we still have not connected restart and try all over again
+    ESP.restart();
+    delay(5000);
+  }
+
+  //if you get here you have connected to the WiFi
+  Serial.println("connected...yeey :)");
+
+  //read updated parameters
+  strcpy(mqtt_server, custom_mqtt_server.getValue());
+  strcpy(mqtt_port, custom_mqtt_port.getValue());
+  strcpy(api_token, custom_api_token.getValue());
+
+  //save the custom parameters to FS
+  if (shouldSaveConfig) {
+    Serial.println("saving config");
+    DynamicJsonBuffer jsonBuffer;
+    JsonObject& json = jsonBuffer.createObject();
+    json["mqtt_server"] = mqtt_server;
+    json["mqtt_port"]   = mqtt_port;
+    json["api_token"]   = api_token;
+
+    json["ip"]          = WiFi.localIP().toString();
+    json["gateway"]     = WiFi.gatewayIP().toString();
+    json["subnet"]      = WiFi.subnetMask().toString();
+
+    File configFile = SPIFFS.open("/config.json", "w");
+    if (!configFile) {
+      Serial.println("failed to open config file for writing");
+    }
+
+    json.prettyPrintTo(Serial);
+    json.printTo(configFile);
+    configFile.close();
+    //end save
+    shouldSaveConfig = false;
+  }
+
+  Serial.println("local ip");
+  Serial.println(WiFi.localIP());
+  Serial.println(WiFi.gatewayIP());
+  Serial.println(WiFi.subnetMask());
+}
+
+void loop() {
+  // put your main code here, to run repeatedly:
+
+
+}

+ 71 - 0
lib/WiFiManager-development/examples/AutoConnect/AutoConnectWithFeedbackLED/AutoConnectWithFeedbackLED.ino

@@ -0,0 +1,71 @@
+// LED will blink when in config mode
+
+#include <WiFiManager.h> // https://github.com/tzapu/WiFiManager
+
+//for LED status
+#include <Ticker.h>
+Ticker ticker;
+
+#ifndef LED_BUILTIN
+#define LED_BUILTIN 13 // ESP32 DOES NOT DEFINE LED_BUILTIN
+#endif
+
+int LED = LED_BUILTIN;
+
+void tick()
+{
+  //toggle state
+  digitalWrite(LED, !digitalRead(LED));     // set pin to the opposite state
+}
+
+//gets called when WiFiManager enters configuration mode
+void configModeCallback (WiFiManager *myWiFiManager) {
+  Serial.println("Entered config mode");
+  Serial.println(WiFi.softAPIP());
+  //if you used auto generated SSID, print it
+  Serial.println(myWiFiManager->getConfigPortalSSID());
+  //entered config mode, make led toggle faster
+  ticker.attach(0.2, tick);
+}
+
+void setup() {
+  WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP
+  // put your setup code here, to run once:
+  Serial.begin(115200);
+  
+  //set led pin as output
+  pinMode(LED, OUTPUT);
+  // start ticker with 0.5 because we start in AP mode and try to connect
+  ticker.attach(0.6, tick);
+
+  //WiFiManager
+  //Local intialization. Once its business is done, there is no need to keep it around
+  WiFiManager wm;
+  //reset settings - for testing
+  // wm.resetSettings();
+
+  //set callback that gets called when connecting to previous WiFi fails, and enters Access Point mode
+  wm.setAPCallback(configModeCallback);
+
+  //fetches ssid and pass and tries to connect
+  //if it does not connect it starts an access point with the specified name
+  //here  "AutoConnectAP"
+  //and goes into a blocking loop awaiting configuration
+  if (!wm.autoConnect()) {
+    Serial.println("failed to connect and hit timeout");
+    //reset and try again, or maybe put it to deep sleep
+    ESP.restart();
+    delay(1000);
+  }
+
+  //if you get here you have connected to the WiFi
+  Serial.println("connected...yeey :)");
+  ticker.detach();
+  //keep LED on
+  digitalWrite(LED, LOW);
+}
+
+void loop() {
+  // put your main code here, to run repeatedly:
+
+}

+ 41 - 0
lib/WiFiManager-development/examples/Basic/Basic.ino

@@ -0,0 +1,41 @@
+#include <WiFiManager.h> // https://github.com/tzapu/WiFiManager
+
+void setup() {
+    WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP
+
+    // put your setup code here, to run once:
+    Serial.begin(115200);
+    
+    // WiFi.mode(WiFi_STA); // it is a good practice to make sure your code sets wifi mode how you want it.
+
+    //WiFiManager, Local intialization. Once its business is done, there is no need to keep it around
+    WiFiManager wm;
+
+    //reset settings - wipe credentials for testing
+    //wm.resetSettings();
+
+    // Automatically connect using saved credentials,
+    // if connection fails, it starts an access point with the specified name ( "AutoConnectAP"),
+    // if empty will auto generate SSID, if password is blank it will be anonymous AP (wm.autoConnect())
+    // then goes into a blocking loop awaiting configuration and will return success result
+
+    bool res;
+    // res = wm.autoConnect(); // auto generated AP name from chipid
+    // res = wm.autoConnect("AutoConnectAP"); // anonymous ap
+    res = wm.autoConnect("AutoConnectAP","password"); // password protected ap
+
+    if(!res) {
+        Serial.println("Failed to connect");
+        // ESP.restart();
+    } 
+    else {
+        //if you get here you have connected to the WiFi    
+        Serial.println("connected...yeey :)");
+    }
+
+}
+
+void loop() {
+    // put your main code here, to run repeatedly:
+    
+}

+ 328 - 0
lib/WiFiManager-development/examples/DEV/OnDemandConfigPortal/OnDemandConfigPortal.ino

@@ -0,0 +1,328 @@
+/**
+ * This is a kind of unit test for DEV for now
+ * It contains many of the public methods
+ * 
+ */
+#include <WiFiManager.h> // https://github.com/tzapu/WiFiManager
+#include <time.h>
+#include <stdio.h>
+
+#define USEOTA
+// enable OTA
+#ifdef USEOTA
+#include <WiFiUdp.h>
+#include <ArduinoOTA.h>
+#endif
+
+#define TRIGGER_PIN 0
+const char* modes[] = { "NULL", "STA", "AP", "STA+AP" };
+
+unsigned long mtime = 0;
+
+// // #define MYOLED
+
+// #include <Wire.h>
+// #include <Adafruit_GFX.h>
+// #include <Adafruit_SSD1306.h>
+// #ifdef MYOLED 
+
+// #define SCREEN_WIDTH 128 // OLED display width, in pixels
+// #define SCREEN_HEIGHT 32 // OLED display height, in pixels
+
+// // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
+// #define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
+// Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
+
+// void init_oled(){
+//   Wire.begin(SCL,SDA);  // begin(sda, scl) SWAP!
+//   // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
+//   if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32
+//     Serial.println(F("SSD1306 allocation failed"));
+//   }
+
+//   display.clearDisplay();
+//   display.setTextSize(1);             // Normal 1:1 pixepl scale
+//   display.setTextColor(WHITE);        // Draw white text
+//   display.setCursor(0,0);             // Start at top-left corner
+//   display.display();
+// }
+
+// void print_oled(String str,uint8_t size){
+//   display.clearDisplay();
+//   display.setTextSize(size);
+//   display.setTextColor(WHITE);
+//   display.setCursor(0,0);
+//   display.println(str);
+//   display.display();
+// }
+// #else
+//   void print_oled(String str,uint8_t size){
+//     (void)str;
+//     (void)size;
+//   }
+// #endif
+
+void print_oled(String str,uint8_t size){
+  (void)str;
+  (void)size;
+}
+
+WiFiManager wm;
+
+// OPTION FLAGS
+bool TEST_CP  = true; // always start the configportal, even if ap found
+bool TEST_NET = true; // do a network test after connect, (gets ntp time)
+bool ALLOWONDEMAND = true;
+
+// char ssid[] = "*************";  //  your network SSID (name)
+// char pass[] = "********";       // your network password
+
+void saveWifiCallback(){
+  Serial.println("[CALLBACK] saveCallback fired");
+}
+
+//gets called when WiFiManager enters configuration mode
+void configModeCallback (WiFiManager *myWiFiManager) {
+  Serial.println("[CALLBACK] configModeCallback fired");
+  #ifdef ESP8266
+    print_oled("WiFiManager Waiting\nIP: " + WiFi.softAPIP().toString() + "\nSSID: " + WiFi.softAPSSID(),1); 
+  #endif  
+  // myWiFiManager->setAPStaticIPConfig(IPAddress(10,0,1,1), IPAddress(10,0,1,1), IPAddress(255,255,255,0)); 
+  // Serial.println(WiFi.softAPIP());
+  //if you used auto generated SSID, print it
+  // Serial.println(myWiFiManager->getConfigPortalSSID());
+}
+
+void saveParamCallback(){
+  Serial.println("[CALLBACK] saveParamCallback fired");
+  // wm.stopConfigPortal();
+}
+
+void bindServerCallback(){
+  wm.server->on("/custom",handleRoute);
+  // wm.server->on("/info",handleRoute); // can override wm!
+}
+
+void handleRoute(){
+  Serial.println("[HTTP] handle route");
+  wm.server->send(200, "text/plain", "hello from user code");
+}
+
+void setup() {
+  WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP
+  // put your setup code here, to run once:
+  Serial.begin(115200);
+  // Serial1.begin(115200);
+
+  // Serial.setDebugOutput(true);  
+  delay(1000);
+  // Serial1.println("TXD1 Enabled");
+
+  Serial.println("\n Starting");
+  // WiFi.setSleepMode(WIFI_NONE_SLEEP); // disable sleep, can improve ap stability
+  
+  #ifdef OLED
+  init_oled();
+  #endif
+  print_oled(F("Starting..."),2);
+  wm.debugPlatformInfo();
+
+  //Local intialization. Once its business is done, there is no need to keep it around
+  //reset settings - for testing
+  // wm.resetSettings();
+  // wm.erase();
+  
+  wm.setClass("invert");
+
+  WiFiManagerParameter custom_html("<p>This Is Custom HTML</p>"); // only custom html
+  WiFiManagerParameter custom_mqtt_server("server", "mqtt server", "", 40);
+  WiFiManagerParameter custom_mqtt_port("port", "mqtt port", "", 6);
+  WiFiManagerParameter custom_token("api_token", "api token", "", 16);
+  WiFiManagerParameter custom_tokenb("invalid token", "invalid token", "", 0); // id is invalid, cannot contain spaces
+  WiFiManagerParameter custom_ipaddress("input_ip", "input IP", "", 15,"pattern='\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}'"); // custom input attrs (ip mask)
+
+  const char _customHtml_checkbox[] = "type=\"checkbox\""; 
+  WiFiManagerParameter custom_checkbox("checkbox", "my checkbox", "T", 2, _customHtml_checkbox, WFM_LABEL_AFTER);
+
+  // callbacks
+  wm.setAPCallback(configModeCallback);
+  wm.setWebServerCallback(bindServerCallback);
+  wm.setSaveConfigCallback(saveWifiCallback);
+  wm.setSaveParamsCallback(saveParamCallback);
+
+  //add all your parameters here
+  wm.addParameter(&custom_html);
+  wm.addParameter(&custom_mqtt_server);
+  wm.addParameter(&custom_mqtt_port);
+  wm.addParameter(&custom_token);
+  wm.addParameter(&custom_tokenb);
+  wm.addParameter(&custom_ipaddress);
+  wm.addParameter(&custom_checkbox);
+
+  custom_html.setValue("test",4);
+  custom_token.setValue("test",4);
+
+  // Set cutom menu via menu[] or vector
+  // const char* menu[] = {"wifi","wifinoscan","info","param","close","sep","erase","restart","exit"};
+  // wm.setMenu(menu,9); // custom menu array must provide length
+
+  std::vector<const char *> menu = {"wifi","wifinoscan","info","param","close","sep","erase","restart","exit"};
+  // wm.setMenu(menu); // custom menu, pass vector
+  
+  wm.setParamsPage(true); // move params to seperate page, not wifi, do not combine with setmenu!
+
+  // set static sta ip
+  // wm.setSTAStaticIPConfig(IPAddress(10,0,1,99), IPAddress(10,0,1,1), IPAddress(255,255,255,0));
+  // wm.setShowStaticFields(false);
+  // wm.setShowDnsFields(false);
+
+  // set static ip
+  // wm.setAPStaticIPConfig(IPAddress(10,0,1,1), IPAddress(10,0,1,1), IPAddress(255,255,255,0));
+  // wm.setAPStaticIPConfig(IPAddress(10,0,1,99), IPAddress(10,0,1,1), IPAddress(255,255,255,0)); 
+
+  // set country
+  wm.setCountry("US"); // setting wifi country seems to improve OSX soft ap connectivity, may help others as well
+  
+  // set channel
+  // wm.setWiFiAPChannel(13);
+  
+  // set AP hidden
+  // wm.setAPHidden(true);
+
+  // show password publicly!
+  // wm.setShowPassword(true);
+
+  //sets timeout until configuration portal gets turned off
+  //useful to make it all retry or go to sleep in seconds
+    wm.setConfigPortalTimeout(120);
+  
+  // wm.setConnectTimeout(20);
+  // wm.setShowStaticFields(true);
+  
+  // wm.startConfigPortal("AutoConnectAP", "password");
+  
+  // wm.setCleanConnect(true); // disconenct before connect, clean connect
+  
+  // wm.setBreakAfterConfig(true);
+
+  //fetches ssid and pass and tries to connect
+  //if it does not connect it starts an access point with the specified name
+  //here  "AutoConnectAP"
+  //and goes into a blocking loop awaiting configuration
+  wifiInfo();
+  print_oled(F("Connecting..."),2);  
+  if(!wm.autoConnect("WM_AutoConnectAP")) {
+    Serial.println("failed to connect and hit timeout");
+    print_oled("Not Connected",2);
+  }
+  else if(TEST_CP) {
+    delay(1000);
+    Serial.println("TEST_CP ENABLED");
+    // start configportal always
+    wm.setConfigPortalTimeout(60);
+    wm.startConfigPortal("WM_ConnectAP");
+  }
+  else {
+    //if you get here you have connected to the WiFi
+     Serial.println("connected...yeey :)");
+      print_oled("Connected\nIP: " + WiFi.localIP().toString() + "\nSSID: " + WiFi.SSID(),1);    
+  }
+  
+  wifiInfo();
+  pinMode(TRIGGER_PIN, INPUT_PULLUP);
+
+  #ifdef USEOTA
+    ArduinoOTA.begin();
+  #endif
+}
+
+void wifiInfo(){
+  WiFi.printDiag(Serial);
+  Serial.println("SAVED: " + (String)wm.getWiFiIsSaved() ? "YES" : "NO");
+  Serial.println("SSID: " + (String)wm.getWiFiSSID());
+  Serial.println("PASS: " + (String)wm.getWiFiPass());
+}
+
+void loop() {
+
+  #ifdef USEOTA
+  ArduinoOTA.handle();
+  #endif
+  // is configuration portal requested?
+  if (ALLOWONDEMAND && digitalRead(TRIGGER_PIN) == LOW ) {
+    delay(100);
+    if ( digitalRead(TRIGGER_PIN) == LOW ){
+      Serial.println("BUTTON PRESSED");
+      wm.setConfigPortalTimeout(140);
+      wm.setParamsPage(false); // move params to seperate page, not wifi, do not combine with setmenu!
+
+      // disable captive portal redirection
+      // wm.setCaptivePortalEnable(false);
+      
+      if (!wm.startConfigPortal("OnDemandAP","12345678")) {
+        Serial.println("failed to connect and hit timeout");
+        delay(3000);
+      }
+    }
+    else {
+      //if you get here you have connected to the WiFi
+      Serial.println("connected...yeey :)");
+      print_oled("Connected\nIP: " + WiFi.localIP().toString() + "\nSSID: " + WiFi.SSID(),1);    
+      getTime();
+    }
+  }
+
+  if(WiFi.status() == WL_CONNECTED && millis()-mtime > 10000 ){
+    getTime();
+    mtime = millis();
+  }
+  // put your main code here, to run repeatedly:
+  delay(100);
+}
+
+void getTime() {
+  int tz           = -5;
+  int dst          = 0;
+  time_t now       = time(nullptr);
+  unsigned timeout = 5000;
+  unsigned start   = millis();  
+  configTime(tz * 3600, dst * 3600, "pool.ntp.org", "time.nist.gov");
+  Serial.print("Waiting for NTP time sync: ");
+  while (now < 8 * 3600 * 2 ) {
+    delay(100);
+    Serial.print(".");
+    now = time(nullptr);
+    if((millis() - start) > timeout){
+      Serial.println("[ERROR] Failed to get NTP time.");
+      return;
+    }
+  }
+  Serial.println("");
+  struct tm timeinfo;
+  gmtime_r(&now, &timeinfo);
+  Serial.print("Current time: ");
+  Serial.print(asctime(&timeinfo));
+}
+
+void debugchipid(){
+  // WiFi.mode(WIFI_STA);
+  // WiFi.printDiag(Serial);
+  // Serial.println(modes[WiFi.getMode()]);
+  
+  // ESP.eraseConfig();
+  // wm.resetSettings();
+  // wm.erase(true);
+  WiFi.mode(WIFI_AP);
+  // WiFi.softAP();
+  WiFi.enableAP(true);
+  delay(500);
+  // esp_wifi_start();
+  delay(1000);
+  WiFi.printDiag(Serial);
+  delay(60000);
+  ESP.restart();
+
+  // AP esp_267751
+  // 507726A4AE30
+  // ESP32 Chip ID = 507726A4AE30
+}

+ 27 - 0
lib/WiFiManager-development/examples/NonBlocking/AutoConnectNonBlocking/AutoConnectNonBlocking.ino

@@ -0,0 +1,27 @@
+#include <WiFiManager.h> // https://github.com/tzapu/WiFiManager
+WiFiManager wm;
+
+void setup() {
+    WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP    
+    // put your setup code here, to run once:
+    Serial.begin(115200);
+    
+    //reset settings - wipe credentials for testing
+    //wm.resetSettings();
+
+    wm.setConfigPortalBlocking(false);
+
+    //automatically connect using saved credentials if they exist
+    //If connection fails it starts an access point with the specified name
+    if(wm.autoConnect("AutoConnectAP")){
+        Serial.println("connected...yeey :)");
+    }
+    else {
+        Serial.println("Configportal running");
+    }
+}
+
+void loop() {
+    wm.process();
+    // put your main code here, to run repeatedly:
+}

+ 36 - 0
lib/WiFiManager-development/examples/NonBlocking/AutoConnectNonBlockingwParams/AutoConnectNonBlockingwParams.ino

@@ -0,0 +1,36 @@
+#include <WiFiManager.h> // https://github.com/tzapu/WiFiManager
+WiFiManager wm;
+WiFiManagerParameter custom_mqtt_server("server", "mqtt server", "", 40);
+
+void setup() {
+    WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP    
+    // put your setup code here, to run once:
+    Serial.begin(115200);
+    
+    //reset settings - wipe credentials for testing
+    //wm.resetSettings();
+    wm.addParameter(&custom_mqtt_server);
+    wm.setConfigPortalBlocking(false);
+    wm.setSaveParamsCallback(saveParamsCallback);
+
+    //automatically connect using saved credentials if they exist
+    //If connection fails it starts an access point with the specified name
+    if(wm.autoConnect("AutoConnectAP")){
+        Serial.println("connected...yeey :)");
+    }
+    else {
+        Serial.println("Configportal running");
+    }
+}
+
+void loop() {
+    wm.process();
+    // put your main code here, to run repeatedly:
+}
+
+void saveParamsCallback () {
+  Serial.println("Get Params:");
+  Serial.print(custom_mqtt_server.getID());
+  Serial.print(" : ");
+  Serial.println(custom_mqtt_server.getValue());
+}

+ 64 - 0
lib/WiFiManager-development/examples/NonBlocking/OnDemandNonBlocking/onDemandNonBlocking.ino

@@ -0,0 +1,64 @@
+/**
+ * OnDemandNonBlocking.ino
+ * example of running the webportal or configportal manually and non blocking
+ * trigger pin will start a webportal for 120 seconds then turn it off.
+ * startCP = true will start both the configportal AP and webportal
+ */
+#include <WiFiManager.h> // https://github.com/tzapu/WiFiManager
+
+// select which pin will trigger the configuration portal when set to LOW
+#define TRIGGER_PIN 0
+
+WiFiManager wm;
+
+unsigned int  timeout   = 120; // seconds to run for
+unsigned int  startTime = millis();
+bool portalRunning      = false;
+bool startAP            = false; // start AP and webserver if true, else start only webserver
+
+void setup() {
+  WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP  
+  // put your setup code here, to run once
+  Serial.begin(115200);
+  Serial.println("\n Starting");
+  pinMode(TRIGGER_PIN, INPUT_PULLUP);
+}
+
+void loop() {
+  doWiFiManager();
+  // put your main code here, to run repeatedly:
+}
+
+void doWiFiManager(){
+  // is auto timeout portal running
+  if(portalRunning){
+    wm.process();
+    if((millis()-startTime) > (timeout*1000)){
+      Serial.println("portaltimeout");
+      portalRunning = false;
+      if(startAP){
+        wm.stopConfigPortal();
+      }  
+      else{
+        wm.stopWebPortal();
+      } 
+   }
+  }
+
+  // is configuration portal requested?
+  if(digitalRead(TRIGGER_PIN) == LOW && (!portalRunning)) {
+    if(startAP){
+      Serial.println("Button Pressed, Starting Config Portal");
+      wm.setConfigPortalBlocking(false);
+      wm.startConfigPortal();
+    }  
+    else{
+      Serial.println("Button Pressed, Starting Web Portal");
+      wm.startWebPortal();
+    }  
+    portalRunning = true;
+    startTime = millis();
+  }
+}
+
+

+ 42 - 0
lib/WiFiManager-development/examples/Old_examples/AutoConnectWithFeedback/AutoConnectWithFeedback.ino

@@ -0,0 +1,42 @@
+#include <WiFiManager.h> // https://github.com/tzapu/WiFiManager
+
+void configModeCallback (WiFiManager *myWiFiManager) {
+  Serial.println("Entered config mode");
+  Serial.println(WiFi.softAPIP());
+  //if you used auto generated SSID, print it
+  Serial.println(myWiFiManager->getConfigPortalSSID());
+}
+
+void setup() {
+  // put your setup code here, to run once:
+  Serial.begin(115200);
+  
+  //WiFiManager
+  //Local intialization. Once its business is done, there is no need to keep it around
+  WiFiManager wifiManager;
+  //reset settings - for testing
+  //wifiManager.resetSettings();
+
+  //set callback that gets called when connecting to previous WiFi fails, and enters Access Point mode
+  wifiManager.setAPCallback(configModeCallback);
+
+  //fetches ssid and pass and tries to connect
+  //if it does not connect it starts an access point with the specified name
+  //here  "AutoConnectAP"
+  //and goes into a blocking loop awaiting configuration
+  if(!wifiManager.autoConnect()) {
+    Serial.println("failed to connect and hit timeout");
+    //reset and try again, or maybe put it to deep sleep
+    ESP.restart();
+    delay(1000);
+  } 
+
+  //if you get here you have connected to the WiFi
+  Serial.println("connected...yeey :)");
+ 
+}
+
+void loop() {
+  // put your main code here, to run repeatedly:
+
+}

+ 43 - 0
lib/WiFiManager-development/examples/Old_examples/AutoConnectWithReset/AutoConnectWithReset.ino

@@ -0,0 +1,43 @@
+#include <FS.h>          // this needs to be first, or it all crashes and burns...
+#include <WiFiManager.h> // https://github.com/tzapu/WiFiManager
+
+void setup() {
+  // put your setup code here, to run once:
+  Serial.begin(115200);
+  Serial.println();
+
+  //WiFiManager
+  //Local intialization. Once its business is done, there is no need to keep it around
+  WiFiManager wifiManager;
+
+  //exit after config instead of connecting
+  wifiManager.setBreakAfterConfig(true);
+
+  //reset settings - for testing
+  //wifiManager.resetSettings();
+
+
+  //tries to connect to last known settings
+  //if it does not connect it starts an access point with the specified name
+  //here  "AutoConnectAP" with password "password"
+  //and goes into a blocking loop awaiting configuration
+  if (!wifiManager.autoConnect("AutoConnectAP", "password")) {
+    Serial.println("failed to connect, we should reset as see if it connects");
+    delay(3000);
+    ESP.restart();
+    delay(5000);
+  }
+
+  //if you get here you have connected to the WiFi
+  Serial.println("connected...yeey :)");
+
+
+  Serial.println("local ip");
+  Serial.println(WiFi.localIP());
+}
+
+void loop() {
+  // put your main code here, to run repeatedly:
+
+
+}

+ 71 - 0
lib/WiFiManager-development/examples/Old_examples/AutoConnectWithStaticIP/AutoConnectWithStaticIP.ino

@@ -0,0 +1,71 @@
+#include <FS.h>          // this needs to be first, or it all crashes and burns...
+#include <WiFiManager.h> // https://github.com/tzapu/WiFiManager
+
+/**************************************************************************************
+ * this example shows how to set a static IP configuration for the ESP
+ * although the IP shows in the config portal, the changes will revert 
+ * to the IP set in the source file.
+ * if you want the ability to configure and persist the new IP configuration
+ * look at the FS examples, which save the config to file
+ *************************************************************************************/
+ 
+//default custom static IP
+//char static_ip[16] = "10.0.1.59";
+//char static_gw[16] = "10.0.1.1";
+//char static_sn[16] = "255.255.255.0";
+
+void setup() {
+  // put your setup code here, to run once:
+  Serial.begin(115200);
+  Serial.println();
+
+  //WiFiManager
+  //Local intialization. Once its business is done, there is no need to keep it around
+  WiFiManager wifiManager;
+
+  //reset settings - for testing
+  //wifiManager.resetSettings();
+
+  //set static ip
+  //block1 should be used for ESP8266 core 2.1.0 or newer, otherwise use block2
+
+  //start-block1
+  //IPAddress _ip,_gw,_sn;
+  //_ip.fromString(static_ip);
+  //_gw.fromString(static_gw);
+  //_sn.fromString(static_sn);
+  //end-block1
+
+  //start-block2
+  IPAddress _ip = IPAddress(10, 0, 1, 78);
+  IPAddress _gw = IPAddress(10, 0, 1, 1);
+  IPAddress _sn = IPAddress(255, 255, 255, 0);
+  //end-block2
+  
+  wifiManager.setSTAStaticIPConfig(_ip, _gw, _sn);
+
+
+  //tries to connect to last known settings
+  //if it does not connect it starts an access point with the specified name
+  //here  "AutoConnectAP" with password "password"
+  //and goes into a blocking loop awaiting configuration
+  if (!wifiManager.autoConnect("AutoConnectAP", "password")) {
+    Serial.println("failed to connect, we should reset as see if it connects");
+    delay(3000);
+    ESP.restart();
+    delay(5000);
+  }
+
+  //if you get here you have connected to the WiFi
+  Serial.println("connected...yeey :)");
+
+
+  Serial.println("local ip");
+  Serial.println(WiFi.localIP());
+}
+
+void loop() {
+  // put your main code here, to run repeatedly:
+
+
+}

+ 38 - 0
lib/WiFiManager-development/examples/Old_examples/AutoConnectWithTimeout/AutoConnectWithTimeout.ino

@@ -0,0 +1,38 @@
+#include <WiFiManager.h> // https://github.com/tzapu/WiFiManager
+
+void setup() {
+  // put your setup code here, to run once:
+  Serial.begin(115200);
+  
+  //WiFiManager
+  //Local intialization. Once its business is done, there is no need to keep it around
+  WiFiManager wifiManager;
+  //reset settings - for testing
+  //wifiManager.resetSettings();
+
+  //sets timeout until configuration portal gets turned off
+  //useful to make it all retry or go to sleep
+  //in seconds
+  wifiManager.setConfigPortalTimeout(180);
+  
+  //fetches ssid and pass and tries to connect
+  //if it does not connect it starts an access point with the specified name
+  //here  "AutoConnectAP"
+  //and goes into a blocking loop awaiting configuration
+  if(!wifiManager.autoConnect("AutoConnectAP")) {
+    Serial.println("failed to connect and hit timeout");
+    delay(3000);
+    //reset and try again, or maybe put it to deep sleep
+    ESP.restart();
+    delay(5000);
+  } 
+
+  //if you get here you have connected to the WiFi
+  Serial.println("connected...yeey :)");
+ 
+}
+
+void loop() {
+  // put your main code here, to run repeatedly:
+
+}

+ 47 - 0
lib/WiFiManager-development/examples/OnDemand/OnDemandConfigPortal/OnDemandConfigPortal.ino

@@ -0,0 +1,47 @@
+/**
+ * OnDemandConfigPortal.ino
+ * example of running the configPortal AP manually, independantly from the captiveportal
+ * trigger pin will start a configPortal AP for 120 seconds then turn it off.
+ * 
+ */
+#include <WiFiManager.h> // https://github.com/tzapu/WiFiManager
+
+// select which pin will trigger the configuration portal when set to LOW
+#define TRIGGER_PIN 0
+
+int timeout = 120; // seconds to run for
+
+void setup() {
+  WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP  
+  // put your setup code here, to run once:
+  Serial.begin(115200);
+  Serial.println("\n Starting");
+  pinMode(TRIGGER_PIN, INPUT_PULLUP);
+}
+
+void loop() {
+  // is configuration portal requested?
+  if ( digitalRead(TRIGGER_PIN) == LOW) {
+    WiFiManager wm;    
+
+    //reset settings - for testing
+    //wifiManager.resetSettings();
+  
+    // set configportal timeout
+    wm.setConfigPortalTimeout(timeout);
+
+    if (!wm.startConfigPortal("OnDemandAP")) {
+      Serial.println("failed to connect and hit timeout");
+      delay(3000);
+      //reset and try again, or maybe put it to deep sleep
+      ESP.restart();
+      delay(5000);
+    }
+
+    //if you get here you have connected to the WiFi
+    Serial.println("connected...yeey :)");
+
+  }
+
+  // put your main code here, to run repeatedly:
+}

+ 51 - 0
lib/WiFiManager-development/examples/OnDemand/OnDemandWebPortal/onDemandWebPortal.ino

@@ -0,0 +1,51 @@
+/**
+ * OnDemandWebPortal.ino
+ * example of running the webportal (always NON blocking)
+ */
+#include <WiFiManager.h> // https://github.com/tzapu/WiFiManager
+
+// select which pin will trigger the configuration portal when set to LOW
+#define TRIGGER_PIN 0
+
+WiFiManager wm;
+
+bool portalRunning = false;
+
+void setup() {
+  WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP 
+  // put your setup code here, to run once
+  Serial.begin(115200);
+  Serial.println("\n Starting");
+  pinMode(TRIGGER_PIN, INPUT_PULLUP);
+}
+
+void loop() {
+  checkButton();
+  // put your main code here, to run repeatedly:
+}
+
+void checkButton(){
+  // is auto timeout portal running
+  if(portalRunning){
+    wm.process();
+  }
+
+  // is configuration portal requested?
+  if(digitalRead(TRIGGER_PIN) == LOW) {
+    delay(50);
+    if(digitalRead(TRIGGER_PIN) == LOW) {
+      if(!portalRunning){
+        Serial.println("Button Pressed, Starting Portal");
+        wm.startWebPortal();
+        portalRunning = true;
+      }
+      else{
+        Serial.println("Button Pressed, Stopping Portal");
+        wm.startWebPortal();
+        portalRunning = false;
+      }
+    }
+  }
+}
+
+

+ 141 - 0
lib/WiFiManager-development/examples/ParamsChildClass/ParamsChildClass.ino

@@ -0,0 +1,141 @@
+/**
+ * WiFiManagerParameter child class example
+ */
+#include <WiFiManager.h> // https://github.com/tzapu/WiFiManager
+#include <Arduino.h>
+#include <EEPROM.h>
+
+#define SETUP_PIN 0
+
+class IPAddressParameter : public WiFiManagerParameter {
+public:
+    IPAddressParameter(const char *id, const char *placeholder, IPAddress address)
+        : WiFiManagerParameter("") {
+        init(id, placeholder, address.toString().c_str(), 16, "", WFM_LABEL_BEFORE);
+    }
+
+    bool getValue(IPAddress &ip) {
+        return ip.fromString(WiFiManagerParameter::getValue());
+    }
+};
+
+class IntParameter : public WiFiManagerParameter {
+public:
+    IntParameter(const char *id, const char *placeholder, long value, const uint8_t length = 10)
+        : WiFiManagerParameter("") {
+        init(id, placeholder, String(value).c_str(), length, "", WFM_LABEL_BEFORE);
+    }
+
+    long getValue() {
+        return String(WiFiManagerParameter::getValue()).toInt();
+    }
+};
+
+class FloatParameter : public WiFiManagerParameter {
+public:
+    FloatParameter(const char *id, const char *placeholder, float value, const uint8_t length = 10)
+        : WiFiManagerParameter("") {
+        init(id, placeholder, String(value).c_str(), length, "", WFM_LABEL_BEFORE);
+    }
+
+    float getValue() {
+        return String(WiFiManagerParameter::getValue()).toFloat();
+    }
+};
+
+struct Settings {
+    float f;
+    int i;
+    char s[20];
+    uint32_t ip;
+} sett;
+
+
+void setup() {
+    WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP    
+    pinMode(SETUP_PIN, INPUT_PULLUP);
+    Serial.begin(115200); 
+
+    //Delay to push SETUP button
+    Serial.println("Press setup button");
+    for (int sec = 3; sec > 0; sec--) {
+        Serial.print(sec);
+        Serial.print("..");
+        delay(1000);
+    }
+
+    EEPROM.begin( 512 );
+    EEPROM.get(0, sett);
+    Serial.println("Settings loaded");
+    
+    if (digitalRead(SETUP_PIN) == LOW) {  
+        // Button pressed 
+        Serial.println("SETUP");
+
+        WiFiManager wm;
+        
+        sett.s[19] = '\0';   //add null terminator at the end cause overflow
+        WiFiManagerParameter param_str( "str", "param_string",  sett.s, 20);
+        FloatParameter param_float( "float", "param_float",  sett.f);
+        IntParameter param_int( "int", "param_int",  sett.i);
+
+        IPAddress ip(sett.ip);
+        IPAddressParameter param_ip("ip", "param_ip", ip);
+
+        wm.addParameter( &param_str );
+        wm.addParameter( &param_float );
+        wm.addParameter( &param_int );
+        wm.addParameter( &param_ip );
+
+        //SSID & password parameters already included
+        wm.startConfigPortal();
+
+        strncpy(sett.s, param_str.getValue(), 20);
+        sett.s[19] = '\0'; 
+        sett.f = param_float.getValue();
+        sett.i = param_int.getValue();
+
+        Serial.print("String param: ");
+        Serial.println(sett.s);
+        Serial.print("Float param: ");
+        Serial.println(sett.f);
+        Serial.print("Int param: ");
+        Serial.println(sett.i, DEC);
+        
+        if (param_ip.getValue(ip)) {
+            sett.ip = ip;
+
+            Serial.print("IP param: ");
+            Serial.println(ip);
+        } else {
+            Serial.println("Incorrect IP");
+        }
+
+        EEPROM.put(0, sett);
+        if (EEPROM.commit()) {
+            Serial.println("Settings saved");
+        } else {
+            Serial.println("EEPROM error");
+        }
+    } 
+    else {  
+        Serial.println("WORK");
+
+        //connect to saved SSID
+        WiFi.begin();  
+
+        //do smth
+        Serial.print("String param: ");
+        Serial.println(sett.s);
+        Serial.print("Float param: ");
+        Serial.println(sett.f);
+        Serial.print("Int param: ");
+        Serial.println(sett.i, DEC);
+        Serial.print("IP param: ");
+        IPAddress ip(sett.ip);
+        Serial.println(ip);
+    }
+}
+
+void loop() {
+}

+ 320 - 0
lib/WiFiManager-development/extras/WiFiManager.template.html

@@ -0,0 +1,320 @@
+<!-- HTTP_HEAD -->
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\"/>
+		<title>{v}</title>
+<!-- /HTTP_HEAD -->
+<!-- HTTP_STYLE -->
+<style>
+
+:root{
+	 /* CSS VARIABLE THEME COLOR */
+	/*--primarycolor:#9933CC;*/
+	--primarycolor:#1fa3ec;
+}
+
+body.invert,
+body.invert a,
+body.invert h1 {
+	background-color:#060606;
+	color:white;
+}
+body.invert .msg{
+	background-color: #282828;
+	border-top: 1px solid #555;
+	border-right: 1px solid #555;
+	border-bottom: 1px solid #555;
+	color:#fff;
+}
+body.invert .q[role=img] {
+    -webkit-filter: invert(1);
+    filter: invert(1);
+}
+.c,
+body {
+    text-align: center;
+    font-family: verdana
+}
+.wrap {
+	text-align:left;
+	display:inline-block;
+	min-width:260px;
+	max-width:500px;
+}
+div,
+input {
+    padding: 5px;
+    font-size: 1em;
+    /*width: 100%;*/
+    margin:5px 0;
+	box-sizing: border-box;
+}
+input,button,.msg{
+	border-radius:.3rem;
+    width: 100%;
+}
+button,input[type="button"],input[type="submit"] {
+    border: 0;
+    background-color: var(--primarycolor);
+    color: #fff;
+    line-height: 2.4rem;
+    font-size: 1.2rem;
+}
+input[type="file"]{
+	border: 1px solid var(--primarycolor);
+}
+a {
+    color: #000;
+    font-weight: 700;
+    text-decoration: none;
+}
+a:hover {
+    color: var(--primarycolor);
+    text-decoration: underline;
+}
+.h {
+	display: none;
+}
+.q {
+    height: 16px;
+    margin: 0;
+    padding: 0 5px;
+    text-align: right;
+    min-width: 38px;
+    float:right;
+}
+.q.q-0:after {
+    background-position-x: 0;
+}
+.q.q-1:after {
+    background-position-x: -16px;
+}
+.q.q-2:after {
+    background-position-x: -32px;
+}
+.q.q-3:after {
+    background-position-x: -48px;
+}
+.q.q-4:after {
+    background-position-x: -64px;
+}
+.q.l:before {
+    background-position-x: -80px;
+    padding-right: 5px
+}
+.ql .q {
+    float: left;
+}
+
+.q:after,
+.q:before {
+    content: '';width:16px;height:16px;display:inline-block;background-repeat:no-repeat;background-position: 16px 0;
+ background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAAAQCAMAAADeZIrLAAAAJFBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADHJj5lAAAAC3RSTlMAIjN3iJmqu8zd7vF8pzcAAABsSURBVHja7Y1BCsAwCASNSVo3/v+/BUEiXnIoXkoX5jAQMxTHzK9cVSnvDxwD8bFx8PhZ9q8FmghXBhqA1faxk92PsxvRc2CCCFdhQCbRkLoAQ3q/wWUBqG35ZxtVzW4Ed6LngPyBU2CobdIDQ5oPWI5nCUwAAAAASUVORK5CYII=');
+}
+@media (-webkit-min-device-pixel-ratio: 2),
+(min-resolution: 192dpi) {
+    .q:before,
+    .q:after {
+        background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALwAAAAgCAMAAACfM+KhAAAALVBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAOrOgAAAADnRSTlMAESIzRGZ3iJmqu8zd7gKjCLQAAACmSURBVHgB7dDBCoMwEEXRmKlVY3L//3NLhyzqIqSUggy8uxnhCR5Mo8xLt+14aZ7wwgsvvPA/ofv9+44334UXXngvb6XsFhO/VoC2RsSv9J7x8BnYLW+AjT56ud/uePMdb7IP8Bsc/e7h8Cfk912ghsNXWPpDC4hvN+D1560A1QPORyh84VKLjjdvfPFm++i9EWq0348XXnjhhT+4dIbCW+WjZim9AKk4UZMnnCEuAAAAAElFTkSuQmCC');
+        background-size: 95px 16px;
+    }
+}
+
+.msg {
+	padding: 20px;
+	margin: 20px 0;
+	border: 1px solid #eee;
+	border-left-width: 5px;
+	border-left-color: #777;
+}
+
+.msg h4 {
+    margin-top: 0;
+	margin-bottom: 5px;
+}
+.msg.P {
+    border-left-color: var(--primarycolor);
+}
+.msg.P h4 {
+    color: var(--primarycolor);
+}
+/*.msg.S {
+    border-left-color: #5cb85c;
+}
+.msg.S h4 {
+    color: #5cb85c;
+}*/
+.msg.D {
+    border-left-color: #dc3630;
+}
+.msg.D h4 {
+    color: #dc3630;
+}
+
+dt {
+	font-weight: bold;
+}
+dd {
+	margin: 0;
+	padding: 0 0 0.5em 0;
+}
+td {
+	vertical-align: top;
+}
+button.D{
+	background-color:#dc3630;
+}
+
+input:disabled {
+	opacity: 0.5;
+}
+
+</style>
+<!-- /HTTP_STYLE -->
+<!-- HTTP_SCRIPT -->
+		<script>
+		function c(l){document.getElementById('s').value=l.innerText||l.textContent;
+		p = l.nextElementSibling.classList.contains('l');
+		document.getElementById('p').disabled = !p;
+		if(p)document.getElementById('p').focus()};
+		</script>
+<!-- /HTTP_SCRIPT -->
+<!-- HTTP_HEAD_END -->
+	</head>
+	<body class="invert">
+		<div class='wrap'>
+		<!-- <div class='wrap ql qinv'> -->
+<!-- /HTTP_HEAD_END -->
+			<!-- SAMPLE -->
+			<h2>/</h2><hR>
+			<!-- /SAMPLE -->
+			<!-- HTTP_PORTAL_OPTIONS -->
+			<!-- /HTTP_PORTAL_OPTIONS -->
+			<!-- HTTP_PORTAL_MENU[] -->
+			<form action='/wifi' method='get'><button>Configure WiFi</button></form><br/>
+			<form action='/0wifi' method='get'><button>Configure WiFi (No Scan)</button></form><br/>
+			<form action='/info' method='get'><button>Info</button></form><br/>
+			<form action='/param' method='get'><button>Setup</button></form><br/>
+			<Hr><br/>
+			<form action='/close' method='post'><button>Close</button></form><br/>
+			<form action='/erase' method='post'><button class='D'>Erase</button></form><br/>
+			<form action='/restart' method='post'><button>Restart</button></form><br/>
+			<form action='/exit' method='post'><button>Exit</button></form><br/>
+			<!-- /HTTP_PORTAL_MENU -->
+			<!-- SAMPLE -->
+			<h2>/wifi</h2><hr>
+			<div><a href='#p' onclick='c(this)'>Acccess Point 01</a><div role='img' aria-label='88%' title='88%' class='q q-4 l'></div></div>
+			<div><a href='#p' onclick='c(this)'>Acccess Point 02</a><div role='img' aria-label='88%' title='88%' class='q q-4'></div></div>
+			<div><a href='#p' onclick='c(this)'>Acccess Point 03</a><div role='img' aria-label='60%' title='60%' class='q q-3 l'></div></div>
+			<div><a href='#p' onclick='c(this)'>Acccess Point 04</a><div role='img' aria-label='60%' title='60%' class='q q-3'></div></div>
+			<div><a href='#p' onclick='c(this)'>Acccess Point 05</a><div role='img' aria-label='60%' title='60%' class='q q-3'></div></div>
+			<div><a href='#p' onclick='c(this)'>Acccess Point 06</a><div role='img' aria-label='40%' title='40%' class='q q-2'></div></div>
+			<div><a href='#p' onclick='c(this)'>Acccess Point 07</a><div role='img' aria-label='40%' title='40%' class='q q-2 l'></div></div>
+			<div><a href='#p' onclick='c(this)'>Acccess Point 08</a><div role='img' aria-label='20%' title='20%' class='q q-1'></div></div>
+			<div><a href='#p' onclick='c(this)'>Acccess Point 09</a><div role='img' aria-label='20%' title='20%' class='q q-1'></div></div>
+			<div><a href='#p' onclick='c(this)'>Acccess Point 10</a><div role='img' aria-label='20%' title='20%' class='q q-4 l'></div><div class='q '>100%</div></div>
+			<div><a href='#p' onclick='c(this)'>Acccess Point 11</a><div role='img' aria-label='10%' title='10%' class='q q-3'></div><div class='q '>70%</div></div>
+			<div><a href='#p' onclick='c(this)'>Acccess Point 12</a><div role='img' aria-label='10%' title='10%' class='q q-1 l'></div><div class='q '>10%</div></div>
+			<div><a href='#p' onclick='c(this)'>Acccess Point 13</a><div role='img' aria-label='10%' title='10%' class='q q-0 h'></div><div class='q '>100%</div></div>
+			<div><a href='#p' onclick='c(this)'>Acccess Point 14</a><div class='q'>66%</div></div>
+			<div><a href='#p' onclick='c(this)'>Acccess Point 15</a><div class='q'>56%</div></div>
+			<!-- /SAMPLE -->
+			<!-- HTTP_ITEM -->
+			<div><a href='#p' onclick='c(this)'>{v}</a><div role='img' aria-label='{r}%' title='{r}%' class='q q-{q} {i}'></div></div>
+			<!-- /HTTP_ITEM -->
+			<!-- HTTP_FORM_START -->
+			<form method='get' action='wifisave'><label for='s'>SSID</label><br/><input id='s' name='s' length=32 placeholder='SSID'><br/><label for='p'>Password</label><input id='p' name='p' length=64 type='password' placeholder='password'><br/>
+			<!-- /HTTP_FORM_START -->
+			<!-- SAMPLE -->
+			<h3>custom parameter</h3><hr>
+			<br/><label for='custom'>Label for Custom Param</label>
+			<br/><input id='custom' name='custom' length='255' placeholder='placeholder' value='' {c}>
+			<!-- /SAMPLE -->			
+			<!-- HTTP_FORM_LABEL -->
+			<br/><label for='{i}'>{p}</label>
+			<!-- /HTTP_FORM_LABEL -->
+			<!-- HTTP_FORM_PARAM -->
+			<br/><input id='{i}' name='{n}' length='{l}' placeholder='{p}' value='{v}' {c}>
+			<!-- /HTTP_FORM_PARAM -->
+			<!-- HTTP_FORM_END -->
+			<br/><button type='submit'>Save</button></form>
+			<!-- /HTTP_FORM_END -->
+			<!-- HTTP_SCAN_LINK -->
+			<br/><form action='/wifi' method='get'><button>Refresh</button></form>
+			<!-- /HTTP_SCAN_LINK -->
+			<!-- HTTP_SAVED -->
+			<div class='msg'><h4>Saving Credentials</h4>Trying to connect ESP to network.<br />If it fails reconnect to AP to try again</div>
+			<!-- /HTTP_SAVED -->
+			<!-- HTTP_STATUS_ON -->
+			<div class='msg P'><strong>Connected</strong> to {v}<br/><em><small>with IP {i}</small></em></div>
+			<!-- /HTTP_STATUS_ON -->     	
+			<!-- HTTP_STATUS_OFF -->
+			<div class='msg {c}'><strong>Not Connected</strong> to {v}{r}</div>
+			<!-- /HTTP_STATUS_OFF --> 
+			<!-- sample -->
+			<div class='msg D'><strong>Not Connected</strong> to apname
+			<!-- /sample -->
+			<!-- HTTP_STATUS_OFFPW -->
+				<br/>Authentication Failure
+			<!-- /HTTP_STATUS_OFFPW -->
+			<!-- HTTP_STATUS_OFFNOAP -->
+				<br/>AP not found
+			<!-- /HTTP_STATUS_OFFNOAP -->	
+			<!-- HTTP_STATUS_OFFFAIL -->
+				<br/>Could not Connect
+			<!-- /HTTP_STATUS_OFFFAIL -->	
+			</div>
+			<!-- HTTP_STATUS_NONE -->
+			<div class='msg'>No AP set</div>
+			<!-- /HTTP_STATUS_NONE -->
+			<!-- SAMPLE -->
+			<div class='msg P'><h4>H4 Color Header</h4>content</div>
+			<!-- /SAMPLE -->
+			<!-- SAMPLE -->
+			<h2>/info</h3><hr>
+			<dl>
+				<dt>Chip ID</dt><dd>123456</dd>
+				<dt>Flash Chip ID</dt><dd>1234556</dd>
+				<dt>IDE Flash Size</dt><dd>4194304 bytes</dd>
+				<dt>Real Flash Size</dt><dd>4194304 bytes</dd>
+				<dt>Empty</dt><dd></dd>
+				<dt>Soft AP IP</dt><dd>192.168.4.1</dd>
+				<dt>Soft AP MAC</dt><dd>00:00:00:00:00:00</dd>
+				<dt>Station MAC</dt><dd>00:00:00:00:00:00</dd>
+			</dl>
+			<!-- /SAMPLE -->
+			<!-- HTTP_HELP -->
+		 		<br/><h3>Available Pages</h3><hr>
+		 		<table class='table'>
+		 		<thead><tr><th>Page</th><th>Function</th></tr></thead><tbody>
+		 		<tr><td><a href='/'>/</a></td>
+		 		<td>Menu page.</td></tr>
+		 		<tr><td><a href='/wifi'>/wifi</a></td>
+		 		<td>Show WiFi scan results and enter WiFi configuration.(/0wifi noscan)</td></tr>
+		 		<tr><td><a href='/wifisave'>/wifisave</a></td>
+		 		<td>Save WiFi configuration information and configure device. Needs variables supplied.</td></tr>
+		 		<tr><td><a href='/close'>/close</a></td>
+		 		<td>Close the configuration server and configuration WiFi network.</td></tr>
+		 		<tr><td><a href='/info'>/info</a></td>
+		 		<td>Information page</td></tr>
+ 				<tr><td><a href='/close'>/close</a></td>
+ 				<td>Close the captiveportal popup,configportal will remain active</td></tr>
+		 		<tr><td><a href='/exit'>/exit</a></td>
+		 		<td>Exit Config Portal, configportal will close</td></tr>
+		 		<tr><td><a href='/restart'>/restart</a></td>
+		 		<td>Reboot the device</td></tr>
+		 		<tr><td><a href='/erase'>/erase</a></td>
+		 		<td>Erase WiFi configuration and reboot Device. Device will not reconnect to a network until new WiFi configuration data is entered.</td></tr>
+		 		</table>
+		 		<p/>More information about WiFiManager at <a href='https://github.com/tzapu/WiFiManager'>https://github.com/tzapu/WiFiManager</a>
+			<!-- /HTTP_HELP -->
+			<!-- FORM_UPLOAD -->
+			<Br/><br/>Form UPLOAD<br/><form method='POST' action='u' enctype='multipart/form-data'><input type='file' name='update' accept='.bin,application/octet-stream'><button type='submit' value='Submit'>Submit</button></form>
+			<!-- /FORM_UPLOAD -->	
+
+<!-- HTTP_END -->
+    </div>
+	</body>
+</html>
+<!-- /HTTP_END -->

+ 60 - 0
lib/WiFiManager-development/extras/parse.js

@@ -0,0 +1,60 @@
+'use strict';
+
+const fs = require('fs');
+
+console.log('starting');
+
+const inFile = 'WiFiManager.template.html';
+const outFile = 'template.h';
+
+const defineRegEx = /<!-- ([A-Z_]+) -->/gm;
+console.log('parsing', inFile);
+
+fs.readFile(inFile, 'utf8', function (err,data) {
+  if (err) {
+    return console.log(err);
+  }
+  //console.log(data);
+
+  let defines = data.match(defineRegEx);
+
+  //console.log(defines);
+  var stream = fs.createWriteStream(outFile);
+  stream.once('open', function(fd) {
+    for (const i in defines) {
+
+      const start = defines[i];
+      const end = start.replace('<!-- ', '<!-- /')
+      defineRegEx.lastIndex = 0;
+      const constantName = defineRegEx.exec(start)[1];
+
+      console.log(constantName);
+      var extractRE = new RegExp(start + '([\\s\\S]+)' + end, 'gm');
+      let extractArray = extractRE.exec(data);
+      if(extractArray.length > 1) {
+        let def = extractArray[1];
+        //console.log(def);
+        //minimise a bit
+        def = def.replace(/\s+/g, ' ');
+        def = def.replace(/>\s+</g, '><');
+        def = def.trim();
+        //more extraneous spaces - possible bad results, needs to be checked
+        //def = def.replace(/(\w)\s(\W)|(\W)\s(\w)|(\W)\s(\W)/g, '$1$2$3$4$5$6');
+        def = def.replace(/(\w)\s(\W)|(\W)\s(\w)/g, '$1$2$3$4');
+        //escape double quotes
+        def = def.replace(/\\([\s\S])|(")/g, "\\$1$2");
+
+
+        console.log(def);
+        //const char HTTP_HEAD[] PROGMEM            =
+        let string = 'const char ' + constantName + '[] PROGMEM';
+        for (let i = string.length; i < 42; i++) {
+          string += ' ';
+        }
+        string += '= "' + def + '";\n';
+        stream.write(string);
+      }
+    }
+    stream.end();
+  });
+});

BIN
lib/WiFiManager-development/extras/png_signal_strength_master.png


+ 12 - 0
lib/WiFiManager-development/extras/template.h

@@ -0,0 +1,12 @@
+const char HTTP_HEAD[] PROGMEM            = "<!DOCTYPE html><html lang=\"en\"><head><meta name=\"viewport\"content=\"width=device-width,initial-scale=1,user-scalable=no\"/><title>{v}</title>";
+const char HTTP_STYLE[] PROGMEM           = "<style> .c{text-align:center;}div,input{padding:5px;font-size:1em;}input{width:95%;}body{text-align:center;font-family:verdana;}button{border:0;border-radius:0.3rem;background-color:#1fa3ec;color:#fff;line-height:2.4rem;font-size:1.2rem;width:100%;} .q{float:right;width:64px;text-align:right;} .l{background:url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAALVBMVEX///8EBwfBwsLw8PAzNjaCg4NTVVUjJiZDRUUUFxdiZGSho6OSk5Pg4eFydHTCjaf3AAAAZElEQVQ4je2NSw7AIAhEBamKn97/uMXEGBvozkWb9C2Zx4xzWykBhFAeYp9gkLyZE0zIMno9n4g19hmdY39scwqVkOXaxph0ZCXQcqxSpgQpONa59wkRDOL93eAXvimwlbPbwwVAegLS1HGfZAAAAABJRU5ErkJggg==\")no-repeat left center;background-size:1em;} </style>";
+const char HTTP_SCRIPT[] PROGMEM          = "<script>function c(l){document.getElementById('s').value=l.innerText||l.textContent;document.getElementById('p').focus();} </script>";
+const char HTTP_HEAD_END[] PROGMEM        = "</head><body><div style=\"text-align:left;display:inline-block;min-width:260px;\">";
+const char HTTP_PORTAL_OPTIONS[] PROGMEM  = "<form action=\"/wifi\"method=\"get\"><button>Configure WiFi</button></form><br/><form action=\"/0wifi\"method=\"get\"><button>Configure WiFi(No Scan)</button></form><br/><form action=\"/i\"method=\"get\"><button>Info</button></form><br/><form action=\"/r\"method=\"post\"><button>Reset</button></form>";
+const char HTTP_ITEM[] PROGMEM            = "<div><a href='#p'onclick='c(this)'>{v}</a>&nbsp;<span class='q{i}'>{r}%</span></div>";
+const char HTTP_FORM_START[] PROGMEM      = "<form method='get'action='wifisave'><input id='s'name='s'length=32 placeholder='SSID'><br/><input id='p'name='p'length=64 type='password'placeholder='password'><br/>";
+const char HTTP_FORM_PARAM[] PROGMEM      = "<br/><input id='{i}'name='{n}'length={l}placeholder='{p}'value='{v}' {c}>";
+const char HTTP_FORM_END[] PROGMEM        = "<br/><button type='submit'>save</button></form>";
+const char HTTP_SCAN_LINK[] PROGMEM       = "<br/><div class=\"c\"><a href=\"/wifi\">Scan</a></div>";
+const char HTTP_SAVED[] PROGMEM           = "<div>Credentials Saved<br/>Trying to connect ESP to network.<br/>If it fails reconnect to AP to try again</div>";
+const char HTTP_END[] PROGMEM             = "</div></body></html>";

+ 182 - 0
lib/WiFiManager-development/extras/test.html

@@ -0,0 +1,182 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
+    <title>Config ESP</title>
+    <script>
+
+    function c(l,e) {
+    	console.log(l);
+    	// preventDefault();
+        document.getElementById('s').value = l.innerText || l.textContent;
+        // document.location.href = document.location +"#wmform";
+        p = l.nextElementSibling.classList.contains("l");
+        document.getElementById('p').disabled = !p;
+        if(p)document.getElementById('p').focus();
+        return false;
+    }
+
+    </script>
+
+<style>
+.c,
+body {
+    text-align: center
+}
+
+div,
+input {
+    padding: 5px;
+    font-size: 1em
+}
+
+input {
+    width: 95%
+}
+
+body {
+    font-family: verdana
+}
+
+button {
+    border: 0;
+    border-radius: .3rem;
+    background-color: #1fa3ec;
+    color: #fff;
+    line-height: 2.4rem;
+    font-size: 1.2rem;
+    width: 100%
+}
+
+a {
+    color: #000;
+    font-weight: 700;
+    text-decoration: none
+}
+
+a:hover {
+    color: #1fa3ec;
+    text-decoration: underline
+}
+
+.q {
+    height: 16px;
+    margin: 0;
+    padding: 0 5px;
+    text-align: right;
+    min-width: 38px
+}
+
+.q.q-0:after {
+    background-position-x: 0
+}
+
+.q.q-1:after {
+    background-position-x: -16px
+}
+
+.q.q-2:after {
+    background-position-x: -32px
+}
+
+.q.q-3:after {
+    background-position-x: -48px
+}
+
+.q.q-4:after {
+    background-position-x: -64px
+}
+
+.q.l:before {
+    background-position-x: -80px;
+    padding-right: 5px
+}
+
+.ql .q {
+    float: left
+}
+
+.qr .q {
+    float: right
+}
+
+.qinv .q {
+    -webkit-filter: invert(1);
+    filter: invert(1)
+}
+
+.q:after,
+.q:before {
+    content: '';
+    width: 16px;
+    height: 16px;
+    display: inline-block;
+    background-repeat: no-repeat;
+    background-position: 16px 0;
+    background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAAAQCAMAAADeZIrLAAAAJFBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADHJj5lAAAAC3RSTlMAIjN3iJmqu8zd7vF8pzcAAABsSURBVHja7Y1BCsAwCASNSVo3/v+/BUEiXnIoXkoX5jAQMxTHzK9cVSnvDxwD8bFx8PhZ9q8FmghXBhqA1faxk92PsxvRc2CCCFdhQCbRkLoAQ3q/wWUBqG35ZxtVzW4Ed6LngPyBU2CobdIDQ5oPWI5nCUwAAAAASUVORK5CYII=');
+}
+
+@media (-webkit-min-device-pixel-ratio: 2),
+(min-resolution: 192dpi) {
+    .q:before,
+    .q:after {
+        background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALwAAAAgCAMAAACfM+KhAAAALVBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAOrOgAAAADnRSTlMAESIzRGZ3iJmqu8zd7gKjCLQAAACmSURBVHgB7dDBCoMwEEXRmKlVY3L//3NLhyzqIqSUggy8uxnhCR5Mo8xLt+14aZ7wwgsvvPA/ofv9+44334UXXngvb6XsFhO/VoC2RsSv9J7x8BnYLW+AjT56ud/uePMdb7IP8Bsc/e7h8Cfk912ghsNXWPpDC4hvN+D1560A1QPORyh84VKLjjdvfPFm++i9EWq0348XXnjhhT+4dIbCW+WjZim9AKk4UZMnnCEuAAAAAElFTkSuQmCC');
+        background-size: 95px 16px;
+    }
+}
+
+input:disabled {
+    opacity: 0.5;
+}
+
+</style>
+
+</head>
+
+<body>
+ 	<!-- classes, left/right invert -->
+    <div class="qr" style='text-align:left;display:inline-block;min-width:260px;'>
+        <div><a href='#p' onclick='c(this)'>Acccess Point 01</a><div role='img' aria-label='88%' title='88%' class='q q-4 l'></div></div>
+        <div><a href='#p' onclick='c(this)'>Acccess Point 02</a><div role='img' aria-label='88%' title='88%' class='q q-4'></div></div>
+        <div><a href='#p' onclick='c(this)'>Acccess Point 03</a><div role='img' aria-label='88%' title='88%' class='q q-3'></div></div>
+        <div><a href='#p' onclick='c(this)'>Acccess Point 04</a><div role='img' aria-label='88%' title='88%' class='q q-3'></div></div>
+        <div><a href='#p' onclick='c(this)'>Acccess Point 05</a><div role='img' aria-label='88%' title='88%' class='q q-3'></div></div>
+        <div><a href='#p' onclick='c(this)'>Acccess Point 06</a><div role='img' aria-label='88%' title='88%' class='q q-2'></div></div>
+        <div><a href='#p' onclick='c(this)'>Acccess Point 07</a><div role='img' aria-label='88%' title='88%' class='q q-2'></div></div>
+        <div><a href='#p' onclick='c(this)'>Acccess Point 08</a><div role='img' aria-label='88%' title='88%' class='q q-1'></div></div>
+        <div><a href='#p' onclick='c(this)'>Acccess Point 09</a><div role='img' aria-label='88%' title='88%' class='q q-1'></div></div>
+        <div><a href='#p' onclick='c(this)'>Acccess Point 10</a><div role='img' aria-label='88%' title='88%' class='q q-1'></div></div>
+        <div><a href='#p' onclick='c(this)'>Acccess Point 11</a><div role='img' aria-label='88%' title='88%' class='q q-0'></div></div>
+        <div><a href='#p' onclick='c(this)'>Acccess Point 12</a><div role='img' aria-label='88%' title='88%' class='q q-0'></div></div>
+        <div><a href='#p' onclick='c(this)'>Acccess Point 13</a><div role='img' aria-label='88%' title='88%' class='q q-0'></div></div>
+        <div><a href='#p' onclick='c(this)'>Acccess Point 14</a><div role='img' aria-label='88%' title='88%' class='q q-0 l'></div></div>
+        <br/>
+        <form id="wmform" method='get' action='wifisave'>
+            <input id='s' name='s' length=32 placeholder='SSID'>
+            <br/>
+            <input id='p' name='p' length=64 type='password' placeholder='password'>
+            <br/>
+            <br/>
+            <input id='server' name='server' length=4 placeholder='mqtt server' value=''>
+            <br/>
+            <input id='port' name='port' length=5 placeholder='mqtt port' value='8080'>
+            <br/>
+            <input id='blynk' name='blynk' length=3 placeholder='blynk token' value='YOUR_BLYNK_TOKEN'>
+            <br/>
+            <br/>
+            <input id='ip' name='ip' length=15 placeholder='Static IP' value='10.0.1.56'>
+            <br/>
+            <input id='gw' name='gw' length=15 placeholder='Static Gateway' value='10.0.1.1'>
+            <br/>
+            <input id='sn' name='sn' length=15 placeholder='Subnet' value='255.255.255.0'>
+            <br/>
+            <br/>
+            <button type='submit'>save</button>
+        </form>
+        <br/>
+        <div class="c"><a href="/wifi">Scan</a></div>
+    </div>
+</body>
+
+</html>

+ 39 - 0
lib/WiFiManager-development/keywords.txt

@@ -0,0 +1,39 @@
+#######################################
+# Syntax Coloring Map For WifiManager
+#######################################
+
+#######################################
+# Datatypes (KEYWORD1)
+#######################################
+
+WiFiManager	KEYWORD1
+WiFiManagerParameter KEYWORD1
+
+
+#######################################
+# Methods and Functions (KEYWORD2)
+#######################################
+autoConnect	KEYWORD2
+getSSID	KEYWORD2
+getPassword	KEYWORD2
+getConfigPortalSSID KEYWORD2
+resetSettings	KEYWORD2
+setConfigPortalTimeout	KEYWORD2
+setConnectTimeout KEYWORD2
+setDebugOutput	KEYWORD2
+setMinimumSignalQuality KEYWORD2
+setAPStaticIPConfig	KEYWORD2
+setSTAStaticIPConfig KEYWORD2
+setAPCallback	KEYWORD2
+setSaveConfigCallback KEYWORD2
+addParameter KEYWORD2
+getID KEYWORD2
+getValue KEYWORD2
+getPlaceholder KEYWORD2
+getValueLength KEYWORD2
+
+#######################################
+# Constants (LITERAL1)
+#######################################
+
+#	LITERAL1

+ 29 - 0
lib/WiFiManager-development/library.json

@@ -0,0 +1,29 @@
+{
+  "name": "WifiManager",
+  "keywords": "wifi,wi-fi,esp,esp8266,esp32,espressif8266,espressif32,nodemcu,wemos,arduino",
+  "description": "WiFi Configuration manager with web configuration portal for ESP boards",
+"authors":
+[
+    {
+        "name": "tzapu",
+        "url": "https://github.com/tzapu"
+    },
+    {
+        "name": "tablatronix",
+        "url": "https://github.com/tablatronix",
+        "maintainer": true
+    }
+],
+"repository":
+  {
+    "type": "git",
+    "url": "https://github.com/tzapu/WiFiManager.git"
+  },
+  "frameworks": "arduino",
+  "platforms": 
+  [
+    "espressif8266",
+    "espressif32"
+  ],
+  "version": "1.0.0"
+}

+ 9 - 0
lib/WiFiManager-development/library.properties

@@ -0,0 +1,9 @@
+name=WiFiManager
+version=1.0.0
+author=tzapu,tablatronix
+maintainer=tablatronix
+sentence=WiFi Configuration manager with web configuration portal for ESP boards
+paragraph=Library for configuring ESP8266/ESP32 modules WiFi credentials and custom parameters at runtime.
+category=Communication
+url=https://github.com/tzapu/WiFiManager.git
+architectures=esp8266,esp32

+ 362 - 0
lib/WiFiManager-development/strings_en.h

@@ -0,0 +1,362 @@
+/**
+ * strings_en.h
+ * engligh strings for
+ * WiFiManager, a library for the ESP8266/Arduino platform
+ * for configuration of WiFi credentials using a Captive Portal
+ * 
+ * @author Creator tzapu
+ * @author tablatronix
+ * @version 0.0.0
+ * @license MIT
+ */
+
+#ifndef _WM_STRINGS_H_
+#define _WM_STRINGS_H_
+
+#ifndef WIFI_MANAGER_OVERRIDE_STRINGS
+// !!! THIS DOES NOT WORK, you cannot define in a sketch, if anyone one knows how to order includes to be able to do this help!
+
+const char HTTP_HEAD_START[]       PROGMEM = "<!DOCTYPE html><html lang='en'><head><meta name='format-detection' content='telephone=no'><meta charset='UTF-8'><meta  name='viewport' content='width=device-width,initial-scale=1,user-scalable=no'/><title>{v}</title>";
+const char HTTP_SCRIPT[]           PROGMEM = "<script>function c(l){"
+"document.getElementById('s').value=l.innerText||l.textContent;"
+"p = l.nextElementSibling.classList.contains('l');"
+"alert(p);"
+"document.getElementById('p').disabled = !p;"
+"if(p)document.getElementById('p').focus();}</script>";
+
+const char HTTP_HEAD_END[]         PROGMEM = "</head><body class='{c}'><div class='wrap'>";
+
+const char HTTP_ROOT_MAIN[]        PROGMEM = "<h1>{v}</h1><h3>WiFiManager</h3>";
+const char * const HTTP_PORTAL_MENU[] PROGMEM = {
+"<form action='/wifi'    method='get'><button>Configure WiFi</button></form><br/>\n", // MENU_WIFI
+"<form action='/0wifi'   method='get'><button>Configure WiFi (No Scan)</button></form><br/>\n", // MENU_WIFINOSCAN
+"<form action='/info'    method='get'><button>Info</button></form><br/>\n", // MENU_INFO
+"<form action='/param'   method='get'><button>Setup</button></form><br/>\n",//MENU_PARAM
+"<form action='/close'   method='get'><button>Close</button></form><br/>\n", // MENU_CLOSE
+"<form action='/restart' method='get'><button>Restart</button></form><br/>\n",// MENU_RESTART
+"<form action='/exit'    method='get'><button>Exit</button></form><br/>\n",  // MENU_EXIT
+"<form action='/erase'   method='get'><button class='D'>Erase</button></form><br/>\n", // MENU_ERASE
+"<hr><br/>" // MENU_SEP
+};
+
+// const char HTTP_PORTAL_OPTIONS[]   PROGMEM = strcat(HTTP_PORTAL_MENU[0] , HTTP_PORTAL_MENU[3] , HTTP_PORTAL_MENU[7]);
+const char HTTP_PORTAL_OPTIONS[]   PROGMEM = "";
+const char HTTP_ITEM_QI[]          PROGMEM = "<div role='img' aria-label='{r}%' title='{r}%' class='q q-{q} {i} {h}'></div>"; // rssi icons
+const char HTTP_ITEM_QP[]          PROGMEM = "<div class='q {h}'>{r}%</div>"; // rssi percentage
+const char HTTP_ITEM[]             PROGMEM = "<div><a href='#p' onclick='c(this)'>{v}</a>{qi}{qp}</div>"; // {q} = HTTP_ITEM_QI, {r} = HTTP_ITEM_QP
+// const char HTTP_ITEM[]            PROGMEM = "<div><a href='#p' onclick='c(this)'>{v}</a> {R} {r}% {q} {e}</div>"; // test all tokens
+
+const char HTTP_FORM_START[]       PROGMEM = "<form method='POST' action='{v}'>";
+const char HTTP_FORM_WIFI[]        PROGMEM = "<label for='s'>SSID</label><input id='s' name='s' maxlength='32' autocorrect='off' autocapitalize='none' placeholder='{v}'><br/><label for='p'>Password</label><input id='p' name='p' maxlength='64' type='password' placeholder='{p}'>";
+const char HTTP_FORM_WIFI_END[]    PROGMEM = "";
+const char HTTP_FORM_STATIC_HEAD[] PROGMEM = "<hr><br/>";
+const char HTTP_FORM_END[]         PROGMEM = "<br/><br/><button type='submit'>Save</button></form>";
+const char HTTP_FORM_LABEL[]       PROGMEM = "<label for='{i}'>{t}</label>";
+const char HTTP_FORM_PARAM_HEAD[]  PROGMEM = "<hr><br/>";
+const char HTTP_FORM_PARAM[]       PROGMEM = "<br/><input id='{i}' name='{n}' maxlength='{l}' value='{v}' {c}>";
+
+const char HTTP_SCAN_LINK[]        PROGMEM = "<br/><form action='/wifi?refresh=1' method='POST'><button name='refresh' value='1'>Refresh</button></form>";
+const char HTTP_SAVED[]            PROGMEM = "<div class='msg'>Saving Credentials<br/>Trying to connect ESP to network.<br />If it fails reconnect to AP to try again</div>";
+const char HTTP_PARAMSAVED[]       PROGMEM = "<div class='msg'>Saved<br/></div>";
+const char HTTP_END[]              PROGMEM = "</div></body></html>";
+const char HTTP_ERASEBTN[]         PROGMEM = "<br/><form action='/erase' method='get'><button class='D'>Erase WiFi Config</button></form>";
+
+const char HTTP_STATUS_ON[]        PROGMEM = "<div class='msg P'><strong>Connected</strong> to {v}<br/><em><small>with IP {i}</small></em></div>";
+const char HTTP_STATUS_OFF[]       PROGMEM = "<div class='msg {c}'><strong>Not Connected</strong> to {v}{r}</div>";
+const char HTTP_STATUS_OFFPW[]     PROGMEM = "<br/>Authentication Failure"; // STATION_WRONG_PASSWORD,  no eps32
+const char HTTP_STATUS_OFFNOAP[]   PROGMEM = "<br/>AP not found";   // WL_NO_SSID_AVAIL
+const char HTTP_STATUS_OFFFAIL[]   PROGMEM = "<br/>Could not Connect"; // WL_CONNECT_FAILED
+const char HTTP_STATUS_NONE[]      PROGMEM = "<div class='msg'>No AP set</div>";
+const char HTTP_BR[]               PROGMEM = "<br/>";
+
+const char HTTP_STYLE[]            PROGMEM = "<style>"
+".c,body{text-align:center;font-family:verdana}div,input{padding:5px;font-size:1em;margin:5px 0;box-sizing:border-box;}"
+"input,button,.msg{border-radius:.3rem;width: 100%}"
+"button,input[type='button'],input[type='submit']{cursor:pointer;border:0;background-color:#1fa3ec;color:#fff;line-height:2.4rem;font-size:1.2rem;width:100%}"
+"input[type='file']{border:1px solid #1fa3ec}"
+".wrap {text-align:left;display:inline-block;min-width:260px;max-width:500px}"
+// links
+"a{color:#000;font-weight:700;text-decoration:none}a:hover{color:#1fa3ec;text-decoration:underline}"
+// quality icons
+".q{height:16px;margin:0;padding:0 5px;text-align:right;min-width:38px;float:right}.q.q-0:after{background-position-x:0}.q.q-1:after{background-position-x:-16px}.q.q-2:after{background-position-x:-32px}.q.q-3:after{background-position-x:-48px}.q.q-4:after{background-position-x:-64px}.q.l:before{background-position-x:-80px;padding-right:5px}.ql .q{float:left}.q:after,.q:before{content:'';width:16px;height:16px;display:inline-block;background-repeat:no-repeat;background-position: 16px 0;"
+"background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAAAQCAMAAADeZIrLAAAAJFBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADHJj5lAAAAC3RSTlMAIjN3iJmqu8zd7vF8pzcAAABsSURBVHja7Y1BCsAwCASNSVo3/v+/BUEiXnIoXkoX5jAQMxTHzK9cVSnvDxwD8bFx8PhZ9q8FmghXBhqA1faxk92PsxvRc2CCCFdhQCbRkLoAQ3q/wWUBqG35ZxtVzW4Ed6LngPyBU2CobdIDQ5oPWI5nCUwAAAAASUVORK5CYII=');}"
+// icons @2x media query (32px rescaled)
+"@media (-webkit-min-device-pixel-ratio: 2),(min-resolution: 192dpi){.q:before,.q:after {"
+"background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALwAAAAgCAMAAACfM+KhAAAALVBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAOrOgAAAADnRSTlMAESIzRGZ3iJmqu8zd7gKjCLQAAACmSURBVHgB7dDBCoMwEEXRmKlVY3L//3NLhyzqIqSUggy8uxnhCR5Mo8xLt+14aZ7wwgsvvPA/ofv9+44334UXXngvb6XsFhO/VoC2RsSv9J7x8BnYLW+AjT56ud/uePMdb7IP8Bsc/e7h8Cfk912ghsNXWPpDC4hvN+D1560A1QPORyh84VKLjjdvfPFm++i9EWq0348XXnjhhT+4dIbCW+WjZim9AKk4UZMnnCEuAAAAAElFTkSuQmCC');"
+"background-size: 95px 16px;}}"
+// msg callouts
+".msg{padding:20px;margin:20px 0;border:1px solid #eee;border-left-width:5px;border-left-color:#777}.msg h4{margin-top:0;margin-bottom:5px}.msg.P{border-left-color:#1fa3ec}.msg.P h4{color:#1fa3ec}.msg.D{border-left-color:#dc3630}.msg.D h4{color:#dc3630}"
+// lists
+"dt{font-weight:bold}dd{margin:0;padding:0 0 0.5em 0;min-height:12px}"
+"td{vertical-align: top;}"
+".h{display:none}"
+"button.D{background-color:#dc3630}"
+// invert
+"body.invert,body.invert a,body.invert h1 {background-color:#060606;color:#fff;}"
+"body.invert .msg{color:#fff;background-color:#282828;border-top:1px solid #555;border-right:1px solid #555;border-bottom:1px solid #555;}"
+"body.invert .q[role=img]{-webkit-filter:invert(1);filter:invert(1);}"
+"input:disabled {opacity: 0.5;}"
+"</style>";
+
+const char HTTP_HELP[]             PROGMEM =
+ "<br/><h3>Available Pages</h3><hr>"
+ "<table class='table'>"
+ "<thead><tr><th>Page</th><th>Function</th></tr></thead><tbody>"
+ "<tr><td><a href='/'>/</a></td>"
+ "<td>Menu page.</td></tr>"
+ "<tr><td><a href='/wifi'>/wifi</a></td>"
+ "<td>Show WiFi scan results and enter WiFi configuration.(/0wifi noscan)</td></tr>"
+ "<tr><td><a href='/wifisave'>/wifisave</a></td>"
+ "<td>Save WiFi configuration information and configure device. Needs variables supplied.</td></tr>"
+ "<tr><td><a href='/param'>/param</a></td>"
+ "<td>Parameter page</td></tr>"
+ "<tr><td><a href='/info'>/info</a></td>"
+ "<td>Information page</td></tr>"
+ "<tr><td><a href='/close'>/close</a></td>"
+ "<td>Close the captiveportal popup,configportal will remain active</td></tr>"
+ "<tr><td><a href='/exit'>/exit</a></td>"
+ "<td>Exit Config Portal, configportal will close</td></tr>"
+ "<tr><td><a href='/restart'>/restart</a></td>"
+ "<td>Reboot the device</td></tr>"
+ "<tr><td><a href='/erase'>/erase</a></td>"
+ "<td>Erase WiFi configuration and reboot Device. Device will not reconnect to a network until new WiFi configuration data is entered.</td></tr>"
+ "</table>"
+ "<p/>More information about WiFiManager at <a href='https://github.com/tzapu/WiFiManager'>https://github.com/tzapu/WiFiManager</a>.";
+
+#ifdef JSTEST
+const char HTTP_JS[] PROGMEM = 
+"<script>function postAjax(url, data, success) {"
+"    var params = typeof data == 'string' ? data : Object.keys(data).map("
+"            function(k){ return encodeURIComponent(k) + '=' + encodeURIComponent(data[k]) }"
+"        ).join('&');"
+"    var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject(\"Microsoft.XMLHTTP\");"
+"    xhr.open('POST', url);"
+"    xhr.onreadystatechange = function() {"
+"        if (xhr.readyState>3 && xhr.status==200) { success(xhr.responseText); }"
+"    };"
+"    xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');"
+"    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');"
+"    xhr.send(params);"
+"    return xhr;}"
+"postAjax('/status', 'p1=1&p2=Hello+World', function(data){ console.log(data); });"
+"postAjax('/status', { p1: 1, p2: 'Hello World' }, function(data){ console.log(data); });"
+"</script>";
+#endif
+
+// Info html
+#ifdef ESP32
+	const char HTTP_INFO_esphead[]    PROGMEM = "<h3>esp32</h3><hr><dl>";
+	const char HTTP_INFO_chiprev[]    PROGMEM = "<dt>Chip Rev</dt><dd>{1}</dd>";
+  const char HTTP_INFO_lastreset[]    PROGMEM = "<dt>Last reset reason</dt><dd>CPU0: {1}<br/>CPU1: {2}</dd>";
+  const char HTTP_INFO_aphost[]       PROGMEM = "<dt>Acccess Point Hostname</dt><dd>{1}</dd>";  
+#else 
+	const char HTTP_INFO_esphead[]    PROGMEM = "<h3>esp8266</h3><hr><dl>";
+	const char HTTP_INFO_flashsize[]  PROGMEM = "<dt>Real Flash Size</dt><dd>{1} bytes</dd>";
+	const char HTTP_INFO_fchipid[]    PROGMEM = "<dt>Flash Chip ID</dt><dd>{1}</dd>";
+	const char HTTP_INFO_corever[]    PROGMEM = "<dt>Core Version</dt><dd>{1}</dd>";
+	const char HTTP_INFO_bootver[]    PROGMEM = "<dt>Boot Version</dt><dd>{1}</dd>";
+	const char HTTP_INFO_memsketch[]  PROGMEM = "<dt>Memory - Sketch Size</dt><dd>Used / Total bytes<br/>{1} / {2}";
+	const char HTTP_INFO_memsmeter[]  PROGMEM = "<br/><progress value='{1}' max='{2}'></progress></dd>";
+	const char HTTP_INFO_lastreset[]  PROGMEM = "<dt>Last reset reason</dt><dd>{1}</dd>";
+#endif
+
+const char HTTP_INFO_freeheap[]   PROGMEM = "<dt>Memory - Free Heap</dt><dd>{1} bytes available</dd>"; 
+const char HTTP_INFO_wifihead[]   PROGMEM = "<br/><h3>WiFi</h3><hr>";
+const char HTTP_INFO_uptime[]     PROGMEM = "<dt>Uptime</dt><dd>{1} Mins {2} Secs</dd>";
+const char HTTP_INFO_chipid[]     PROGMEM = "<dt>Chip ID</dt><dd>{1}</dd>";
+const char HTTP_INFO_idesize[]    PROGMEM = "<dt>Flash Size</dt><dd>{1} bytes</dd>";
+const char HTTP_INFO_sdkver[]     PROGMEM = "<dt>SDK Version</dt><dd>{1}</dd>";
+const char HTTP_INFO_cpufreq[]    PROGMEM = "<dt>CPU Frequency</dt><dd>{1}MHz</dd>";
+const char HTTP_INFO_apip[]       PROGMEM = "<dt>Access Point IP</dt><dd>{1}</dd>";
+const char HTTP_INFO_apmac[]      PROGMEM = "<dt>Access Point MAC</dt><dd>{1}</dd>";
+const char HTTP_INFO_apssid[]     PROGMEM = "<dt>SSID</dt><dd>{1}</dd>";
+const char HTTP_INFO_apbssid[]    PROGMEM = "<dt>BSSID</dt><dd>{1}</dd>";
+const char HTTP_INFO_staip[]      PROGMEM = "<dt>Station IP</dt><dd>{1}</dd>";
+const char HTTP_INFO_stagw[]      PROGMEM = "<dt>Station Gateway</dt><dd>{1}</dd>";
+const char HTTP_INFO_stasub[]     PROGMEM = "<dt>Station Subnet</dt><dd>{1}</dd>";
+const char HTTP_INFO_dnss[]       PROGMEM = "<dt>DNS Server</dt><dd>{1}</dd>";
+const char HTTP_INFO_host[]       PROGMEM = "<dt>Hostname</dt><dd>{1}</dd>";
+const char HTTP_INFO_stamac[]     PROGMEM = "<dt>Station MAC</dt><dd>{1}</dd>";
+const char HTTP_INFO_conx[]       PROGMEM = "<dt>Connected</dt><dd>{1}</dd>";
+const char HTTP_INFO_autoconx[]   PROGMEM = "<dt>Autoconnect</dt><dd>{1}</dd>";
+const char HTTP_INFO_temp[]       PROGMEM = "<dt>Temperature</dt><dd>{1} C&deg; / {2} F&deg;</dd>";
+
+// Strings
+const char S_y[]                  PROGMEM = "Yes";
+const char S_n[]                  PROGMEM = "No";
+const char S_enable[]             PROGMEM = "Enabled";
+const char S_disable[]            PROGMEM = "Disabled";
+const char S_GET[]                PROGMEM = "GET";
+const char S_POST[]               PROGMEM = "POST";
+const char S_NA[]                 PROGMEM = "Unknown";
+const char S_passph[]             PROGMEM = "********";
+const char S_titlewifisaved[]     PROGMEM = "Credentials Saved";
+const char S_titlewifisettings[]  PROGMEM = "Settings Saved";
+const char S_titlewifi[]          PROGMEM = "Config ESP";
+const char S_titleinfo[]          PROGMEM = "Info";
+const char S_titleparam[]         PROGMEM = "Setup";
+const char S_titleparamsaved[]    PROGMEM = "Setup Saved";
+const char S_titleexit[]          PROGMEM = "Exit";
+const char S_titlereset[]         PROGMEM = "Reset";
+const char S_titleerase[]         PROGMEM = "Erase";
+const char S_titleclose[]         PROGMEM = "Close";
+const char S_options[]            PROGMEM = "options";
+const char S_nonetworks[]         PROGMEM = "No networks found. Refresh to scan again.";
+const char S_staticip[]           PROGMEM = "Static IP";
+const char S_staticgw[]           PROGMEM = "Static Gateway";
+const char S_staticdns[]          PROGMEM = "Static DNS";
+const char S_subnet[]             PROGMEM = "Subnet";
+const char S_exiting[]            PROGMEM = "Exiting";
+const char S_resetting[]          PROGMEM = "Module will reset in a few seconds.";
+const char S_closing[]            PROGMEM = "You can close the page, portal will continue to run";
+const char S_error[]              PROGMEM = "An Error Occured";
+const char S_notfound[]           PROGMEM = "File Not Found\n\n";
+const char S_uri[]                PROGMEM = "URI: ";
+const char S_method[]             PROGMEM = "\nMethod: ";
+const char S_args[]               PROGMEM = "\nArguments: ";
+const char S_parampre[]           PROGMEM = "param_";
+
+// debug strings
+const char D_HR[]                 PROGMEM = "--------------------";
+
+// END WIFI_MANAGER_OVERRIDE_STRINGS
+#endif
+
+// -----------------------------------------------------------------------------------------------
+// DO NOT EDIT BELOW THIS LINE
+
+const uint8_t _nummenutokens = 9;
+const char * const _menutokens[9] PROGMEM = {
+    "wifi",
+    "wifinoscan",
+    "info",
+    "param",
+    "close",
+    "restart",
+    "exit",
+    "erase",
+    "sep"
+};
+
+const char R_root[]               PROGMEM = "/";
+const char R_wifi[]               PROGMEM = "/wifi";
+const char R_wifinoscan[]         PROGMEM = "/0wifi";
+const char R_wifisave[]           PROGMEM = "/wifisave";
+const char R_info[]               PROGMEM = "/info";
+const char R_param[]              PROGMEM = "/param";
+const char R_paramsave[]          PROGMEM = "/paramsave";
+const char R_restart[]            PROGMEM = "/restart";
+const char R_exit[]               PROGMEM = "/exit";
+const char R_close[]              PROGMEM = "/close";
+const char R_erase[]              PROGMEM = "/erase"; 
+const char R_status[]             PROGMEM = "/status";
+
+
+//Strings
+const char S_ip[]                 PROGMEM = "ip";
+const char S_gw[]                 PROGMEM = "gw";
+const char S_sn[]                 PROGMEM = "sn";
+const char S_dns[]                PROGMEM = "dns";
+
+// softap ssid default prefix
+#ifdef ESP8266
+	const char S_ssidpre[]        PROGMEM = "ESP";
+#elif defined(ESP32)
+	const char S_ssidpre[]        PROGMEM = "ESP32";
+#else
+	const char S_ssidpre[]        PROGMEM = "WM";
+#endif
+
+//Tokens
+//@todo consolidate and reduce
+const char T_ss[]                 PROGMEM = "{"; // token start sentinel
+const char T_es[]                 PROGMEM = "}"; // token end sentinel
+const char T_1[]                  PROGMEM = "{1}"; // @token 1
+const char T_2[]                  PROGMEM = "{2}"; // @token 2
+const char T_v[]                  PROGMEM = "{v}"; // @token v
+const char T_I[]                  PROGMEM = "{I}"; // @token I
+const char T_i[]                  PROGMEM = "{i}"; // @token i
+const char T_n[]                  PROGMEM = "{n}"; // @token n
+const char T_p[]                  PROGMEM = "{p}"; // @token p
+const char T_t[]                  PROGMEM = "{t}"; // @token t
+const char T_l[]                  PROGMEM = "{l}"; // @token l
+const char T_c[]                  PROGMEM = "{c}"; // @token c
+const char T_e[]                  PROGMEM = "{e}"; // @token e
+const char T_q[]                  PROGMEM = "{q}"; // @token q
+const char T_r[]                  PROGMEM = "{r}"; // @token r
+const char T_R[]                  PROGMEM = "{R}"; // @token R
+const char T_h[]                  PROGMEM = "{h}"; // @token h
+
+// http
+const char HTTP_HEAD_CL[]         PROGMEM = "Content-Length";
+const char HTTP_HEAD_CT[]         PROGMEM = "text/html";
+const char HTTP_HEAD_CT2[]        PROGMEM = "text/plain";
+const char HTTP_HEAD_CORS[]       PROGMEM = "Access-Control-Allow-Origin";
+const char HTTP_HEAD_CORS_ALLOW_ALL[]  PROGMEM = "*";
+
+const char * const WIFI_STA_STATUS[] PROGMEM
+{
+  "WL_IDLE_STATUS",     // 0 STATION_IDLE
+  "WL_NO_SSID_AVAIL",   // 1 STATION_NO_AP_FOUND
+  "WL_SCAN_COMPLETED",  // 2
+  "WL_CONNECTED",       // 3 STATION_GOT_IP
+  "WL_CONNECT_FAILED",  // 4 STATION_CONNECT_FAIL, STATION_WRONG_PASSWORD(NI)
+  "WL_CONNECTION_LOST", // 5
+  "WL_DISCONNECTED",    // 6 
+  "WL_STATION_WRONG_PASSWORD" // 7 KLUDGE 
+};
+
+#ifdef ESP32
+const char * const AUTH_MODE_NAMES[] PROGMEM
+{
+    "OPEN",
+    "WEP",             
+    "WPA_PSK",         
+    "WPA2_PSK",        
+    "WPA_WPA2_PSK",    
+    "WPA2_ENTERPRISE", 
+    "MAX"
+};
+#elif defined(ESP8266)
+const char * const AUTH_MODE_NAMES[] PROGMEM
+{
+    "",
+    "",
+    "WPA_PSK",      // 2 ENC_TYPE_TKIP
+    "",
+    "WPA2_PSK",     // 4 ENC_TYPE_CCMP
+    "WEP",          // 5 ENC_TYPE_WEP
+    "",
+    "OPEN",         //7 ENC_TYPE_NONE
+    "WPA_WPA2_PSK", // 8 ENC_TYPE_AUTO
+};
+#endif
+
+const char* const WIFI_MODES[] PROGMEM = { "NULL", "STA", "AP", "STA+AP" };
+
+
+#ifdef ESP32
+// as 2.5.2
+// typedef struct {
+//     char                  cc[3];   /**< country code string */
+//     uint8_t               schan;   /**< start channel */
+//     uint8_t               nchan;   /**< total channel number */
+//     int8_t                max_tx_power;   /**< This field is used for getting WiFi maximum transmitting power, call esp_wifi_set_max_tx_power to set the maximum transmitting power. */
+//     wifi_country_policy_t policy;  /**< country policy */
+// } wifi_country_t;
+const wifi_country_t WM_COUNTRY_US{"US",1,11,CONFIG_ESP32_PHY_MAX_TX_POWER,WIFI_COUNTRY_POLICY_AUTO};
+const wifi_country_t WM_COUNTRY_CN{"CN",1,13,CONFIG_ESP32_PHY_MAX_TX_POWER,WIFI_COUNTRY_POLICY_AUTO};
+const wifi_country_t WM_COUNTRY_JP{"JP",1,14,CONFIG_ESP32_PHY_MAX_TX_POWER,WIFI_COUNTRY_POLICY_AUTO};
+#elif defined(ESP8266)
+// typedef struct {
+//     char cc[3];               /**< country code string */
+//     uint8_t schan;            /**< start channel */
+//     uint8_t nchan;            /**< total channel number */
+//     uint8_t policy;           /**< country policy */
+// } wifi_country_t;
+const wifi_country_t WM_COUNTRY_US{"US",1,11,WIFI_COUNTRY_POLICY_AUTO};
+const wifi_country_t WM_COUNTRY_CN{"CN",1,13,WIFI_COUNTRY_POLICY_AUTO};
+const wifi_country_t WM_COUNTRY_JP{"JP",1,14,WIFI_COUNTRY_POLICY_AUTO};
+#endif
+
+#endif

+ 60 - 0
lib/WiFiManager-development/travis/common.sh

@@ -0,0 +1,60 @@
+#!/bin/bash
+
+function build_examples()
+{
+  excludes=("$@")
+  # track the exit code for this platform
+  local exit_code=0
+  # loop through results and add them to the array
+  examples=($(find $PWD/examples/ -name "*.pde" -o -name "*.ino"))
+
+  # get the last example in the array
+  local last="${examples[@]:(-1)}"
+
+  # loop through example sketches
+  for example in "${examples[@]}"; do
+
+    # store the full path to the example's sketch directory
+    local example_dir=$(dirname $example)
+
+    # store the filename for the example without the path
+    local example_file=$(basename $example)
+
+    # skip files listed as excludes
+    for exclude in "${excludes[@]}"; do
+        if [ "${example_file}" == "${exclude}" ] ; then
+            echo ">>>>>>>>>>>>>>>>>>>>>>>> Skipping ${example_file} <<<<<<<<<<<<<<<<<<<<<<<<<<"
+            continue 2
+        fi
+    done
+    
+    echo "$example_file: "
+    local sketch="$example_dir/$example_file"
+    echo "$sketch"
+    #arduino -v --verbose-build --verify $sketch
+
+    # verify the example, and save stdout & stderr to a variable
+    # we have to avoid reading the exit code of local:
+    # "when declaring a local variable in a function, the local acts as a command in its own right"
+    local build_stdout
+    build_stdout=$(arduino --verify $sketch 2>&1)
+
+    # echo output if the build failed
+    if [ $? -ne 0 ]; then
+      # heavy X
+      echo -e "\xe2\x9c\x96"
+      echo -e "----------------------------- DEBUG OUTPUT -----------------------------\n"
+      echo "$build_stdout"
+      echo -e "\n------------------------------------------------------------------------\n"
+
+      # mark as fail
+      exit_code=1
+
+    else
+      # heavy checkmark
+      echo -e "\xe2\x9c\x93"
+    fi
+  done
+
+  return $exit_code
+}

+ 45 - 2
platformio.ini

@@ -2,17 +2,60 @@
 ;
 ;   Build options: build flags, source filter
 ;   Upload options: custom upload port, speed and extra flags
-;   Library options: dependencies, extra library storages 
+;   Library options: dependencies, extra library storages
 ;   Advanced options: extra scripting
 ;
 ; Please visit documentation for the other options and examples
 ; https://docs.platformio.org/page/projectconf.html
 
+[env:Gateway_21]
+platform = espressif8266
+board = d1_mini
+board_build.mcu = esp8266
+board_build.f_cpu = 80000000L
+build_flags =
+  -D _WIFIMANAGER=1
+  -D OLED=0
+framework = arduino
+upload_protocol = espota
+board_build.flash_mode = qio
+upload_speed = 115200
+upload_port = 192.168.2.21
+
+[env:Gateway_22]
+platform = espressif8266
+board = d1_mini
+board_build.mcu = esp8266
+board_build.f_cpu = 80000000L
+build_flags =
+  -D OLED=1
+framework = arduino
+upload_protocol = espota
+board_build.flash_mode = qio
+upload_speed = 115200
+upload_port = 192.168.2.22
+
+[env:Gateway_31]
+platform = espressif8266
+board = d1_mini
+board_build.mcu = esp8266
+board_build.f_cpu = 80000000L
+build_flags =
+  -D _PIN_OUT=2
+  -D OLED=2
+framework = arduino
+upload_protocol = espota
+board_build.flash_mode = qio
+upload_speed = 115200
+upload_port = 192.168.2.31
+
 [env:Gateway_59]
 platform = espressif32
 board = heltec_wifi_lora_32
+build_flags =
+  -D _WIFIMANAGER=1
 framework = arduino
 upload_protocol = espota
 board_build.flash_mode = qio
 upload_speed = 115200
-upload_port = 192.168.2.59
+upload_port = 192.168.2.59

+ 22 - 12
src/ESP-sc-gway.ino

@@ -24,6 +24,16 @@
 //
 // ----------------------------------------------------------------------------------------
 
+#if defined (ARDUINO_ARCH_ESP32) || defined(ESP32)
+#	define ESP32_ARCH 1
+#	define _PIN_OUT 4										// For ESP32 this pin-out is standard
+#elif defined(ARDUINO_ARCH_ESP8266)
+	//
+#else
+#	error "Architecture unknown and not supported"
+#endif
+
+
 // The followion file contains most of the definitions
 // used in other files. It should be the first file.
 #include "configGway.h"										// contains the configuration data of GWay
@@ -63,27 +73,26 @@ extern "C" {
 #endif
 
 // ----------- Specific ESP32 stuff --------------
-#if defined (ARDUINO_ARCH_ESP32) || defined(ESP32)
-#	define ESP32_ARCH 1
+#if defined(ESP32_ARCH)
+#	include <WiFi.h>										// MMM added 20Feb
 #	include <ESPmDNS.h>
 #	include <SPIFFS.h>
 
-#	if _WIFIMANAGER==1
-#		define ESP_getChipId()   ((uint32_t)ESP.getEfuseMac())
-#		include <ESP_WiFiManager.h>							// Library for ESP WiFi config through an AP
-#	endif //_WIFIMANAGER
-
 #	if A_SERVER==1
-#		include <ESP32WebServer.h>							// Dedicated Webserver for ESP32
+#		include <WebServer.h>								// Standard Webserver for ESP32
 #		include <Streaming.h>          						// http://arduiniana.org/libraries/streaming/
-		ESP32WebServer server(A_SERVERPORT);
+		WebServer server(A_SERVERPORT); // MMM added 20Feb
 #	endif //A_SERVER
 
 #	if A_OTA==1
-#		include <ESP32httpUpdate.h>							// Not yet available
+//#		include <ESP32httpUpdate.h>							// Not yet available
 #		include <ArduinoOTA.h>
 #	endif //A_OTA
 
+#	if _WIFIMANAGER==1
+#		define ESP_getChipId()   ((uint32_t)ESP.getEfuseMac())
+#		include <WiFiManager.h>								// Standard lib for ESP WiFi config through an AP
+#	endif //_WIFIMANAGER
 
 // ----------- Specific ESP8266 stuff --------------
 #elif defined(ARDUINO_ARCH_ESP8266)
@@ -97,7 +106,7 @@ extern "C" {
 #	if A_SERVER==1
 #		include <ESP8266WebServer.h>
 #		include <Streaming.h>          						// http://arduiniana.org/libraries/streaming/
-		ESP8266WebServer server(A_SERVERPORT);
+		ESP8266WebServer server(A_SERVERPORT);				// Standard IDE lib
 #	endif //A_SERVER
 
 #	if A_OTA==1
@@ -106,7 +115,7 @@ extern "C" {
 #	endif //A_OTA
 
 #	if _WIFIMANAGER==1						
-#		include <ESP_WiFiManager.h>							// Library for ESP WiFi config through an AP
+#		include <WiFiManager.h>								// Library for ESP WiFi config through an AP
 #		define ESP_getChipId()   (ESP.getChipId())
 #	endif //_WIFIMANAGER
 
@@ -229,6 +238,7 @@ int readGwayCfg(const char *fn, struct espGwayConfig *c);				// _loraFiles.ino
 void init_oLED();														// _oLED.ino
 void acti_oLED();														// _oLED.ino
 void addr_oLED();														// _oLED.ino
+void msg_oLED(String mesg);												// _oLED.ino
 
 void setupOta(char *hostname);											// _otaServer.ino
 

+ 37 - 11
src/_WiFi.ino

@@ -123,9 +123,9 @@ int WlanStatus() {
 // ----------------------------------------------------------------------------
 int wifiMgr() 
 {
-
 #if _WIFIMANAGER==1
-	ESP_WiFiManager ESP_wifiManager;
+
+	WiFiManager wifiManager;
 	
 #	if _MONITOR>=1
 	if (debug>=1) {
@@ -139,9 +139,20 @@ int wifiMgr()
 	char s [ssid.length() + 1];
 	strncpy(s, ssid.c_str(), ssid.length());
 	s[ssid.length()]= 0;
-	ESP_wifiManager.setConfigPortalTimeout(120);
-	ESP_wifiManager.startConfigPortal(s, AP_PASSWD );
-		
+
+	wifiManager.setDebugOutput(false);
+	wifiManager.setConfigPortalTimeout(120);
+	wifiManager.startConfigPortal(s, AP_PASSWD );
+	wifiManager.setAPCallback(configModeCallback);
+
+	if (!wifiManager.autoConnect()) {
+#		if _MONITOR>=1
+			Serial.println("wifiMgr:: failed to connect and hit timeout");
+#		endif
+		ESP.restart();
+		delay(1000);
+	}
+
 #	if _MONITOR>=1
 	if ((debug>=1) && (pdebug & P_MAIN)) {
 		mPrint("WlanConnect:: Now starting WlanStatus");
@@ -152,24 +163,39 @@ int wifiMgr()
 			case 0: mPrint("WlanConnect:: WlanStatus Disconnected"); break;
 			default: mPrint("WlatConnect:: WlanStatus other");
 		}
-			}
+	}
 #	endif //_MONITOR 
 
 	// At this point, there IS a Wifi Access Point found and connected
 	// We must connect to the local SPIFFS storage to store the access point
 	//String s = WiFi.SSID();
 
-#	if defined(ESP32_ARCH)
-		//
-#	else		
+#	if defined(ARDUINO_ARCH_ESP8266)
 		// Now look for the password
 		struct station_config sta_conf;
 		wifi_station_get_config(&sta_conf);
-#	endif //ESP32_ARCH
+#	else
+		mPrint("wifiMgr:: define arch specific");
+#	endif
+
 #endif //_WIFIMANAGER
 	return 1;
 }
 
+// ----------------------------------------------------------------------------
+// Callback Function for MiFiManager
+// ----------------------------------------------------------------------------
+//gets called when WiFiManager enters configuration mode
+#if _WIFIMANAGER==1
+
+void configModeCallback (WiFiManager *myWiFiManager) 
+{
+  Serial.println("Entered config mode");
+  Serial.println(WiFi.softAPIP());
+  //if you used auto generated SSID, print it
+  Serial.println(myWiFiManager->getConfigPortalSSID());
+}
+#endif //_WIFIMANAGER
 
 // ----------------------------------------------------------------------------
 // Function to join the Wifi Network (as defined in sta array
@@ -254,7 +280,7 @@ int WlanConnect(int maxTry) {
 			// We increase the time for connect but try the same SSID
 			// We try for several times
 			agains=1;
-			while (((WiFi.status()) != WL_CONNECTED) && (agains < 8)) {
+			while ((WiFi.status() != WL_CONNECTED) && (agains < 8)) {
 				agains++;		
 				delay(8000);											//delay(agains*500);
 #				if _MONITOR>=1

+ 3 - 3
src/_loraFiles.ino

@@ -19,7 +19,7 @@
 #if _MONITOR>=1
 // ----------------------------------------------------------------------------
 // LoRa Monitor logging code.
-// Define one print function and depending on the loggin parameter output
+// Define one print function and depending on the logging parameter output
 // to _USB of to the www screen function
 // ----------------------------------------------------------------------------
 int initMonitor(struct moniLine *monitor) 
@@ -587,7 +587,7 @@ int writeSeen(const char *fn, struct nodeSeen *listSeen)
 	int i;
 	if (!SPIFFS.exists(fn)) {
 #		if _MONITOR>=1
-			mPrint("WARNING:: writeSeen, file not exists, initSeen");
+			mPrint("WARNING:: writeSeen, file not exists="+String(fn));
 #		endif //_MONITOR
 		//initSeen(listSeen);		// XXX make all initial declarations here if config vars need to have a value
 	}
@@ -595,7 +595,7 @@ int writeSeen(const char *fn, struct nodeSeen *listSeen)
 	File f = SPIFFS.open(fn, "w");
 	if (!f) {
 #		if _MONITOR>=1
-			mPrint("writeConfig:: ERROR open file="+String(fn));
+			mPrint("writeSeen:: ERROR open file="+String(fn)+" for writing");
 #		endif //_MONITOR
 		return(-1);
 	}

+ 15 - 11
src/_oLED.ino

@@ -18,7 +18,7 @@
 // ========================================================================================
 //
 
-#if OLED>=1
+
 
 
 // --------------------------------------------------------------------	
@@ -28,6 +28,7 @@
 // --------------------------------------------------------------------
 void init_oLED() 
 {
+#if OLED>=1
 #if defined OLED_RST
 	pinMode(OLED_RST,OUTPUT);
 	digitalWrite(OLED_RST, LOW); 	// low to reset OLED
@@ -35,6 +36,7 @@ void init_oLED()
 	digitalWrite(OLED_RST, HIGH); 	// must be high to turn on OLED
 	delay(50);
 #else
+	//
 #endif
 	// Initialising the UI will init the display too.
 	display.init();
@@ -45,6 +47,7 @@ void init_oLED()
 	display.setTextAlignment(TEXT_ALIGN_LEFT);
 	display.drawString(0, 24, "STARTING");
 	display.display();
+#endif
 }
 
 // --------------------------------------------------------------------
@@ -55,25 +58,26 @@ void init_oLED()
 // --------------------------------------------------------------------
 void acti_oLED() 
 {
-#	if OLED>=1
+#if OLED>=1
 	// Initialising the UI will init the display too.
 	display.clear();
 	
-#if OLED==1
+# if OLED==1
 	display.setFont(ArialMT_Plain_16);
 	display.drawString(0, 0, "READY,  SSID=");
 	display.drawString(0, 16, WiFi.SSID());
 	display.drawString(0, 32, "IP=");
 	display.drawString(0, 48, WiFi.localIP().toString().c_str() );
-#elif OLED==2
+# elif OLED==2
 	display.setFont(ArialMT_Plain_16);
 	display.drawString(0, 0, "READY,  SSID=");
 	display.drawString(0, 16, WiFi.SSID());
 	display.drawString(0, 32, "IP=");
 	display.drawString(0, 48, WiFi.localIP().toString().c_str() );
-#endif
+# endif
 
 	display.display();
+	
 #endif // OLED
 	delay(4000);
 }
@@ -122,10 +126,10 @@ void msg_lLED(String mesg, String mesg2)
 // --------------------------------------------------------------------
 void addr_oLED() 
 {
-#if _DUSB>=1
-	Serial.print(F("OLED_ADDR=0x"));
-	Serial.println(OLED_ADDR, HEX);
-#endif //_DUSB
+#if OLED>=1
+	#if _DUSB>=1
+		Serial.print(F("OLED_ADDR=0x"));
+		Serial.println(OLED_ADDR, HEX);
+	#endif //_DUSB
+#endif
 }
-
-#endif

+ 1 - 0
src/_txRx.ino

@@ -348,6 +348,7 @@ int buildPacket(uint32_t tmst, uint8_t *buff_up, struct LoraUp LoraUp, bool inte
 		}
 	}
 #	endif //DUSB
+
 	statr[0].node = ( message[1]<<24 | message[2]<<16 | message[3]<<8 | message[4] );
 
 #if _STATISTICS >= 2

+ 14 - 21
src/_udpSemtech.ino

@@ -180,7 +180,7 @@ int readUdp(int packetSize)
 	
 		case PKT_PULL_DATA:	// 0x02 UP
 #			if _MONITOR>=1
-				mPrint(" Pull Data");
+				mPrint("readUdp:: PKT_PULL_DATA");
 #			endif //_MONITOR
 		break;
 	
@@ -201,7 +201,7 @@ int readUdp(int packetSize)
 			if (sendPacket(data, packetSize-4) < 0) {
 #				if _MONITOR>=1
 				if ( debug>=0 ) {
-					mPrint("A readUdp:: ERROR: PKT_PULL_RESP sendPacket failed");
+					mPrint("readUdp:: ERROR: PKT_PULL_RESP sendPacket failed");
 				}
 #				endif //_MONITOR
 				return(-1);
@@ -222,57 +222,50 @@ int readUdp(int packetSize)
 			buff[11]=MAC_array[5];
 			buff[12]=0;
 #			if _MONITOR>=1
-			if (( debug >= 2 ) && ( pdebug & P_MAIN )) {
-				mPrint("M readUdp:: TX buff filled");
+			if (( debug >= 2 ) && ( pdebug & P_TX )) {
+				mPrint("readUdp:: TX buff filled and ready");
 			}
 #			endif //_MONITOR
+
 			// Only send the PKT_PULL_ACK to the UDP socket that just sent the data!!!
 			Udp.beginPacket(remoteIpNo, remotePortNo);
 			if (Udp.write((unsigned char *)buff, 12) != 12) {
 #				if _MONITOR>=1
-				if ((debug>=0) && (pdebug & P_RADIO)) {
-					mPrint("A readUdp:: ERROR: PKT_PULL_ACK UDP write");
+				if (debug>=0) {
+					mPrint("readUdp:: ERROR: PKT_PULL_ACK UDP write");
 				}
 #				endif //_MONITOR
 			}
 			else {
 #				if _MONITOR>=1
 				if (( debug>=0 ) && ( pdebug & P_TX )) {
-					mPrint("M PKT_TX_ACK:: micros="+String(micros()));
+					mPrint("readUdp:: PKT_TX_ACK:: micros="+String(micros()));
 				}
 #				endif //_MONITOR
 			}
 
 			if (!Udp.endPacket()) {
 #				if _MONITOR>=1
-				if (( debug>=0 ) && ( pdebug & P_RADIO )) {
-					mPrint("M PKT_PULL_DATALL ERROR Udp.endPacket");
+				if (( debug>=0 ) && ( pdebug & P_TX )) {
+					mPrint("readUdp:: PKT_PULL_DATALL ERROR Udp.endPacket");
 				}
 #				endif //_MONITOR
 			}
 			
 			yield();
 #			if _MONITOR>=1
-			if (( debug >=1 ) && (pdebug & P_MAIN )) {
-				Serial.print(F("M PKT_PULL_RESP:: size ")); 
-				Serial.print(packetSize);
-				Serial.print(F(" From ")); 
-				Serial.print(remoteIpNo);
-				Serial.print(F(", port ")); 
-				Serial.print(remotePortNo);	
-				Serial.print(F(", data: "));
+			if (( debug>=1 ) && (pdebug & P_TX )) {
 				data = buff_down + 4;
 				data[packetSize] = 0;
-				Serial.print((char *)data);
-				Serial.println(F("..."));
+				mPrint("readUdp:: PKT_PULL_RESP:: size="+String(packetSize)+" From "+String(remoteIpNo.toString())+":"+String(remotePortNo)+", data="+String((char *)data)); 
 			}
 #			endif //_MONITOR	
 		break;
 	
 		case PKT_PULL_ACK:	// 0x04 DOWN; the server sends a PULL_ACK to confirm PULL_DATA receipt
 #			if _MONITOR>=1
-			if (( debug >= 2 ) && (pdebug & P_MAIN )) {
-				Serial.print(F("M PKT_PULL_ACK:: size ")); Serial.print(packetSize);
+			if (( debug >= 2 ) && (pdebug & P_TX )) {
+				Serial.print(F("readUdp:: PKT_PULL_ACK: size=")); Serial.print(packetSize);
 				Serial.print(F(" From ")); Serial.print(remoteIpNo);
 				Serial.print(F(", port ")); Serial.print(remotePortNo);	
 				Serial.print(F(", data: "));

+ 16 - 8
src/_wwwServer.ino

@@ -88,9 +88,6 @@ boolean YesNo()
 	response += "</script>";
 	server.sendContent(response);
 	
-// Put something like this in the ESP program
-//	response += "<input type=\"button\" value=\"YesNo\" onclick=\"ynDialog()\" />";
-	
 	return(ret);
 }
 
@@ -347,9 +344,19 @@ static void setVariables(const char *cmd, const char *arg) {
 	// WiFi Manager
 	//
 #if _WIFIMANAGER==1
-	if (strcmp(cmd, "NEWSSID")==0) { 
-		ESP_WiFiManager ESP_wifiManager;
-		WiFi.disconnect();
+	if (strcmp(cmd, "NEWSSID")==0) {
+	
+		//and goes into a blocking loop awaiting configuration
+		WiFiManager wifiManager;
+#		if _MONITOR>=1		
+		if (!wifiManager.autoConnect()) {
+			Serial.println("failed to connect and hit timeout");
+			ESP.restart();
+			delay(1000);
+		}
+#		endif
+		
+		//WiFi.disconnect();
 		
 		// Add the ID to the SSID of the WiFiManager
 		String ssid = String(AP_NAME) + "-" + String(ESP_getChipId(), HEX);
@@ -359,7 +366,8 @@ static void setVariables(const char *cmd, const char *arg) {
 			mPrint("Set Variables:: ssid="+ ssid );
 		}
 #		endif //_MONITOR
-		ESP_wifiManager.startConfigPortal( ssid.c_str(), AP_PASSWD );
+
+		// wifiManager.startConfigPortal( ssid.c_str(), AP_PASSWD );		// MMM added 23Feb
 	}
 #endif //_WIFIMANAGER
 
@@ -1162,7 +1170,7 @@ static void systemStatus()
 	
 
 		response +="<tr><td class=\"cell\">Free heap</td><td class=\"cell\">"; response+=ESP.getFreeHeap(); response+="</tr>";
-// XXX We Shoudl find an ESP32 alternative
+// XXX We Should find an ESP32 alternative
 #if !defined ESP32_ARCH
 		response +="<tr><td class=\"cell\">ESP speed</td><td class=\"cell\">"; response+=ESP.getCpuFreqMHz(); 
 		response +="<td style=\"border: 1px solid black; width:40px;\"><a href=\"SPEED=80\"><button>80</button></a></td>";

+ 30 - 16
src/configGway.h

@@ -1,12 +1,9 @@
 // 1-channel LoRa Gateway for ESP32 and ESP8266
 // Copyright (c) Maarten Westenberg 2016-2020 
 
-// Specify the correct version and date of your gateway here.
-// Normally it is provided with the GitHub version
-#define VERSION "V.6.2.1.E.EU868 PlatformIO; 200129c"
+#define VERSION "V.6.2.3.E.EU868; PlatformIO 200223a"
 //
 // Based on work done by Thomas Telkamp for Raspberry PI 1ch gateway and many others.
-// Contibutions of Dorijan Morelj and Andreas Spies for OLED support.
 //
 // All rights reserved. This program and the accompanying materials
 // are made available under the terms of the MIT License
@@ -29,6 +26,10 @@
 // the right _PIN_OUT below. Selecting OLED while that is not connected does not 
 // really matter (so you can leave that in).
 //
+// The source has been optimized for PlatformIO usage. Than means the some variables
+// can be define in the .platformio.ini file. Pleas look at the example file to see 
+// how to set these #defines
+//
 // ========================================================================================
 
 
@@ -36,18 +37,24 @@
 // This is usually a good idea if the webserver is interrupted halfway a writing
 // operation. Also to be used when software is upgraded
 // Normally, value 0 is a good default and should not be changed.
-#define _SPIFFS_FORMAT 0
+#if !defined _SPIFFS_FORMAT
+#	define _SPIFFS_FORMAT 0
+#endif
 
 
-// Allows configuration through WifiManager AP setup. Must be 0 or 1					
-#define _WIFIMANAGER 0
+// Allows configuration through WifiManager AP setup. Must be 0 or 1	
+#if !defined _WIFIMANAGER				
+#	define _WIFIMANAGER 0
+#endif
 
 
 // Debug message will be put on Serial is this one is set.
 // If set to 0, no printing to USB devices is done.
 // Set to 1 it will print all user level messages (with correct debug set)
 // If set to 2 it will also print interrupt messages (not recommended)
-#define _DUSB 1
+#if !defined _DUSB
+#	define _DUSB 1
+#endif
 
 
 // Define the monitor screen. When it is greater than 0 then logging is displayed in
@@ -143,7 +150,9 @@
 //	3: ESP32, Wemos pin out (Not used)
 //	4: ESP32, Heltec and TTGO pin out (should work for Heltec, 433 and OLED too).
 //	5: Other, define your own in loraModem.h (does not include GPS Code)
-#define _PIN_OUT 4
+#if !defined _PIN_OUT
+#	define _PIN_OUT 1
+#endif
 
 
 // Single channel gateways if they behave strict should only use one frequency 
@@ -157,6 +166,8 @@
 //		in order to receive downlink messages. This is the default mode.
 // NOTE: In all other cases, value 0 works for most gateways with CAD enabled
 #define _STRICT_1CH 1
+
+
 //
 // Also, normally the server will respond with SF12 in the RX2 timeslot.
 // For TTN, thr RX2 timeslot is SF9, and we should use that one for TTN
@@ -175,12 +186,14 @@
 
 
 // Define if OLED Display is connected to I2C bus. Note that defining an OLED display does not
-// impact performance very much, certainly if no OLED is connected. Wrong OLED will not show
-// sensible results on display
+// impact performance negatively, certainly if no OLED is connected. Wrong OLED will not show
+// sensible results on the OLED display
 // OLED==0; No OLED display connected
-// OLED==1; 0.9 Oled Screen based on SSD1306
-// OLED==2;	1"3 Oled screens for Wemos, 128x64 SH1106
-#define OLED 1
+// OLED==1; 0.9" Oled Screen based on SSD1306
+// OLED==2;	1.3" Oled screens for Wemos, 128x64 SH1106
+#if !defined OLED
+#	define OLED 1
+#endif
 
 
 // Define whether we want to manage the gateway over UDP (next to management 
@@ -215,7 +228,6 @@
 #define _WWW_INTERVAL	60					// Number of seconds before we refresh the WWW page
 
 
-
 // This defines whether or not we would use the gateway as 
 // as sort of backend decoding system for local sensors which decodes
 // 1: _LOCALSERVER is used
@@ -231,6 +243,7 @@
 #define _LON 5.978654
 #define _ALT 14								// Altitude
 
+
 // ntp
 // Please add daylight saving time to NTP_TIMEZONES when desired
 #define NTP_TIMESERVER "nl.pool.ntp.org"	// Country and region specific
@@ -268,14 +281,15 @@
 // configurations on configNode.h are not large enough for example.
 // ========================================================================
 
-
 // Maximum number of Message History statistics records gathered. 20 is a good maximum 
 // (memory intensive). For ESP32 maybe 30 could be used as well
 #define _MAXSTAT 20
 
+
 // Define the maximum amount of itemas we monitor on the screen
 #define _MAXMONITOR 20
 
+
 // We will log a list of LoRa nodes that was forwarded using this gateway.
 // For eacht node we record:
 //	- node Number, or known node name