From 8e324926f97b260b4a24b5ecee9488f0817e5485 Mon Sep 17 00:00:00 2001 From: kavers1 Date: Mon, 6 May 2019 21:20:39 +0200 Subject: [PATCH 1/9] Multi access point functionality Added functionality so that it will connect to multiple stored access points. Starting with the last used and then scanning for access points and selecting the known ones with the highest RSSI --- .gitignore | 5 +- PersWiFiManager.cpp | 532 ++++++++++++++++++++++++++++++++--- PersWiFiManager.h | 41 ++- data/wifimulti.html | 41 +++ data/wifimulti.min.html | 2 + simple_json_non_blocking.ino | 525 ++++++++++++++++++++++++++++++++++ 6 files changed, 1102 insertions(+), 44 deletions(-) create mode 100644 data/wifimulti.html create mode 100644 data/wifimulti.min.html create mode 100644 simple_json_non_blocking.ino diff --git a/.gitignore b/.gitignore index 1065d7c..aa63b39 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ PersWiFiManager.ino data/* -!data/wifi* \ No newline at end of file +!data/wifi* +.pioenvs/* +.vscode/* +platformio.ini diff --git a/PersWiFiManager.cpp b/PersWiFiManager.cpp index adfd641..c97465e 100644 --- a/PersWiFiManager.cpp +++ b/PersWiFiManager.cpp @@ -8,6 +8,10 @@ #ifdef WIFI_HTM_PROGMEM const char wifi_htm[] PROGMEM = R"=====(ESP WiFi







Back |Home
)====="; #endif +#ifdef WIFI_HTM2_PROGMEM +const char wifi_htm[] PROGMEM = R"=====( ESP WiFi









Back | Home
)====="; +#endif + #ifdef WIFI_HTM_GZ_PROGMEM #define wifi_htm_gz_len 1103 static const uint8_t wifi_htm_gz[] PROGMEM = { @@ -105,21 +109,141 @@ static const uint8_t wifi_htm_gz[] PROGMEM = { 0xaf, 0xfc, 0x04, 0x35, 0x76, 0x39, 0x90, 0x7c, 0x07, 0x00, 0x00 }; #endif +#ifdef WIFI_HTM2_GZ_PROGMEM +#define wifi_htm_gz_len 1273 +static const uint8_t wifi_htm_gz[] PROGMEM = { +0x1f, 0x8b, 0x08, 0x00, 0x5d, 0x94, 0xaf, 0x5c, 0x00, 0xff, 0x9d, 0x56, +0x6d, 0x73, 0xd3, 0x38, 0x10, 0xfe, 0x7e, 0xbf, 0xc2, 0x98, 0x81, 0xd8, +0x83, 0xe3, 0xbc, 0x14, 0xb8, 0x3b, 0x3b, 0x32, 0x53, 0x68, 0xef, 0xda, +0x19, 0xb8, 0x61, 0x12, 0x66, 0xae, 0x33, 0xa5, 0x1f, 0x14, 0x7b, 0x9d, +0x08, 0x14, 0xc9, 0x48, 0x72, 0x4c, 0x2e, 0xe7, 0xff, 0xce, 0xca, 0x8e, +0xd3, 0x94, 0xb4, 0xdc, 0x1c, 0x1f, 0x9c, 0xac, 0xac, 0x7d, 0x7b, 0x76, +0x9f, 0x95, 0x35, 0x79, 0x94, 0xc9, 0xd4, 0x6c, 0x0a, 0x58, 0x9a, 0x15, +0x4f, 0x26, 0x2b, 0x30, 0xd4, 0x49, 0xa5, 0x30, 0x20, 0x0c, 0x71, 0x2b, +0x96, 0x99, 0x25, 0xc9, 0x60, 0xcd, 0x52, 0xe8, 0x37, 0x8b, 0x80, 0x09, +0x66, 0x18, 0xe5, 0x7d, 0x9d, 0x52, 0x0e, 0x64, 0x14, 0x94, 0x1a, 0x54, +0xb3, 0xa0, 0x73, 0x5c, 0x0b, 0xe9, 0x0a, 0xba, 0x02, 0xb2, 0x66, 0x50, +0x15, 0x52, 0x99, 0x64, 0x62, 0x98, 0xe1, 0x90, 0x9c, 0xcf, 0xde, 0x3b, +0x7f, 0xb3, 0x3f, 0xd8, 0x64, 0xd0, 0xae, 0x27, 0x3a, 0x55, 0xac, 0x30, +0x49, 0x5e, 0x8a, 0xd4, 0x30, 0x29, 0x9c, 0x85, 0xc7, 0xfc, 0xad, 0x02, +0x53, 0x2a, 0xe1, 0x60, 0x42, 0xe5, 0x0a, 0xe3, 0x87, 0x0b, 0x30, 0xe7, +0x1c, 0xac, 0xf8, 0x7a, 0x73, 0x99, 0xa1, 0x46, 0x1d, 0xef, 0x0d, 0x0a, +0xcf, 0x04, 0xdc, 0xdf, 0xb2, 0xdc, 0xc3, 0x6c, 0x73, 0xa6, 0x56, 0x9e, +0xf1, 0xfd, 0x8a, 0x89, 0x4c, 0x56, 0x21, 0x97, 0x29, 0xb5, 0x4a, 0x84, +0x1f, 0x18, 0x9c, 0x7b, 0xfa, 0x38, 0x42, 0xaa, 0x80, 0x1a, 0xd8, 0x05, +0x41, 0x85, 0x3a, 0x5e, 0x53, 0xe5, 0xcc, 0x88, 0xab, 0xc1, 0x9c, 0x1a, +0xa3, 0xd8, 0xbc, 0x34, 0xe0, 0x06, 0xa7, 0xc4, 0xa5, 0x45, 0x01, 0x22, +0x7b, 0xb3, 0x64, 0x3c, 0x73, 0x83, 0x0b, 0xe2, 0x32, 0x21, 0x40, 0x5d, +0x7c, 0x78, 0xf7, 0xd6, 0x0d, 0xae, 0x82, 0x8a, 0x07, 0xd3, 0x80, 0xf2, +0xdb, 0x60, 0x58, 0x10, 0xe1, 0x35, 0xd9, 0x5d, 0xf9, 0x6d, 0xcc, 0xf8, +0x8a, 0x08, 0xa8, 0x9c, 0xab, 0x77, 0x6f, 0x2f, 0x8c, 0x29, 0xa6, 0xf0, +0xa5, 0x04, 0x6d, 0x3c, 0x1f, 0x4d, 0xc9, 0x43, 0x78, 0x7b, 0x15, 0xef, +0xf9, 0x71, 0xc5, 0xaf, 0x2f, 0x6e, 0x88, 0x3b, 0x43, 0x8f, 0x82, 0x89, +0x45, 0x18, 0x86, 0x6e, 0x7c, 0x15, 0x4a, 0x81, 0x99, 0x67, 0x1b, 0x6d, +0x30, 0xfd, 0x74, 0x49, 0xc5, 0x02, 0x48, 0x17, 0xbc, 0x8d, 0x6b, 0x96, +0x4c, 0x87, 0x8d, 0xce, 0xcc, 0xea, 0x10, 0xf2, 0xfc, 0xf6, 0xb5, 0xb5, +0x2a, 0x35, 0x21, 0xe3, 0xe1, 0xd0, 0xdf, 0x5e, 0x91, 0x61, 0x17, 0xc3, +0x8d, 0x77, 0x56, 0xba, 0x90, 0x42, 0xc3, 0x07, 0xf8, 0x6a, 0x42, 0x5d, +0x70, 0x66, 0xbc, 0xde, 0x47, 0xd1, 0xf3, 0xc3, 0x5c, 0xaa, 0x73, 0x9a, +0x2e, 0xbd, 0x7d, 0x24, 0xf0, 0xb7, 0x1c, 0x8c, 0x63, 0x08, 0x74, 0x7a, +0x41, 0xcf, 0x0f, 0x34, 0x41, 0x33, 0x8e, 0x94, 0xf1, 0xc6, 0x7e, 0xf8, +0x49, 0x32, 0xd1, 0xbc, 0x6e, 0x2a, 0x9b, 0x91, 0x73, 0xaf, 0x97, 0xb1, +0x35, 0x6a, 0x31, 0x2b, 0x52, 0x14, 0xd2, 0x9d, 0x10, 0xb3, 0xeb, 0xd9, +0x8d, 0xd7, 0x4b, 0x39, 0xd5, 0x1a, 0x0d, 0x34, 0xbe, 0x49, 0xef, 0xbc, +0xf9, 0x62, 0x75, 0x10, 0x79, 0x8a, 0xbe, 0x3f, 0x1f, 0xc2, 0x5d, 0x78, +0x56, 0x3b, 0x5c, 0x53, 0x5e, 0x02, 0xd1, 0x31, 0x2e, 0x8b, 0x26, 0xdb, +0xb4, 0xd4, 0x1e, 0xb6, 0x94, 0x5d, 0x9f, 0xde, 0x78, 0xdf, 0xb5, 0xdc, +0x62, 0xfb, 0x4b, 0x66, 0x80, 0x3d, 0xb7, 0x61, 0x10, 0xbd, 0xb9, 0x1e, +0xde, 0x3c, 0x73, 0x9f, 0xb8, 0xcf, 0xbc, 0x82, 0x2a, 0x0d, 0x97, 0xc8, +0x07, 0x73, 0x3d, 0xba, 0xf1, 0x5f, 0xb9, 0x1f, 0xcb, 0xb3, 0xdf, 0x4e, +0xce, 0xf0, 0xf7, 0x6c, 0x34, 0x76, 0x23, 0x5c, 0x8e, 0x5f, 0x9e, 0x0e, +0xdd, 0xa6, 0x33, 0xe8, 0x98, 0x75, 0x42, 0xda, 0x09, 0x0f, 0xb0, 0xab, +0x37, 0x57, 0x3d, 0xdf, 0xaf, 0xfd, 0xfa, 0x17, 0xe0, 0x1a, 0x9c, 0xe3, +0x66, 0x8c, 0x0f, 0x9b, 0x71, 0xd4, 0x89, 0x18, 0x29, 0x89, 0x49, 0x81, +0x42, 0x98, 0x5e, 0xcb, 0xaf, 0xe0, 0x64, 0x88, 0x1d, 0xac, 0xeb, 0xda, +0x12, 0x02, 0xe9, 0xe9, 0xb9, 0x7f, 0x9e, 0x7f, 0x70, 0x03, 0x1c, 0xdb, +0x9c, 0x0d, 0x38, 0xd3, 0xc6, 0x0d, 0x1e, 0x0d, 0x7d, 0xdc, 0xd4, 0x48, +0x5d, 0x5b, 0x89, 0xdb, 0x71, 0x43, 0x7a, 0xbf, 0xc7, 0xe2, 0x58, 0x4a, +0x4c, 0x3b, 0x86, 0x4e, 0xef, 0x65, 0x68, 0x4c, 0x7f, 0xc0, 0x50, 0x6a, +0x19, 0x4a, 0x5b, 0xf6, 0x4c, 0x01, 0xe7, 0x05, 0x8f, 0x0a, 0xb1, 0x70, +0x4e, 0xd3, 0x14, 0xb4, 0x76, 0x0a, 0xec, 0xbd, 0xd1, 0x0d, 0x63, 0xa7, +0x3f, 0xc3, 0xd8, 0xa7, 0x4f, 0x8f, 0xe9, 0xfa, 0x50, 0x2a, 0x2e, 0x73, +0x7d, 0xd4, 0xdc, 0x70, 0x08, 0x33, 0x86, 0x64, 0xa4, 0x1b, 0xe2, 0xce, +0xf1, 0x20, 0xf8, 0xec, 0xc6, 0x0f, 0x9a, 0x60, 0x81, 0xfe, 0xb7, 0x0d, +0x3d, 0x36, 0x11, 0x52, 0x00, 0x22, 0xc4, 0xd6, 0xed, 0x2a, 0xf1, 0x33, +0x73, 0xf4, 0xdd, 0x74, 0xec, 0x87, 0xe2, 0xee, 0x08, 0x34, 0x43, 0xf1, +0xc0, 0x08, 0xb0, 0xfd, 0x08, 0x40, 0x8d, 0x66, 0x3f, 0xe0, 0x3c, 0x20, +0xe7, 0x31, 0xd5, 0x96, 0xb3, 0xad, 0xf0, 0x5f, 0x9c, 0xad, 0x6d, 0x07, +0x2d, 0xc5, 0x7a, 0x48, 0x31, 0x4c, 0xa4, 0xa1, 0x18, 0x2d, 0x7a, 0x0d, +0xc1, 0xa6, 0x1d, 0xc1, 0x26, 0x83, 0xdd, 0xb9, 0x3e, 0x69, 0x4a, 0x94, +0x5c, 0x8a, 0xa2, 0x34, 0xdb, 0x82, 0x66, 0x19, 0xb2, 0x22, 0x7a, 0x51, +0x7c, 0x8d, 0x73, 0xfc, 0xb4, 0xf4, 0x35, 0xfb, 0x07, 0xa2, 0x11, 0xac, +0xe2, 0xe6, 0x93, 0x12, 0xfd, 0xfe, 0xe2, 0x49, 0x3d, 0x97, 0xd9, 0x66, +0x6b, 0x30, 0xc1, 0x3e, 0xe5, 0x6c, 0x21, 0xa2, 0x14, 0xa3, 0x83, 0x6a, +0xd5, 0x73, 0xba, 0x62, 0x7c, 0x13, 0xad, 0x41, 0x65, 0x54, 0xd0, 0x78, +0x4e, 0xd3, 0xcf, 0x0b, 0x25, 0x4b, 0x91, 0xf5, 0x53, 0xc9, 0xa5, 0x8a, +0x1e, 0xe3, 0x14, 0xc4, 0x3b, 0x31, 0xcf, 0xf3, 0x9a, 0x6e, 0x77, 0x8b, +0x51, 0x4e, 0x4f, 0x20, 0xad, 0xf1, 0x0c, 0x37, 0x52, 0x6c, 0xe7, 0x52, +0x65, 0xa0, 0xa2, 0x61, 0xdc, 0x0a, 0x7d, 0x45, 0x33, 0x56, 0xea, 0x28, +0x3c, 0xc1, 0x44, 0x8e, 0x7d, 0xb6, 0xb6, 0x07, 0x6e, 0x63, 0xce, 0x04, +0xf4, 0x97, 0xc0, 0x16, 0x4b, 0x13, 0x8d, 0xc3, 0xe7, 0x68, 0x75, 0x00, +0x26, 0x1c, 0xef, 0xe1, 0x8c, 0x86, 0xc3, 0x27, 0xf1, 0x8e, 0x1c, 0x51, +0x43, 0xa7, 0x3a, 0xfc, 0xb2, 0xcd, 0xb9, 0xa4, 0x26, 0x52, 0xd6, 0xba, +0x0e, 0xf5, 0xb6, 0xdb, 0x67, 0xa2, 0x71, 0xdb, 0xa8, 0x75, 0xf6, 0xd6, +0xb5, 0x44, 0xb4, 0x68, 0x52, 0x45, 0x4b, 0x96, 0x65, 0x20, 0xe2, 0xa6, +0x34, 0xfb, 0x97, 0xc0, 0x39, 0x2b, 0x34, 0xd3, 0x71, 0xb5, 0x64, 0x06, +0xfa, 0xba, 0xa0, 0x29, 0x44, 0x42, 0x56, 0x8a, 0x16, 0xf5, 0xe3, 0x8a, +0x6f, 0x0f, 0x53, 0x1d, 0x85, 0x2f, 0x60, 0x65, 0x3b, 0xd3, 0x74, 0x64, +0x82, 0xf4, 0x72, 0x1a, 0x91, 0x1c, 0x54, 0x9b, 0x43, 0x6e, 0xf6, 0x29, +0xdf, 0x93, 0xd2, 0xc9, 0x78, 0x88, 0xbd, 0x3b, 0xe8, 0x63, 0x32, 0x69, +0x8b, 0xea, 0x74, 0x54, 0x6c, 0x0f, 0xa4, 0xc4, 0x7e, 0xa5, 0x26, 0x83, +0x76, 0x2f, 0x99, 0x14, 0x0e, 0xcb, 0x48, 0x85, 0xb7, 0x0a, 0x24, 0xfc, +0xca, 0xa1, 0x0d, 0x57, 0xc9, 0xa0, 0xa1, 0x0e, 0x7e, 0xb4, 0x05, 0xa4, +0xc6, 0xc1, 0xfb, 0xc6, 0x52, 0x66, 0xa4, 0x90, 0xda, 0xa0, 0x2f, 0x5d, +0xce, 0x57, 0xcc, 0x90, 0xee, 0x74, 0x4a, 0x26, 0xcc, 0x12, 0xc8, 0x7a, +0xd1, 0x0e, 0x07, 0xb1, 0xc0, 0xcb, 0xc8, 0xc9, 0xd8, 0x69, 0x6e, 0x18, +0x78, 0x03, 0xe0, 0x88, 0x7a, 0x29, 0x39, 0xf6, 0x92, 0xcc, 0x66, 0x97, +0x67, 0x98, 0x93, 0x3a, 0xb0, 0x28, 0x3a, 0x8b, 0x97, 0xcf, 0x5b, 0x8b, +0xe2, 0x8e, 0x45, 0x81, 0x03, 0x55, 0x21, 0x11, 0x1c, 0x7b, 0xf7, 0xd9, +0xaf, 0x5a, 0x1f, 0xcd, 0xd3, 0xe2, 0x6b, 0x76, 0xdb, 0xb4, 0x92, 0x37, +0x6d, 0xce, 0xb7, 0xf8, 0x06, 0x16, 0x57, 0xab, 0xde, 0x40, 0xa5, 0x08, +0x75, 0x50, 0x1c, 0xd5, 0xa6, 0x83, 0xd3, 0xa8, 0x24, 0x28, 0xde, 0x7a, +0x38, 0x2e, 0x8c, 0x36, 0x52, 0xc1, 0x61, 0x59, 0x0e, 0x20, 0xb1, 0x0e, +0xd2, 0xaf, 0x2d, 0x22, 0x76, 0x54, 0x83, 0xaf, 0xbb, 0xde, 0x76, 0xbd, +0xb4, 0x47, 0xd3, 0x1d, 0x3c, 0xb6, 0x94, 0xe6, 0x1e, 0xa5, 0x3b, 0x40, +0x67, 0x36, 0x87, 0x7b, 0x61, 0x1e, 0x78, 0xea, 0xd0, 0xf5, 0x0a, 0x0f, +0x8f, 0xfe, 0xb9, 0x94, 0xc6, 0x69, 0x2f, 0x8a, 0xaf, 0xf0, 0x0b, 0xd4, +0x62, 0x51, 0xf6, 0x80, 0xed, 0x25, 0xed, 0xee, 0xad, 0x3f, 0xeb, 0x84, +0x3a, 0x4b, 0x05, 0x39, 0xf9, 0x44, 0xd7, 0xb4, 0x3d, 0x32, 0x90, 0xe8, +0x16, 0xfa, 0x26, 0xb4, 0xa3, 0x88, 0xad, 0x7f, 0x8d, 0x7f, 0x93, 0x01, +0x4d, 0xfe, 0xed, 0x54, 0x07, 0x4e, 0x72, 0x21, 0x57, 0x98, 0x16, 0xc5, +0x8c, 0x90, 0xc5, 0xc9, 0x37, 0xad, 0x78, 0x3e, 0x86, 0xba, 0x0a, 0x00, +0x00 +}; +#endif PersWiFiManager::PersWiFiManager(AsyncWebServer &s, AsyncDNSServer &d, const fs::FS& fs):_fs(fs) { _aserver = &s; _adnsServer = &d; _apPass = ""; + _scanTime = 0; + _autoReconnect = true; } //PersWiFiManager +PersWiFiManager::~PersWiFiManager() { + APlistClean(); +} + bool PersWiFiManager::attemptConnection(const String &ssid, const String &pass) { //attempt to connect to wifi WiFi.mode(WIFI_STA); if (ssid.length()) { +#ifdef PERSWIFI_DEBUG if(Serial) Serial.printf("Connecting to SSID: %s\n", ssid.c_str()); +#endif if (pass.length()) WiFi.begin(ssid.c_str(), pass.c_str()); else @@ -127,11 +251,14 @@ bool PersWiFiManager::attemptConnection(const String &ssid, const String &pass) } else { +#ifdef PERSWIFI_DEBUG if(Serial) Serial.printf("Connecting to previously stored WiFi credentials.\n"); +#endif WiFi.begin(); } - + _connectStartTime = millis(); + _scanTime = 0; // mark a fresh connection attempt _tkWiFiH.attach_ms(10, std::bind(&PersWiFiManager::handleWiFi, this)); @@ -139,32 +266,176 @@ bool PersWiFiManager::attemptConnection(const String &ssid, const String &pass) } //attemptConnection +// unsigned long _reportTime; + void PersWiFiManager::handleWiFi() { - if (!_connectStartTime) - return; - - if (WiFi.status() == WL_CONNECTED) - { +// if (millis() > _reportTime + 1000){ +// _reportTime = millis(); +// if(Serial) { +// Serial.print(WiFi.status()); +// } +// } + + //if (!_connectStartTime) + // return; + switch (WiFi.status()) { + case WL_CONNECTED : + if (!_connectStartTime) + return; _connectStartTime = 0; + if (_scanTime) + WiFi.scanDelete(); // clean up the last scan + _scanTime = 0; + if (_autoReconnect && ! existsAP(WiFi.SSID().c_str(), WiFi.psk().c_str())) // store current succes for later retries + addAP(WiFi.SSID().c_str(), WiFi.psk().c_str()); if (_connectHandler) _connectHandler(); return; +#ifdef PERSWIFI_DEBUG if (Serial) { Serial.print("Router IP: "); - Serial.println(WiFi.localIP()); + Serial.print(WiFi.localIP()); + Serial.print(" On SSID: "); + Serial.println(WiFi.SSID()); + } +#endif + break; + case WL_DISCONNECTED : + // if trying to connect wait for time out + if ((_connectStartTime) && ((millis() - _connectStartTime) < (1000 * WIFI_CONNECT_TIMEOUT))){ + return; // still giving time to setup the connection + } + if (_disconnectHandler) + _disconnectHandler(); + // if disconnected after connection see if we have to reconnect + if (_autoReconnect ) { /// ??? is this correct +#ifdef PERSWIFI_DEBUG + if (Serial) + Serial.println(" Trying to reconnect to stored AP's "); +#endif + } + case WL_IDLE_STATUS: + if (!_autoReconnect) { + Serial.println(" no auto reconnect"); + _scanTime = 0; + _connectStartTime = 0; + return; + } + case WL_SCAN_COMPLETED : + case WL_NO_SSID_AVAIL : + case WL_CONNECT_FAILED : + case WL_CONNECTION_LOST : + // all these cases we try to connect to a stored AP + // check if the scan is done + // is no scan start --> start scanning and wait for completiong + // if scan is done sort by signal strength and try to connect to all of the available stored AP's + if (APlist.size() >0) { // do we have other AP to connect to ? + if ((_scanTime == 0) || (millis() - _scanTime > (1000 * WIFI_RETRY_TIME))){ // no scan started +#ifdef PERSWIFI_DEBUG + if (Serial){ + Serial.println("Scan networks for AP's"); + } +#endif + _scanTime = millis(); + WiFi.scanDelete(); + // for( auto entry : APlist ) + // does not allow me to set the ID to the scantime. no idea why + // so went for the old for loop + for(unsigned int i = 0; i < APlist.size(); i++){ + APlist.at(i).ID = _scanTime; + } +#ifdef PERSWIFI_DEBUG + if (Serial) + for( auto entry : APlist ){ + Serial.print(entry.ID);Serial.print(" ");Serial.println( entry.ssid); + } +#endif + WiFi.scanNetworks(true); + } + else + { + int n = WiFi.scanComplete(); + if (n == -1 ) { // not finished yet + return; + } + if (n != -2){ // scan done sort, filter and loop over results to try reconnecting +#ifdef PERSWIFI_DEBUG + Serial.print( "scan done "); Serial.print(n); Serial.print(" @time ");Serial.println(_scanTime); + for( auto entry : APlist ){ + Serial.print(entry.ID);Serial.print(" ");Serial.println( entry.ssid); + } +#endif + int ix[n+1]; + for (int i = 0; i < n+1; i++) + ix[i] = i; + //sort by signal strength + for (int i = 0; i < n; i++) + for (int j = 1; j < n - i; j++) + if (WiFi.RSSI(ix[j]) > WiFi.RSSI(ix[j - 1])) + std::swap(ix[j], ix[j - 1]); + //remove duplicates + for (int i = 0; i < n; i++){ + if (ix[i]>=0){ + for (int j = i + 1; j < n; j++){ + if ((ix[j] >= -1) && (WiFi.SSID(ix[i]).equals(WiFi.SSID(ix[j])) && WiFi.encryptionType(ix[i]) == WiFi.encryptionType(ix[j]))) + ix[j] = -1; + } + // check if SSID is in stored AP's and connect + for(unsigned int k = 0; k < APlist.size(); k++){ + if(APlist.at(k).ID == _scanTime) { +#ifdef PERSWIFI_DEBUG + Serial.print(i);Serial.print(" : "); + Serial.print ( " compare " ); Serial.print(WiFi.SSID(ix[i])); Serial.print(" <> "); Serial.println(APlist.at(k).ssid); +#endif + if (WiFi.SSID(ix[i]).equals(APlist.at(k).ssid)) { // SSID match + APlist.at(k).ID = 0; +#ifdef PERSWIFI_DEBUG + if (Serial){ + Serial.print("Try to connect to : "); + Serial.println(WiFi.SSID(ix[i])); + } +#endif + if (APlist.at(k).passphrase) + WiFi.begin(APlist.at(k).ssid, APlist.at(k).passphrase); + else + WiFi.begin(APlist.at(k).ssid); + _connectStartTime = millis(); // reset connect time out + return; + } + } + } + } + } + } +#ifdef PERSWIFI_DEBUG + Serial.println(""); + Serial.println(" Start AP mode"); +#endif + startApMode(); + _connectStartTime = 0; //reset connect start time + } + } + else // no additional AP's defined + { + startApMode(); + _connectStartTime = 0; //reset connect start time } - } - - //if failed or not connected and time is up - if ((WiFi.status() == WL_CONNECT_FAILED) || ((WiFi.status() != WL_CONNECTED) && ((millis() - _connectStartTime) > (1000 * WIFI_CONNECT_TIMEOUT)))) - { - startApMode(); - _connectStartTime = 0; //reset connect start time } } //handleWiFi +wl_status_t PersWiFiManager::GetStatus() +{ + wl_status_t status = WiFi.status(); + if (_connectStartTime == (unsigned long) 0) // if no attemp to connect return the real status + return status; + if (status == (wl_status_t) WL_CONNECTED) // if connected return connected + return status; + else // else report that we are still trying to connect whatever the status is + return WL_IDLE_STATUS; +} + void PersWiFiManager::startApMode() { //start AP mode @@ -172,48 +443,45 @@ void PersWiFiManager::startApMode() WiFi.mode(WIFI_AP); WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0)); _apPass.length() ? WiFi.softAP(getApSsid().c_str(), _apPass.c_str()) : WiFi.softAP(getApSsid().c_str()); +#ifdef PERSWIFI_DEBUG if(Serial) { Serial.print("Started AP mode, IP: "); Serial.println(WiFi.softAPIP()); Serial.println("--------------"); } +#endif if (_apHandler) _apHandler(); } //startApMode void PersWiFiManager::setConnectNonBlock(bool b) { - if(Serial) Serial.println("\n>>>>>>>>>>Does not do anything, non-blocking mode is default<<<<<<<<<<<<"); + DEBUG_WIFI_MULTI("\n>>>>>>>>>>Does not do anything, non-blocking mode is default<<<<<<<<<<<<"); _connectNonBlock = b; } //setConnectNonBlock void PersWiFiManager::setupWiFiHandlers() { - if (Serial) - { - Serial.println("\n\n---------------------------"); - Serial.println("Starting SPIFFs..."); - } + DEBUG_WIFI_MULTI("\n\n---------------------------"); + DEBUG_WIFI_MULTI("Starting SPIFFs..."); +#ifdef PERSWIFI_DEBUG if (_fs.begin()) { + Dir dir = _fs.openDir("/"); while (dir.next()) { String fileName = dir.fileName(); size_t fileSize = dir.fileSize(); - if (Serial) - Serial.printf("FS File: %s, size: %dB\n", fileName.c_str(), fileSize); + DEBUG_WIFI_MULTI("FS File: %s, size: %dB\n", fileName.c_str(), fileSize); } FSInfo fs_info; _fs.info(fs_info); - if (Serial) - { - Serial.printf("FS Usage: %d/%d bytes\n\n", fs_info.usedBytes, fs_info.totalBytes); - Serial.println("SPIFFs started"); - } + DEBUG_WIFI_MULTI("FS Usage: %d/%d bytes\n\nSPIFFs started\n", fs_info.usedBytes, fs_info.totalBytes); } +#endif IPAddress apIP(192, 168, 1, 1); _adnsServer->setErrorReplyCode(AsyncDNSReplyCode::NoError); @@ -221,15 +489,19 @@ void PersWiFiManager::setupWiFiHandlers() _aserver->on("/wifi/list", HTTP_GET, [](AsyncWebServerRequest *request) { //scan for wifi networks - String s = "Scan again after 3-5s"; + String s = "list"; s.reserve(2050); int n = WiFi.scanComplete(); - if (n == -2) + DEBUG_WIFI_MULTI("get list : %d\n",n); + if (n == -2) //WIFI_SCAN_FAILED (-2) { WiFi.scanNetworks(true); + request->send(202, "text/plain", "Scan updating. Refresh after 3-5s"); + DEBUG_WIFI_MULTI("Scanning networks refresh in 5 sec\n"); + return; } - else if (n) + else if (n) // n != -1 WIFI_SCAN_RUNNING (-1) { //build array of indices int ix[n]; @@ -262,28 +534,54 @@ void PersWiFiManager::setupWiFiHandlers() { WiFi.scanNetworks(true); } + if ( n > 0) { + DEBUG_WIFI_MULTI("Sending >>>>>>>>>>>>>\n%s\n<<<<<<<<<<<<<<<<<<<<<",s.c_str()); + request->send(200, "text/plain", s); + } + else + request->send(202, "text/plain", "Still scanning ..."); } - if (Serial) - { - Serial.print("Sending >>>>>>>>>>>>>\n"); - Serial.println(s); - Serial.println("<<<<<<<<<<<<<<<<<<<<<"); - } - - //send string to client - request->send(200, "text/plain", s); s = String(); }); //_aserver->on /wifi/list _aserver->on("/wifi/connect", HTTP_POST, [&](AsyncWebServerRequest *request) { - request->send(200, "text/html", " Connecting..."); + request->send(200, "text/html", " Connecting..."); if (request->hasArg("n") and request->hasArg("p")) attemptConnection(request->arg("n"), request->arg("p")); }); //_aserver->on /wifi/connect + _aserver->on("/wifi/store", HTTP_POST, [&](AsyncWebServerRequest *request) { + request->send(200, "text/html", " Store..."); + if (request->hasArg("i") ) { + if(request->arg("i")) { + DEBUG_WIFI_MULTI("remove store info for %s \n",request->arg("i").c_str()); + removeAP(WiFi.SSID().c_str()); + DEBUG_WIFI_MULTI("Store current connection for %s \n",WiFi.SSID().c_str()); + } + else + { + DEBUG_WIFI_MULTI("Add current connection for %s \n",WiFi.SSID().c_str()); + } + addAP(WiFi.SSID().c_str(),WiFi.psk().c_str()); + if (_storeHandler) // let outside world know there has been a change + _storeHandler(); + } + }); //_aserver->on /wifi/store + + _aserver->on("/wifi/ap", HTTP_GET, [&](AsyncWebServerRequest *request) { - request->send(200, "text/html", " Access point: " + getApSsid()); - startApMode(); + /// todo instead of config.json we have to return the APlist + String s = "list"; + s.reserve(APlist.size()*40); + s = ""; + for(auto entry : APlist) { + s += String(entry.ssid) + "\n"; + } + Serial.println(s); + request->send(200, "text/html", s); + //request->send(SPIFFS, "/config.json", "application/json",true); + DEBUG_WIFI_MULTI(" access point is : %s \n",getApSsid().c_str()); + //startApMode(); }); //_aserver->on /wifi/ap _aserver->on("/wifi/restart", HTTP_GET, [](AsyncWebServerRequest *request) { @@ -364,6 +662,20 @@ void PersWiFiManager::setupWiFiHandlers() }); #endif +#ifdef WIFI_HTM2_PROGMEM + _aserver->on("/wifi", HTTP_GET, [](AsyncWebServerRequest *request) { + request->send_P(200, "text/html", wifi_htm); + }); +#endif + +#ifdef WIFI_HTM2_GZ_PROGMEM + _aserver->on("/wifi", HTTP_GET, [](AsyncWebServerRequest *request) { + AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", wifi_htm_gz, wifi_htm_gz_len); + response->addHeader("Content-Encoding", "gzip"); + request->send(response); + }); +#endif + } //setupWiFiHandlers void PersWiFiManager::setFSCredentials(const String &http_user, const String &http_pass) @@ -398,7 +710,143 @@ void PersWiFiManager::onConnect(WiFiChangeHandlerFunction fn) _connectHandler = fn; } +void PersWiFiManager::onDisConnect(WiFiChangeHandlerFunction fn) +{ + _disconnectHandler = fn; +} + void PersWiFiManager::onAp(WiFiChangeHandlerFunction fn) { _apHandler = fn; +} + +void PersWiFiManager::onStore(WiFiChangeHandlerFunction fn) +{ + _storeHandler = fn; +} + + +persWifiAPlist PersWiFiManager::getAPlist(){ + return APlist; +} +bool PersWiFiManager::removeAP(const char* ssid) { + return APlistRemove(ssid); +} + +bool PersWiFiManager::addAP(const char* ssid, const char *passphrase) { + return APlistAdd(ssid, passphrase); +} + +bool PersWiFiManager::existsAP(const char* ssid, const char *passphrase) { + return APlistExists(ssid, passphrase); +} + +bool PersWiFiManager::APlistRemove(const char* ssid) { + int i = 0; + for(auto entry : APlist) { + if(!strcmp(entry.ssid, ssid)) { + APlist.erase(APlist.begin()+i); + DEBUG_WIFI_MULTI("[WIFI][APlistRemove] remove SSID: %s\n", ssid); + return true; + } + i++; + } + DEBUG_WIFI_MULTI("[WIFI][APlistRemove] SSID: %s not found\n", ssid); + return false; +} + +bool PersWiFiManager::APlistAdd(const char* ssid, const char *passphrase) { + + persWifiAPEntry newAP; + + if(!ssid || *ssid == 0x00 || strlen(ssid) > 32) { + // fail SSID too long or missing! + DEBUG_WIFI_MULTI("[WIFI][APlistAdd] no ssid or ssid too long\n"); + return false; + } + + //for passphrase, max is 63 ascii + null. For psk, 64hex + null. + if(passphrase && strlen(passphrase) > 64) { + // fail passphrase too long! + DEBUG_WIFI_MULTI("[WIFI][APlistAdd] passphrase too long\n"); + return false; + } + + if(APlistExists(ssid, NULL)) { //does SSID already exists ?? + DEBUG_WIFI_MULTI("[WIFI][APlistAdd] SSID: %s already exists\n", ssid); + if(APlistExists(ssid, passphrase)) { // and is the password identical + DEBUG_WIFI_MULTI("[WIFI][APlistAdd] SSID: %s already exists no updata needed\n", ssid); + return true; + } + else{ + for(auto entry : APlist) { + if(!strcmp(entry.ssid, ssid)) { // update the password + entry.passphrase = strdup(passphrase); + } + } + DEBUG_WIFI_MULTI("[WIFI][APlistAdd] SSID: %s updated password\n", ssid); + return true; + } + } + + newAP.ssid = strdup(ssid); + + if(!newAP.ssid) { + DEBUG_WIFI_MULTI("[WIFI][APlistAdd] fail newAP.ssid == 0\n"); + return false; + } + + if(passphrase) { + newAP.passphrase = strdup(passphrase); + } else { + newAP.passphrase = strdup(""); + } + + if(!newAP.passphrase) { + DEBUG_WIFI_MULTI("[WIFI][APlistAdd] fail newAP.passphrase == 0\n"); + free(newAP.ssid); + return false; + } + + newAP.ID = APlist.size(); + + APlist.push_back(newAP); + DEBUG_WIFI_MULTI("[WIFI][APlistAdd] add SSID: %s\n", newAP.ssid); + return true; +} + +bool PersWiFiManager::APlistExists(const char* ssid, const char *passphrase) { + DEBUG_WIFI_MULTI("[WIFI][APlistExists] check if ssid %s exists ?",ssid); + if(!ssid || *ssid == 0x00 || strlen(ssid) > 32) { + // fail SSID too long or missing! + DEBUG_WIFI_MULTI("[WIFI][APlistExists] no ssid or ssid too long\n"); + return false; + } + for(auto entry : APlist) { + if(!strcmp(entry.ssid, ssid)) { + DEBUG_WIFI_MULTI(" YES "); + if(!passphrase) { + return true; + } else { + if(!strcmp(entry.passphrase, passphrase)) { + DEBUG_WIFI_MULTI("and password match\n"); + return true; + } + } + } + } + DEBUG_WIFI_MULTI("\n"); + return false; +} + +void PersWiFiManager::APlistClean(void) { + for(auto entry : APlist) { + if(entry.ssid) { + free(entry.ssid); + } + if(entry.passphrase) { + free(entry.passphrase); + } + } + APlist.clear(); } \ No newline at end of file diff --git a/PersWiFiManager.h b/PersWiFiManager.h index a70b2a6..10fb705 100644 --- a/PersWiFiManager.h +++ b/PersWiFiManager.h @@ -13,9 +13,23 @@ #include //#define WIFI_HTM_PROGMEM -#define WIFI_HTM_GZ_PROGMEM +//#define WIFI_HTM_GZ_PROGMEM +//#define WIFI_HTM2_PROGMEM +#define WIFI_HTM2_GZ_PROGMEM #define WIFI_CONNECT_TIMEOUT 30 +#define WIFI_RETRY_TIME 60 +#define PERSWIFI_DEBUG 1 +//#define DEBUG_WIFI_MULTI(fmt, ...) if(Serial) Serial.printf( (PGM_P)PSTR(fmt), ##__VA_ARGS__ ) +#define DEBUG_WIFI_MULTI(fmt,...) + +struct persWifiAPEntry { + char * ssid; + char * passphrase; + unsigned long ID; +}; + +typedef std::vector persWifiAPlist; class PersWiFiManager { @@ -24,6 +38,7 @@ class PersWiFiManager typedef std::function WiFiChangeHandlerFunction; PersWiFiManager(AsyncWebServer &s, AsyncDNSServer &d, const fs::FS& fs = SPIFFS); + ~PersWiFiManager(); bool attemptConnection(const String &ssid = "", const String &pass = ""); @@ -45,8 +60,26 @@ class PersWiFiManager void onConnect(WiFiChangeHandlerFunction fn); + void onDisConnect(WiFiChangeHandlerFunction fn); + void onAp(WiFiChangeHandlerFunction fn); + void onStore(WiFiChangeHandlerFunction fn); + + bool addAP(const char* ssid, const char *passphrase = NULL); + bool removeAP(const char* ssid); + bool existsAP(const char* ssid, const char *passphrase = NULL); + persWifiAPlist getAPlist(); + wl_status_t GetStatus(); + + +private: + persWifiAPlist APlist; + bool APlistAdd(const char* ssid, const char *passphrase = NULL); + bool APlistRemove(const char* ssid); + bool APlistExists(const char* ssid, const char *passphrase = NULL); + void APlistClean(void); + private: Ticker _tkWiFiH; @@ -57,10 +90,16 @@ class PersWiFiManager String _fsUser = "admin", _fsPass = "password"; bool _connectNonBlock; + bool _autoReconnect; + bool _scanSorted; unsigned long _connectStartTime; + unsigned long _scanTime; + WiFiChangeHandlerFunction _connectHandler; + WiFiChangeHandlerFunction _disconnectHandler; WiFiChangeHandlerFunction _apHandler; + WiFiChangeHandlerFunction _storeHandler; }; //class diff --git a/data/wifimulti.html b/data/wifimulti.html new file mode 100644 index 0000000..fc5030d --- /dev/null +++ b/data/wifimulti.html @@ -0,0 +1,41 @@ + + + + + + ESP WiFi + + + + + +
+ +

+
+ +
+ +
+
+ +
+
+

+ +
+ +
+ +
+
+
+ +
+ Back | + Home +
+ + + \ No newline at end of file diff --git a/data/wifimulti.min.html b/data/wifimulti.min.html new file mode 100644 index 0000000..ad13ec4 --- /dev/null +++ b/data/wifimulti.min.html @@ -0,0 +1,2 @@ +ESP WiFi









Back|Home
\ No newline at end of file diff --git a/simple_json_non_blocking.ino b/simple_json_non_blocking.ino new file mode 100644 index 0000000..b7cf846 --- /dev/null +++ b/simple_json_non_blocking.ino @@ -0,0 +1,525 @@ +//includes +#include +#include +#include //https://github.com/debsahu/PersWiFiManager + //https://github.com/me-no-dev/ESPAsyncTCP + //https://github.com/me-no-dev/ESPAsyncWebServer + //https://github.com/devyte/ESPAsyncDNSServer + //https://github.com/me-no-dev/ESPAsyncUDP +#include +#include + +#define DEVICE_NAME "ESP8266 ADEM" +#define MAX_NR_SSID 10 +//server objects +AsyncWebServer server(80); +AsyncDNSServer dnsServer; +PersWiFiManager persWM(server, dnsServer); +////// Sample program data +int x; +String y; + +AESLib aesLib; + +String plaintext = "12345678;"; +int loopcount = 0; + +char cleartext[256]; +char ciphertext[512]; + +// AES Encryption Key +byte aes_key[] = { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }; + +// General initialization vector (you must use your own IV's in production for full security!!!) +byte aes_iv[N_BLOCK] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +// Sample strings as generated by node.js server +String server_b64iv = "AAAAAAAAAAAAAAAAAAAAAAAA=="; // same as aes_iv but in Base-64 form as received from server +String server_b64msg = "ei6NxsBeWk7hj41eia3S0LdkAlm2qxpRbmcsrd23TTc="; // same as aes_iv but in Base-64 form as received from server + +// Generate IV (once) +void aes_init() { + // workaround for incorrect B64 functionality on first run... + encrypt((char *) "HELLO WORLD!", aes_iv); + + print_key_iv(); + + // reset aes_iv to server-based value + int ivLen = base64_decode((char*)server_b64iv.c_str(), (char *)aes_iv, server_b64iv.length()); + Serial.print("Decoded IV bytes: "); + Serial.println(ivLen); + print_key_iv(); +} + +String encrypt(char * msg, byte iv[]) { + int msgLen = strlen(msg); + char *encrypted = new char [4 * msgLen]; + aesLib.encrypt64(msg, encrypted, aes_key, iv,128); + String tmp = String(encrypted); + delete(encrypted); + return tmp; +} + +String decrypt(char * msg, byte iv[]) { +// unsigned long ms = micros(); + int msgLen = strlen(msg); + char *decrypted = new char [msgLen]; // half may be enough + aesLib.decrypt64(msg, decrypted, aes_key, iv,128); + String tmp = String(decrypted); + delete(decrypted); + return tmp; +} + +void print_key_iv() { + + int i; + + Serial.println("AES IV: "); + for (i = 0; i < (int) sizeof(aes_iv); i++) { + Serial.print(aes_iv[i], HEX); + if ((i + 1) < (int) sizeof(aes_iv)) { + Serial.print(","); + } + } + + Serial.println(""); +} + + +void test_base64(){ +String strTest1 = ""; + for(int k = 0; k < 4; k++){ + strTest1 = strTest1 + "U"; + Serial.print(".... [ ]");Serial.println(strTest1); + + int i = base64_enc_len(strTest1.length()); + if ((i%4) == 0){ + Serial.print(" ==> [ OK ]"); + } + else + { + Serial.print(" ==> [FAIL]"); + } + Serial.print("input length :");Serial.print(strTest1.length()); + Serial.print(" is encoded : ");Serial.println(i); + char out[i]; + int j = base64_encode(out,(char *)strTest1.c_str(),strTest1.length()); + if (j==i){ + Serial.print(" ==> [ OK ]"); + } + else + { + Serial.print(" ==> [FAIL]"); + } + Serial.print("encoded length :");Serial.println(j); + if (String("VQ==VVU=VVVVVVVVVQ==").substring(k*4, k*4 + j).equals(out)){ + Serial.print(" ==> [ OK ]"); + } + else + { + Serial.print(" ==> [FAIL]"); + } + Serial.print("compare encoded string :");Serial.println(out); + int m= base64_dec_len(out,j); + char in[m]; + if (m==(int)strTest1.length()){ + Serial.print(" ==> [ OK ]"); + } + else + { + Serial.print(" ==> [FAIL]"); + } + Serial.print("decode length :");Serial.println(m); + base64_decode(in,out,j); + if (strTest1.equals(in)){ + Serial.print(" ==> [ OK ]"); + } + else + { + Serial.print(" ==> [FAIL]"); + } + Serial.print("decoded string :");Serial.println(in); + } +} + +/* +// Enable ECB, CTR and CBC mode. Note this can be done before including aes.h or at compile-time. +// E.g. with GCC by using the -D flag: gcc -c aes.c -DCBC=0 -DCTR=1 -DECB=1 +#define CBC 1 +#define CTR 1 +#define ECB 1 +#include + + + +static void phex(uint8_t* str); +static int test_encrypt_cbc(void); +static int test_decrypt_cbc(void); + +// prints string as hex +static void phex(uint8_t* str) +{ + +#if defined(AES256) + uint8_t len = 32; +#elif defined(AES192) + uint8_t len = 24; +#elif defined(AES128) + uint8_t len = 16; +#endif + + unsigned char i; + for (i = 0; i < len; ++i){ + Serial.print("0x"); + Serial.print( str[i],HEX); + Serial.print(", "); + } + Serial.println(); + for (i = 0; i < len; ++i) + Serial.print( (char )str[i]); + Serial.println(); +} + + + +static int test_decrypt_cbc(void) +{ + +#if defined(AES128) + uint8_t key[] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }; + uint8_t in[] = { 0x44, 0x6E, 0xB4, 0xFC, 0x0E, 0xCB, 0x11, 0x14, 0x04, 0x93, 0x05, 0x74, 0xE5, 0x8E, 0x3E, 0xD6}; +#endif + uint8_t iv[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; + uint8_t out[] = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!', 'A', 'E', 'S', 0x00 }; + +// uint8_t buffer[64]; + struct AES_ctx ctx; + + AES_init_ctx_iv(&ctx, key, iv); + AES_CBC_decrypt_buffer(&ctx, in, 16); + phex(in); + Serial.print("\n"); + Serial.print("CBC decrypt: "); + + if (0 == memcmp((char*) out, (char*) in, 16)) { + Serial.print("SUCCESS!\n"); + return(0); + } else { + Serial.print("FAILURE!\n"); + return(1); + } +} + +static int test_encrypt_cbc(void) +{ +#if defined(AES128) + uint8_t key[] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }; + uint8_t out[] = { 0x44, 0x6E, 0xB4, 0xFC, 0x0E, 0xCB, 0x11, 0x14, 0x04, 0x93, 0x05, 0x74, 0xE5, 0x8E, 0x3E, 0xD6}; + +#endif + uint8_t iv[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; + uint8_t in[] = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!', 'A', 'E', 'S', 0x00 }; + struct AES_ctx ctx; + + AES_init_ctx_iv(&ctx, key, iv); + phex(in); + Serial.print("\n"); + + AES_CBC_encrypt_buffer(&ctx, in, 16); + + phex(in); + Serial.print("\n"); + + Serial.print("CBC encrypt: "); + + if (0 == memcmp((char*) out, (char*) in, 16)) { + Serial.print("SUCCESS!\n"); + return(0); + } else { + Serial.print("FAILURE!\n"); + return(1); + } +} +*/ + + + +void readAPs(){ + 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.print("....opened config file "); + Serial.print(ESP.getFreeHeap()); + Serial.print(" --> "); + // size_t size = configFile.size(); + // Allocate a buffer to store contents of the file. + // std::unique_ptr buf(new char[size]); + Serial.print(ESP.getFreeHeap()); + + // configFile.readBytes(buf.get(), size); + DynamicJsonDocument jsonDoc(1024); + + DeserializationError error = deserializeJson(jsonDoc, configFile); + if (!error){ + Serial.println("....parsed json"); + const char *encpwd; + const char *ssid; + + /// Loop over storage size + JsonArray AP = jsonDoc["AP"]; + Serial.printf("jsonArray of size %d\n", AP.size()); + for(int i=0;i<=10;i++){ + byte dec_iv[N_BLOCK] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + Serial.printf("%d : ",i); + if (!AP[i]["S"].isNull()) { + ssid = AP[i]["S"]; + Serial.printf("reading : AP[%d] = %s ",i,ssid); + if (String(ssid).length() > 0) { + if (!AP[i]["P"].isNull()) { + encpwd = AP[i]["P"]; + Serial.printf("encrypted password = %s ",encpwd); + + + String pwd = decrypt( (char*)encpwd, dec_iv); + Serial.printf("Decrypted password = %s\n",pwd.c_str()); + persWM.addAP(ssid,pwd.c_str()); + } + else { + persWM.addAP(ssid); + } + } + } + else + { + break; + } + } + // is this blocking ??? https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp + + } else { + Serial.println("failed to load json config"); + } + } + } +} + +void setup() { + Serial.begin(77400); //for terminal debugging + Serial.println("Begin Setup"); + dnsServer.start(53,"www.myAdem.local",IPAddress(192, 168, 0, 189)); + //sets network name for AP mode + persWM.setApCredentials(DEVICE_NAME); + //persWM.setApCredentials(DEVICE_NAME, "password"); optional password + + persWM.onConnect([]() { + if (Serial) { + Serial.print("Router IP: "); + Serial.println(WiFi.localIP()); + Serial.print(" On SSID: "); + Serial.println(WiFi.SSID()); + } + }); + persWM.onDisConnect([]() { + if (Serial) { + Serial.println("Disconnected "); + } + readAPs(); // reread the AP's, they can be changed using edit function + }); + + persWM.onAp([](){ + if (Serial) { + Serial.print("AP Mode, IP: "); + Serial.println(persWM.getApSsid()); + } + }); + + persWM.onStore([]() { + Serial.print(ESP.getFreeHeap()); + DynamicJsonDocument jsonDoc(1024); + + File configFile ; + if (! SPIFFS.exists("/config.json")) { + Serial.println("create config file"); + } + else { + Serial.println("reading config file"); + Serial.print(ESP.getFreeHeap()); + configFile = SPIFFS.open("/config.json", "r"); + if (configFile) { + //size_t size = configFile.size(); + // Allocate a buffer to store contents of the file. + //std::unique_ptr buf(new char[size]); + //configFile.readBytes(buf.get(), size); + DeserializationError error = deserializeJson(jsonDoc, configFile);//buf.get()); + Serial.printf("error %s\n", error); + configFile.close(); + } + } + Serial.print(ESP.getFreeHeap()); + if (jsonDoc.isNull()){ // create empty document + jsonDoc.createNestedArray("AP"); + } + serializeJsonPretty(jsonDoc,Serial); + const char *ssid; + bool isDirty = false; + /// Loop over storage size + /// get count of SSID's + int count = MAX_NR_SSID; + JsonArray AP = jsonDoc["AP"]; + if (Serial) { + Serial.printf("%s : access point has be entered or update\n",WiFi.SSID().c_str()); + } + for(auto entry : persWM.getAPlist()) { + bool isFound = false; + byte enc_iv[N_BLOCK] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + String encrypted = encrypt(entry.passphrase, enc_iv); + if (Serial) { + Serial.printf("found %s as SSID and password (encrypted) %s\n",entry.ssid,encrypted.c_str()); + } + for(int i = 0; i < count;i++){ + ssid = AP[i]["S"]; + if (String(entry.ssid).equals(ssid)) { + isFound = true; + if (encrypted.equals((const char *)AP[i]["P"])){ + continue; + } + else + { + AP[i]["P"] = encrypted; + isDirty = true; + } + } + } + if(!isFound){ + // new AP --> add to list + JsonObject newAP = AP.createNestedObject(); + newAP["S"] = entry.ssid; + newAP["P"] = encrypted; + isDirty = true; + } + } + serializeJsonPretty(jsonDoc,Serial); + if (isDirty){ + Serial.println("storing new config file"); + + configFile = SPIFFS.open("/config.json", "w"); + if (!configFile) { + Serial.println(F("Failed to open config file")); + } + else { + if (serializeJsonPretty(jsonDoc, configFile) == 0) { + Serial.println(F("Failed to write to config file")); + } + configFile.close(); + } + } + }); + + if (SPIFFS.begin()) { + Serial.println("SPIFFS opened: " ); + readAPs(); + } + + //make connecting/disconnecting non-blocking + //persWM.setConnectNonBlock(true); //non blocking mode is enabled by default + + persWM.setFSCredentials("admin","password"); //SPIFFs: http:///edit + persWM.begin(); + //SPIFFS.format(); + + //handles commands from webpage, sends live data in JSON format + server.on("/api", HTTP_GET, [](AsyncWebServerRequest *request) { + Serial.println("server.on /api"); + if (request->hasArg("x")) { + x = request->arg("x").toInt(); + Serial.println(String("x: ")+x); + } //if + if (request->hasArg("y")) { + y = request->arg("y"); + Serial.println("y: "+y); + } //if + + //build json object of program data + StaticJsonDocument<200> jsondoc; + + jsondoc["x"] = x; + jsondoc["y"] = y; + + char jsonchar[200]; + serializeJson(jsondoc, jsonchar,200); //print to char array, takes more memory but sends in one piece + request->send(200, "application/json", jsonchar); + + }); //server.on api + + server.on("/Adem", HTTP_GET, [](AsyncWebServerRequest *request) { + Serial.println("server.on /Adem"); + request->redirect("http://home.scarlet.be/~la348750/"); + //AsyncWebServerResponse *response = request->beginResponse( 302, "text/plain",""); + //response->addHeader("Location",String("home.scarlet.be/Adem")); + //request->send(response); + }); + + server.begin(); + Serial.println("----------------------\nsetup complete."); + + test_base64(); + aes_init(); + + print_key_iv(); + + byte enc_iv[N_BLOCK] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // iv_block gets written to, provide own fresh copy... + // first decrypt after init should use aes_iv as given by server to test bare string first + String decrypted = decrypt((char*)server_b64msg.c_str(), enc_iv); // aes_iv fails here, incorrectly decoded... + Serial.print("Server Cleartext: "); + Serial.println(decrypted); + + print_key_iv(); + + loopcount = -1; + Serial.print("size of byte ");Serial.println(sizeof(byte)); + Serial.print("size of int ");Serial.println(sizeof(int)); + Serial.print("size of key ");Serial.println(sizeof(aes_key)); +} //void setup + + byte enc_iv[N_BLOCK] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // iv_block gets written to, provide own fresh copy... + byte dec_iv[N_BLOCK] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // iv_block gets written to, provide own fresh copy... + +void loop() { + //encrypt(); + //decrypt("ipYk12VCYyD+aJ7KL7lO8L5zOq71XvsLzp650gKBFgQor7GHs98QpQSjQOZdhCwggq2Ehf4nVNwTeK3VjtqMVJRGBw9YViARXCTOGqctjFc=", "+eNzSlRRPi0YZhrp5ctpnA==", 83); + //delay(8000); + + //in non-blocking mode, handleWiFi must be called in the main loop + //persWM.handleWiFi(); // no need + // do stuff with x and y + loopcount++; +/* + sprintf(cleartext, ">START; %i<", loopcount); + + print_key_iv(); + + // Encrypt + String encrypted = encrypt(cleartext, enc_iv); + sprintf(ciphertext, "%s", encrypted.c_str()); + Serial.print("Ciphertext: "); + Serial.println(encrypted); + + // Decrypt + String decrypted = decrypt( ciphertext, dec_iv); + Serial.print("Cleartext: "); + Serial.println(decrypted); + + if (decrypted.equals(cleartext)){ + Serial.println("SUCCES"); + } + else + { + Serial.println("FAILURE"); + loopcount = 0; + } + Serial.print(ESP.getFreeHeap()); + delay(1500); +*/ +} //void loop \ No newline at end of file From b7fe508436f410fbca87b6cc4bb16fa0e63b2dcd Mon Sep 17 00:00:00 2001 From: kavers1 Date: Sun, 26 May 2019 15:32:48 +0200 Subject: [PATCH 2/9] overcome compile warnings --- simple_json_non_blocking.ino | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/simple_json_non_blocking.ino b/simple_json_non_blocking.ino index b7cf846..576adb3 100644 --- a/simple_json_non_blocking.ino +++ b/simple_json_non_blocking.ino @@ -54,7 +54,7 @@ void aes_init() { String encrypt(char * msg, byte iv[]) { int msgLen = strlen(msg); char *encrypted = new char [4 * msgLen]; - aesLib.encrypt64(msg, encrypted, aes_key, iv,128); + aesLib.encrypt64(msg, encrypted, aes_key, 128,iv); String tmp = String(encrypted); delete(encrypted); return tmp; @@ -64,7 +64,7 @@ String decrypt(char * msg, byte iv[]) { // unsigned long ms = micros(); int msgLen = strlen(msg); char *decrypted = new char [msgLen]; // half may be enough - aesLib.decrypt64(msg, decrypted, aes_key, iv,128); + aesLib.decrypt64(msg, decrypted, aes_key, 128,iv); String tmp = String(decrypted); delete(decrypted); return tmp; @@ -353,7 +353,7 @@ void setup() { //std::unique_ptr buf(new char[size]); //configFile.readBytes(buf.get(), size); DeserializationError error = deserializeJson(jsonDoc, configFile);//buf.get()); - Serial.printf("error %s\n", error); + Serial.printf("error %s\n", error.c_str()); configFile.close(); } } From 18408a5a023b93cacbc6e6cbcf6cad6dee61e518 Mon Sep 17 00:00:00 2001 From: kavers1 Date: Sun, 26 May 2019 15:45:51 +0200 Subject: [PATCH 3/9] update doc multiAP --- README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/README.md b/README.md index eda7711..18d9023 100644 --- a/README.md +++ b/README.md @@ -22,3 +22,18 @@ This Persistent WiFi Manager provides a WiFi Settings web interface for ESP8266- This library and UI was inspired by tzapu's [WiFiManager library](https://github.com/tzapu/WiFiManager). The main difference is that it allows the program to continue functioning normally, even in AP mode. It is also more memory efficient, as it does not have to dynamically build the page, and can serve it from SPIFFS rather than PROGMEM. [Full Documentation](http://ryandowning.net/PersWiFiManager) + +## Info on multiple stored access points + +Added event handlers : + onDisConnect : is called when loosing a connection. This can be used to store the credentials of the last connection or trigger the reconnect to a different AP + onStore : is triggered by a succesfull connection to an AP, to store the current credentials in a safe storage. (in the demo it use AESLIB to encrypt the credential before storing them in a json file) +Added functions: +(similar to the ESP8266 wifiMulti AP handling but async + https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/station-examples.html ) + + bool addAP(const char* ssid, const char *passphrase = NULL) : adds AP credentials to the AP-list which will be used to try to connect to + bool removeAP(const char* ssid) : removes an AP from the AP-list + bool existsAP(const char* ssid, const char *passphrase = NULL) : checks if the AP exists in the AP-list with the same credentials + persWifiAPlist getAPlist() : returns the current list of AP's + wl_status_t GetStatus(): returns the status of the current connection. From 28606b2bc50050a26bb0990a3cfbdcb405595bf0 Mon Sep 17 00:00:00 2001 From: kavers1 Date: Sun, 26 May 2019 15:50:36 +0200 Subject: [PATCH 4/9] update docs multiAP --- README.md | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 18d9023..3064b98 100644 --- a/README.md +++ b/README.md @@ -26,14 +26,23 @@ This library and UI was inspired by tzapu's [WiFiManager library](https://github ## Info on multiple stored access points Added event handlers : - onDisConnect : is called when loosing a connection. This can be used to store the credentials of the last connection or trigger the reconnect to a different AP - onStore : is triggered by a succesfull connection to an AP, to store the current credentials in a safe storage. (in the demo it use AESLIB to encrypt the credential before storing them in a json file) + + onDisConnect : is called when loosing a connection. This can be used to store the credentials of the last connection or trigger the reconnect to a different AP + + onStore : is triggered by a succesfull connection to an AP, to store the current credentials in a safe storage. (in the demo it use AESLIB to encrypt the credential before storing them in a json file) + Added functions: + (similar to the ESP8266 wifiMulti AP handling but async https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/station-examples.html ) - bool addAP(const char* ssid, const char *passphrase = NULL) : adds AP credentials to the AP-list which will be used to try to connect to - bool removeAP(const char* ssid) : removes an AP from the AP-list - bool existsAP(const char* ssid, const char *passphrase = NULL) : checks if the AP exists in the AP-list with the same credentials - persWifiAPlist getAPlist() : returns the current list of AP's - wl_status_t GetStatus(): returns the status of the current connection. + bool addAP(const char* ssid, const char *passphrase = NULL) : adds AP credentials to the AP-list which will be used to try to connect to + + bool removeAP(const char* ssid) : removes an AP from the AP-list + + bool existsAP(const char* ssid, const char *passphrase = NULL) : checks if the AP exists in the AP-list with the same credentials + + persWifiAPlist getAPlist() : returns the current list of AP's + + wl_status_t GetStatus(): returns the status of the current connection. + From b3421fda7b535ed43a9038be5083cf5ad3cab1a7 Mon Sep 17 00:00:00 2001 From: kavers1 Date: Sun, 26 May 2019 15:55:36 +0200 Subject: [PATCH 5/9] update docs multiAP --- README.md | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 3064b98..65dd8bd 100644 --- a/README.md +++ b/README.md @@ -27,22 +27,17 @@ This library and UI was inspired by tzapu's [WiFiManager library](https://github Added event handlers : - onDisConnect : is called when loosing a connection. This can be used to store the credentials of the last connection or trigger the reconnect to a different AP - - onStore : is triggered by a succesfull connection to an AP, to store the current credentials in a safe storage. (in the demo it use AESLIB to encrypt the credential before storing them in a json file) + * onDisConnect : is called when loosing a connection. This can be used to store the credentials of the last connection or trigger the reconnect to a different AP + * onStore : is triggered by a succesfull connection to an AP, to store the current credentials in a safe storage. (in the demo it use AESLIB to encrypt the credential before storing them in a json file) Added functions: (similar to the ESP8266 wifiMulti AP handling but async https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/station-examples.html ) - bool addAP(const char* ssid, const char *passphrase = NULL) : adds AP credentials to the AP-list which will be used to try to connect to - - bool removeAP(const char* ssid) : removes an AP from the AP-list - - bool existsAP(const char* ssid, const char *passphrase = NULL) : checks if the AP exists in the AP-list with the same credentials + * bool addAP(const char* ssid, const char *passphrase = NULL) : adds AP credentials to the AP-list which will be used to try to connect to + * bool removeAP(const char* ssid) : removes an AP from the AP-list + * bool existsAP(const char* ssid, const char *passphrase = NULL) : checks if the AP exists in the AP-list with the same credentials + * persWifiAPlist getAPlist() : returns the current list of AP's + * wl_status_t GetStatus(): returns the status of the current connection. - persWifiAPlist getAPlist() : returns the current list of AP's - - wl_status_t GetStatus(): returns the status of the current connection. - From 8c021b7deddd77fdad20f18997c6ae8796a575b0 Mon Sep 17 00:00:00 2001 From: kavers1 Date: Sun, 26 May 2019 15:58:15 +0200 Subject: [PATCH 6/9] updated docs multiAP --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 65dd8bd..bbf2207 100644 --- a/README.md +++ b/README.md @@ -32,8 +32,7 @@ Added event handlers : Added functions: -(similar to the ESP8266 wifiMulti AP handling but async - https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/station-examples.html ) +(similar to the ESP8266 [wifiMulti](https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/station-examples.html) AP handling but async ) * bool addAP(const char* ssid, const char *passphrase = NULL) : adds AP credentials to the AP-list which will be used to try to connect to * bool removeAP(const char* ssid) : removes an AP from the AP-list From 3e24bfa99cae60419c76945b3d1f19fc7a145e5e Mon Sep 17 00:00:00 2001 From: kavers1 Date: Sun, 26 May 2019 16:04:23 +0200 Subject: [PATCH 7/9] updated examples for MultiAP --- .../MultiAP_simple_json_non_blocking.ino | 525 ++++++++++++++++++ 1 file changed, 525 insertions(+) create mode 100644 examples/MultiAP_simple_json_non_blocking/MultiAP_simple_json_non_blocking.ino diff --git a/examples/MultiAP_simple_json_non_blocking/MultiAP_simple_json_non_blocking.ino b/examples/MultiAP_simple_json_non_blocking/MultiAP_simple_json_non_blocking.ino new file mode 100644 index 0000000..576adb3 --- /dev/null +++ b/examples/MultiAP_simple_json_non_blocking/MultiAP_simple_json_non_blocking.ino @@ -0,0 +1,525 @@ +//includes +#include +#include +#include //https://github.com/debsahu/PersWiFiManager + //https://github.com/me-no-dev/ESPAsyncTCP + //https://github.com/me-no-dev/ESPAsyncWebServer + //https://github.com/devyte/ESPAsyncDNSServer + //https://github.com/me-no-dev/ESPAsyncUDP +#include +#include + +#define DEVICE_NAME "ESP8266 ADEM" +#define MAX_NR_SSID 10 +//server objects +AsyncWebServer server(80); +AsyncDNSServer dnsServer; +PersWiFiManager persWM(server, dnsServer); +////// Sample program data +int x; +String y; + +AESLib aesLib; + +String plaintext = "12345678;"; +int loopcount = 0; + +char cleartext[256]; +char ciphertext[512]; + +// AES Encryption Key +byte aes_key[] = { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }; + +// General initialization vector (you must use your own IV's in production for full security!!!) +byte aes_iv[N_BLOCK] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +// Sample strings as generated by node.js server +String server_b64iv = "AAAAAAAAAAAAAAAAAAAAAAAA=="; // same as aes_iv but in Base-64 form as received from server +String server_b64msg = "ei6NxsBeWk7hj41eia3S0LdkAlm2qxpRbmcsrd23TTc="; // same as aes_iv but in Base-64 form as received from server + +// Generate IV (once) +void aes_init() { + // workaround for incorrect B64 functionality on first run... + encrypt((char *) "HELLO WORLD!", aes_iv); + + print_key_iv(); + + // reset aes_iv to server-based value + int ivLen = base64_decode((char*)server_b64iv.c_str(), (char *)aes_iv, server_b64iv.length()); + Serial.print("Decoded IV bytes: "); + Serial.println(ivLen); + print_key_iv(); +} + +String encrypt(char * msg, byte iv[]) { + int msgLen = strlen(msg); + char *encrypted = new char [4 * msgLen]; + aesLib.encrypt64(msg, encrypted, aes_key, 128,iv); + String tmp = String(encrypted); + delete(encrypted); + return tmp; +} + +String decrypt(char * msg, byte iv[]) { +// unsigned long ms = micros(); + int msgLen = strlen(msg); + char *decrypted = new char [msgLen]; // half may be enough + aesLib.decrypt64(msg, decrypted, aes_key, 128,iv); + String tmp = String(decrypted); + delete(decrypted); + return tmp; +} + +void print_key_iv() { + + int i; + + Serial.println("AES IV: "); + for (i = 0; i < (int) sizeof(aes_iv); i++) { + Serial.print(aes_iv[i], HEX); + if ((i + 1) < (int) sizeof(aes_iv)) { + Serial.print(","); + } + } + + Serial.println(""); +} + + +void test_base64(){ +String strTest1 = ""; + for(int k = 0; k < 4; k++){ + strTest1 = strTest1 + "U"; + Serial.print(".... [ ]");Serial.println(strTest1); + + int i = base64_enc_len(strTest1.length()); + if ((i%4) == 0){ + Serial.print(" ==> [ OK ]"); + } + else + { + Serial.print(" ==> [FAIL]"); + } + Serial.print("input length :");Serial.print(strTest1.length()); + Serial.print(" is encoded : ");Serial.println(i); + char out[i]; + int j = base64_encode(out,(char *)strTest1.c_str(),strTest1.length()); + if (j==i){ + Serial.print(" ==> [ OK ]"); + } + else + { + Serial.print(" ==> [FAIL]"); + } + Serial.print("encoded length :");Serial.println(j); + if (String("VQ==VVU=VVVVVVVVVQ==").substring(k*4, k*4 + j).equals(out)){ + Serial.print(" ==> [ OK ]"); + } + else + { + Serial.print(" ==> [FAIL]"); + } + Serial.print("compare encoded string :");Serial.println(out); + int m= base64_dec_len(out,j); + char in[m]; + if (m==(int)strTest1.length()){ + Serial.print(" ==> [ OK ]"); + } + else + { + Serial.print(" ==> [FAIL]"); + } + Serial.print("decode length :");Serial.println(m); + base64_decode(in,out,j); + if (strTest1.equals(in)){ + Serial.print(" ==> [ OK ]"); + } + else + { + Serial.print(" ==> [FAIL]"); + } + Serial.print("decoded string :");Serial.println(in); + } +} + +/* +// Enable ECB, CTR and CBC mode. Note this can be done before including aes.h or at compile-time. +// E.g. with GCC by using the -D flag: gcc -c aes.c -DCBC=0 -DCTR=1 -DECB=1 +#define CBC 1 +#define CTR 1 +#define ECB 1 +#include + + + +static void phex(uint8_t* str); +static int test_encrypt_cbc(void); +static int test_decrypt_cbc(void); + +// prints string as hex +static void phex(uint8_t* str) +{ + +#if defined(AES256) + uint8_t len = 32; +#elif defined(AES192) + uint8_t len = 24; +#elif defined(AES128) + uint8_t len = 16; +#endif + + unsigned char i; + for (i = 0; i < len; ++i){ + Serial.print("0x"); + Serial.print( str[i],HEX); + Serial.print(", "); + } + Serial.println(); + for (i = 0; i < len; ++i) + Serial.print( (char )str[i]); + Serial.println(); +} + + + +static int test_decrypt_cbc(void) +{ + +#if defined(AES128) + uint8_t key[] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }; + uint8_t in[] = { 0x44, 0x6E, 0xB4, 0xFC, 0x0E, 0xCB, 0x11, 0x14, 0x04, 0x93, 0x05, 0x74, 0xE5, 0x8E, 0x3E, 0xD6}; +#endif + uint8_t iv[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; + uint8_t out[] = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!', 'A', 'E', 'S', 0x00 }; + +// uint8_t buffer[64]; + struct AES_ctx ctx; + + AES_init_ctx_iv(&ctx, key, iv); + AES_CBC_decrypt_buffer(&ctx, in, 16); + phex(in); + Serial.print("\n"); + Serial.print("CBC decrypt: "); + + if (0 == memcmp((char*) out, (char*) in, 16)) { + Serial.print("SUCCESS!\n"); + return(0); + } else { + Serial.print("FAILURE!\n"); + return(1); + } +} + +static int test_encrypt_cbc(void) +{ +#if defined(AES128) + uint8_t key[] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }; + uint8_t out[] = { 0x44, 0x6E, 0xB4, 0xFC, 0x0E, 0xCB, 0x11, 0x14, 0x04, 0x93, 0x05, 0x74, 0xE5, 0x8E, 0x3E, 0xD6}; + +#endif + uint8_t iv[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; + uint8_t in[] = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!', 'A', 'E', 'S', 0x00 }; + struct AES_ctx ctx; + + AES_init_ctx_iv(&ctx, key, iv); + phex(in); + Serial.print("\n"); + + AES_CBC_encrypt_buffer(&ctx, in, 16); + + phex(in); + Serial.print("\n"); + + Serial.print("CBC encrypt: "); + + if (0 == memcmp((char*) out, (char*) in, 16)) { + Serial.print("SUCCESS!\n"); + return(0); + } else { + Serial.print("FAILURE!\n"); + return(1); + } +} +*/ + + + +void readAPs(){ + 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.print("....opened config file "); + Serial.print(ESP.getFreeHeap()); + Serial.print(" --> "); + // size_t size = configFile.size(); + // Allocate a buffer to store contents of the file. + // std::unique_ptr buf(new char[size]); + Serial.print(ESP.getFreeHeap()); + + // configFile.readBytes(buf.get(), size); + DynamicJsonDocument jsonDoc(1024); + + DeserializationError error = deserializeJson(jsonDoc, configFile); + if (!error){ + Serial.println("....parsed json"); + const char *encpwd; + const char *ssid; + + /// Loop over storage size + JsonArray AP = jsonDoc["AP"]; + Serial.printf("jsonArray of size %d\n", AP.size()); + for(int i=0;i<=10;i++){ + byte dec_iv[N_BLOCK] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + Serial.printf("%d : ",i); + if (!AP[i]["S"].isNull()) { + ssid = AP[i]["S"]; + Serial.printf("reading : AP[%d] = %s ",i,ssid); + if (String(ssid).length() > 0) { + if (!AP[i]["P"].isNull()) { + encpwd = AP[i]["P"]; + Serial.printf("encrypted password = %s ",encpwd); + + + String pwd = decrypt( (char*)encpwd, dec_iv); + Serial.printf("Decrypted password = %s\n",pwd.c_str()); + persWM.addAP(ssid,pwd.c_str()); + } + else { + persWM.addAP(ssid); + } + } + } + else + { + break; + } + } + // is this blocking ??? https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp + + } else { + Serial.println("failed to load json config"); + } + } + } +} + +void setup() { + Serial.begin(77400); //for terminal debugging + Serial.println("Begin Setup"); + dnsServer.start(53,"www.myAdem.local",IPAddress(192, 168, 0, 189)); + //sets network name for AP mode + persWM.setApCredentials(DEVICE_NAME); + //persWM.setApCredentials(DEVICE_NAME, "password"); optional password + + persWM.onConnect([]() { + if (Serial) { + Serial.print("Router IP: "); + Serial.println(WiFi.localIP()); + Serial.print(" On SSID: "); + Serial.println(WiFi.SSID()); + } + }); + persWM.onDisConnect([]() { + if (Serial) { + Serial.println("Disconnected "); + } + readAPs(); // reread the AP's, they can be changed using edit function + }); + + persWM.onAp([](){ + if (Serial) { + Serial.print("AP Mode, IP: "); + Serial.println(persWM.getApSsid()); + } + }); + + persWM.onStore([]() { + Serial.print(ESP.getFreeHeap()); + DynamicJsonDocument jsonDoc(1024); + + File configFile ; + if (! SPIFFS.exists("/config.json")) { + Serial.println("create config file"); + } + else { + Serial.println("reading config file"); + Serial.print(ESP.getFreeHeap()); + configFile = SPIFFS.open("/config.json", "r"); + if (configFile) { + //size_t size = configFile.size(); + // Allocate a buffer to store contents of the file. + //std::unique_ptr buf(new char[size]); + //configFile.readBytes(buf.get(), size); + DeserializationError error = deserializeJson(jsonDoc, configFile);//buf.get()); + Serial.printf("error %s\n", error.c_str()); + configFile.close(); + } + } + Serial.print(ESP.getFreeHeap()); + if (jsonDoc.isNull()){ // create empty document + jsonDoc.createNestedArray("AP"); + } + serializeJsonPretty(jsonDoc,Serial); + const char *ssid; + bool isDirty = false; + /// Loop over storage size + /// get count of SSID's + int count = MAX_NR_SSID; + JsonArray AP = jsonDoc["AP"]; + if (Serial) { + Serial.printf("%s : access point has be entered or update\n",WiFi.SSID().c_str()); + } + for(auto entry : persWM.getAPlist()) { + bool isFound = false; + byte enc_iv[N_BLOCK] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + String encrypted = encrypt(entry.passphrase, enc_iv); + if (Serial) { + Serial.printf("found %s as SSID and password (encrypted) %s\n",entry.ssid,encrypted.c_str()); + } + for(int i = 0; i < count;i++){ + ssid = AP[i]["S"]; + if (String(entry.ssid).equals(ssid)) { + isFound = true; + if (encrypted.equals((const char *)AP[i]["P"])){ + continue; + } + else + { + AP[i]["P"] = encrypted; + isDirty = true; + } + } + } + if(!isFound){ + // new AP --> add to list + JsonObject newAP = AP.createNestedObject(); + newAP["S"] = entry.ssid; + newAP["P"] = encrypted; + isDirty = true; + } + } + serializeJsonPretty(jsonDoc,Serial); + if (isDirty){ + Serial.println("storing new config file"); + + configFile = SPIFFS.open("/config.json", "w"); + if (!configFile) { + Serial.println(F("Failed to open config file")); + } + else { + if (serializeJsonPretty(jsonDoc, configFile) == 0) { + Serial.println(F("Failed to write to config file")); + } + configFile.close(); + } + } + }); + + if (SPIFFS.begin()) { + Serial.println("SPIFFS opened: " ); + readAPs(); + } + + //make connecting/disconnecting non-blocking + //persWM.setConnectNonBlock(true); //non blocking mode is enabled by default + + persWM.setFSCredentials("admin","password"); //SPIFFs: http:///edit + persWM.begin(); + //SPIFFS.format(); + + //handles commands from webpage, sends live data in JSON format + server.on("/api", HTTP_GET, [](AsyncWebServerRequest *request) { + Serial.println("server.on /api"); + if (request->hasArg("x")) { + x = request->arg("x").toInt(); + Serial.println(String("x: ")+x); + } //if + if (request->hasArg("y")) { + y = request->arg("y"); + Serial.println("y: "+y); + } //if + + //build json object of program data + StaticJsonDocument<200> jsondoc; + + jsondoc["x"] = x; + jsondoc["y"] = y; + + char jsonchar[200]; + serializeJson(jsondoc, jsonchar,200); //print to char array, takes more memory but sends in one piece + request->send(200, "application/json", jsonchar); + + }); //server.on api + + server.on("/Adem", HTTP_GET, [](AsyncWebServerRequest *request) { + Serial.println("server.on /Adem"); + request->redirect("http://home.scarlet.be/~la348750/"); + //AsyncWebServerResponse *response = request->beginResponse( 302, "text/plain",""); + //response->addHeader("Location",String("home.scarlet.be/Adem")); + //request->send(response); + }); + + server.begin(); + Serial.println("----------------------\nsetup complete."); + + test_base64(); + aes_init(); + + print_key_iv(); + + byte enc_iv[N_BLOCK] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // iv_block gets written to, provide own fresh copy... + // first decrypt after init should use aes_iv as given by server to test bare string first + String decrypted = decrypt((char*)server_b64msg.c_str(), enc_iv); // aes_iv fails here, incorrectly decoded... + Serial.print("Server Cleartext: "); + Serial.println(decrypted); + + print_key_iv(); + + loopcount = -1; + Serial.print("size of byte ");Serial.println(sizeof(byte)); + Serial.print("size of int ");Serial.println(sizeof(int)); + Serial.print("size of key ");Serial.println(sizeof(aes_key)); +} //void setup + + byte enc_iv[N_BLOCK] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // iv_block gets written to, provide own fresh copy... + byte dec_iv[N_BLOCK] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // iv_block gets written to, provide own fresh copy... + +void loop() { + //encrypt(); + //decrypt("ipYk12VCYyD+aJ7KL7lO8L5zOq71XvsLzp650gKBFgQor7GHs98QpQSjQOZdhCwggq2Ehf4nVNwTeK3VjtqMVJRGBw9YViARXCTOGqctjFc=", "+eNzSlRRPi0YZhrp5ctpnA==", 83); + //delay(8000); + + //in non-blocking mode, handleWiFi must be called in the main loop + //persWM.handleWiFi(); // no need + // do stuff with x and y + loopcount++; +/* + sprintf(cleartext, ">START; %i<", loopcount); + + print_key_iv(); + + // Encrypt + String encrypted = encrypt(cleartext, enc_iv); + sprintf(ciphertext, "%s", encrypted.c_str()); + Serial.print("Ciphertext: "); + Serial.println(encrypted); + + // Decrypt + String decrypted = decrypt( ciphertext, dec_iv); + Serial.print("Cleartext: "); + Serial.println(decrypted); + + if (decrypted.equals(cleartext)){ + Serial.println("SUCCES"); + } + else + { + Serial.println("FAILURE"); + loopcount = 0; + } + Serial.print(ESP.getFreeHeap()); + delay(1500); +*/ +} //void loop \ No newline at end of file From 31fbeeaeb272f2189f71bed8ffd3932f774aeb5a Mon Sep 17 00:00:00 2001 From: kavers1 Date: Sun, 26 May 2019 16:05:47 +0200 Subject: [PATCH 8/9] delete multiap example --- simple_json_non_blocking.ino | 525 ----------------------------------- 1 file changed, 525 deletions(-) delete mode 100644 simple_json_non_blocking.ino diff --git a/simple_json_non_blocking.ino b/simple_json_non_blocking.ino deleted file mode 100644 index 576adb3..0000000 --- a/simple_json_non_blocking.ino +++ /dev/null @@ -1,525 +0,0 @@ -//includes -#include -#include -#include //https://github.com/debsahu/PersWiFiManager - //https://github.com/me-no-dev/ESPAsyncTCP - //https://github.com/me-no-dev/ESPAsyncWebServer - //https://github.com/devyte/ESPAsyncDNSServer - //https://github.com/me-no-dev/ESPAsyncUDP -#include -#include - -#define DEVICE_NAME "ESP8266 ADEM" -#define MAX_NR_SSID 10 -//server objects -AsyncWebServer server(80); -AsyncDNSServer dnsServer; -PersWiFiManager persWM(server, dnsServer); -////// Sample program data -int x; -String y; - -AESLib aesLib; - -String plaintext = "12345678;"; -int loopcount = 0; - -char cleartext[256]; -char ciphertext[512]; - -// AES Encryption Key -byte aes_key[] = { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }; - -// General initialization vector (you must use your own IV's in production for full security!!!) -byte aes_iv[N_BLOCK] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - -// Sample strings as generated by node.js server -String server_b64iv = "AAAAAAAAAAAAAAAAAAAAAAAA=="; // same as aes_iv but in Base-64 form as received from server -String server_b64msg = "ei6NxsBeWk7hj41eia3S0LdkAlm2qxpRbmcsrd23TTc="; // same as aes_iv but in Base-64 form as received from server - -// Generate IV (once) -void aes_init() { - // workaround for incorrect B64 functionality on first run... - encrypt((char *) "HELLO WORLD!", aes_iv); - - print_key_iv(); - - // reset aes_iv to server-based value - int ivLen = base64_decode((char*)server_b64iv.c_str(), (char *)aes_iv, server_b64iv.length()); - Serial.print("Decoded IV bytes: "); - Serial.println(ivLen); - print_key_iv(); -} - -String encrypt(char * msg, byte iv[]) { - int msgLen = strlen(msg); - char *encrypted = new char [4 * msgLen]; - aesLib.encrypt64(msg, encrypted, aes_key, 128,iv); - String tmp = String(encrypted); - delete(encrypted); - return tmp; -} - -String decrypt(char * msg, byte iv[]) { -// unsigned long ms = micros(); - int msgLen = strlen(msg); - char *decrypted = new char [msgLen]; // half may be enough - aesLib.decrypt64(msg, decrypted, aes_key, 128,iv); - String tmp = String(decrypted); - delete(decrypted); - return tmp; -} - -void print_key_iv() { - - int i; - - Serial.println("AES IV: "); - for (i = 0; i < (int) sizeof(aes_iv); i++) { - Serial.print(aes_iv[i], HEX); - if ((i + 1) < (int) sizeof(aes_iv)) { - Serial.print(","); - } - } - - Serial.println(""); -} - - -void test_base64(){ -String strTest1 = ""; - for(int k = 0; k < 4; k++){ - strTest1 = strTest1 + "U"; - Serial.print(".... [ ]");Serial.println(strTest1); - - int i = base64_enc_len(strTest1.length()); - if ((i%4) == 0){ - Serial.print(" ==> [ OK ]"); - } - else - { - Serial.print(" ==> [FAIL]"); - } - Serial.print("input length :");Serial.print(strTest1.length()); - Serial.print(" is encoded : ");Serial.println(i); - char out[i]; - int j = base64_encode(out,(char *)strTest1.c_str(),strTest1.length()); - if (j==i){ - Serial.print(" ==> [ OK ]"); - } - else - { - Serial.print(" ==> [FAIL]"); - } - Serial.print("encoded length :");Serial.println(j); - if (String("VQ==VVU=VVVVVVVVVQ==").substring(k*4, k*4 + j).equals(out)){ - Serial.print(" ==> [ OK ]"); - } - else - { - Serial.print(" ==> [FAIL]"); - } - Serial.print("compare encoded string :");Serial.println(out); - int m= base64_dec_len(out,j); - char in[m]; - if (m==(int)strTest1.length()){ - Serial.print(" ==> [ OK ]"); - } - else - { - Serial.print(" ==> [FAIL]"); - } - Serial.print("decode length :");Serial.println(m); - base64_decode(in,out,j); - if (strTest1.equals(in)){ - Serial.print(" ==> [ OK ]"); - } - else - { - Serial.print(" ==> [FAIL]"); - } - Serial.print("decoded string :");Serial.println(in); - } -} - -/* -// Enable ECB, CTR and CBC mode. Note this can be done before including aes.h or at compile-time. -// E.g. with GCC by using the -D flag: gcc -c aes.c -DCBC=0 -DCTR=1 -DECB=1 -#define CBC 1 -#define CTR 1 -#define ECB 1 -#include - - - -static void phex(uint8_t* str); -static int test_encrypt_cbc(void); -static int test_decrypt_cbc(void); - -// prints string as hex -static void phex(uint8_t* str) -{ - -#if defined(AES256) - uint8_t len = 32; -#elif defined(AES192) - uint8_t len = 24; -#elif defined(AES128) - uint8_t len = 16; -#endif - - unsigned char i; - for (i = 0; i < len; ++i){ - Serial.print("0x"); - Serial.print( str[i],HEX); - Serial.print(", "); - } - Serial.println(); - for (i = 0; i < len; ++i) - Serial.print( (char )str[i]); - Serial.println(); -} - - - -static int test_decrypt_cbc(void) -{ - -#if defined(AES128) - uint8_t key[] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }; - uint8_t in[] = { 0x44, 0x6E, 0xB4, 0xFC, 0x0E, 0xCB, 0x11, 0x14, 0x04, 0x93, 0x05, 0x74, 0xE5, 0x8E, 0x3E, 0xD6}; -#endif - uint8_t iv[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; - uint8_t out[] = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!', 'A', 'E', 'S', 0x00 }; - -// uint8_t buffer[64]; - struct AES_ctx ctx; - - AES_init_ctx_iv(&ctx, key, iv); - AES_CBC_decrypt_buffer(&ctx, in, 16); - phex(in); - Serial.print("\n"); - Serial.print("CBC decrypt: "); - - if (0 == memcmp((char*) out, (char*) in, 16)) { - Serial.print("SUCCESS!\n"); - return(0); - } else { - Serial.print("FAILURE!\n"); - return(1); - } -} - -static int test_encrypt_cbc(void) -{ -#if defined(AES128) - uint8_t key[] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }; - uint8_t out[] = { 0x44, 0x6E, 0xB4, 0xFC, 0x0E, 0xCB, 0x11, 0x14, 0x04, 0x93, 0x05, 0x74, 0xE5, 0x8E, 0x3E, 0xD6}; - -#endif - uint8_t iv[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; - uint8_t in[] = { 'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!', 'A', 'E', 'S', 0x00 }; - struct AES_ctx ctx; - - AES_init_ctx_iv(&ctx, key, iv); - phex(in); - Serial.print("\n"); - - AES_CBC_encrypt_buffer(&ctx, in, 16); - - phex(in); - Serial.print("\n"); - - Serial.print("CBC encrypt: "); - - if (0 == memcmp((char*) out, (char*) in, 16)) { - Serial.print("SUCCESS!\n"); - return(0); - } else { - Serial.print("FAILURE!\n"); - return(1); - } -} -*/ - - - -void readAPs(){ - 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.print("....opened config file "); - Serial.print(ESP.getFreeHeap()); - Serial.print(" --> "); - // size_t size = configFile.size(); - // Allocate a buffer to store contents of the file. - // std::unique_ptr buf(new char[size]); - Serial.print(ESP.getFreeHeap()); - - // configFile.readBytes(buf.get(), size); - DynamicJsonDocument jsonDoc(1024); - - DeserializationError error = deserializeJson(jsonDoc, configFile); - if (!error){ - Serial.println("....parsed json"); - const char *encpwd; - const char *ssid; - - /// Loop over storage size - JsonArray AP = jsonDoc["AP"]; - Serial.printf("jsonArray of size %d\n", AP.size()); - for(int i=0;i<=10;i++){ - byte dec_iv[N_BLOCK] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - Serial.printf("%d : ",i); - if (!AP[i]["S"].isNull()) { - ssid = AP[i]["S"]; - Serial.printf("reading : AP[%d] = %s ",i,ssid); - if (String(ssid).length() > 0) { - if (!AP[i]["P"].isNull()) { - encpwd = AP[i]["P"]; - Serial.printf("encrypted password = %s ",encpwd); - - - String pwd = decrypt( (char*)encpwd, dec_iv); - Serial.printf("Decrypted password = %s\n",pwd.c_str()); - persWM.addAP(ssid,pwd.c_str()); - } - else { - persWM.addAP(ssid); - } - } - } - else - { - break; - } - } - // is this blocking ??? https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WiFi/src/ESP8266WiFiMulti.cpp - - } else { - Serial.println("failed to load json config"); - } - } - } -} - -void setup() { - Serial.begin(77400); //for terminal debugging - Serial.println("Begin Setup"); - dnsServer.start(53,"www.myAdem.local",IPAddress(192, 168, 0, 189)); - //sets network name for AP mode - persWM.setApCredentials(DEVICE_NAME); - //persWM.setApCredentials(DEVICE_NAME, "password"); optional password - - persWM.onConnect([]() { - if (Serial) { - Serial.print("Router IP: "); - Serial.println(WiFi.localIP()); - Serial.print(" On SSID: "); - Serial.println(WiFi.SSID()); - } - }); - persWM.onDisConnect([]() { - if (Serial) { - Serial.println("Disconnected "); - } - readAPs(); // reread the AP's, they can be changed using edit function - }); - - persWM.onAp([](){ - if (Serial) { - Serial.print("AP Mode, IP: "); - Serial.println(persWM.getApSsid()); - } - }); - - persWM.onStore([]() { - Serial.print(ESP.getFreeHeap()); - DynamicJsonDocument jsonDoc(1024); - - File configFile ; - if (! SPIFFS.exists("/config.json")) { - Serial.println("create config file"); - } - else { - Serial.println("reading config file"); - Serial.print(ESP.getFreeHeap()); - configFile = SPIFFS.open("/config.json", "r"); - if (configFile) { - //size_t size = configFile.size(); - // Allocate a buffer to store contents of the file. - //std::unique_ptr buf(new char[size]); - //configFile.readBytes(buf.get(), size); - DeserializationError error = deserializeJson(jsonDoc, configFile);//buf.get()); - Serial.printf("error %s\n", error.c_str()); - configFile.close(); - } - } - Serial.print(ESP.getFreeHeap()); - if (jsonDoc.isNull()){ // create empty document - jsonDoc.createNestedArray("AP"); - } - serializeJsonPretty(jsonDoc,Serial); - const char *ssid; - bool isDirty = false; - /// Loop over storage size - /// get count of SSID's - int count = MAX_NR_SSID; - JsonArray AP = jsonDoc["AP"]; - if (Serial) { - Serial.printf("%s : access point has be entered or update\n",WiFi.SSID().c_str()); - } - for(auto entry : persWM.getAPlist()) { - bool isFound = false; - byte enc_iv[N_BLOCK] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - String encrypted = encrypt(entry.passphrase, enc_iv); - if (Serial) { - Serial.printf("found %s as SSID and password (encrypted) %s\n",entry.ssid,encrypted.c_str()); - } - for(int i = 0; i < count;i++){ - ssid = AP[i]["S"]; - if (String(entry.ssid).equals(ssid)) { - isFound = true; - if (encrypted.equals((const char *)AP[i]["P"])){ - continue; - } - else - { - AP[i]["P"] = encrypted; - isDirty = true; - } - } - } - if(!isFound){ - // new AP --> add to list - JsonObject newAP = AP.createNestedObject(); - newAP["S"] = entry.ssid; - newAP["P"] = encrypted; - isDirty = true; - } - } - serializeJsonPretty(jsonDoc,Serial); - if (isDirty){ - Serial.println("storing new config file"); - - configFile = SPIFFS.open("/config.json", "w"); - if (!configFile) { - Serial.println(F("Failed to open config file")); - } - else { - if (serializeJsonPretty(jsonDoc, configFile) == 0) { - Serial.println(F("Failed to write to config file")); - } - configFile.close(); - } - } - }); - - if (SPIFFS.begin()) { - Serial.println("SPIFFS opened: " ); - readAPs(); - } - - //make connecting/disconnecting non-blocking - //persWM.setConnectNonBlock(true); //non blocking mode is enabled by default - - persWM.setFSCredentials("admin","password"); //SPIFFs: http:///edit - persWM.begin(); - //SPIFFS.format(); - - //handles commands from webpage, sends live data in JSON format - server.on("/api", HTTP_GET, [](AsyncWebServerRequest *request) { - Serial.println("server.on /api"); - if (request->hasArg("x")) { - x = request->arg("x").toInt(); - Serial.println(String("x: ")+x); - } //if - if (request->hasArg("y")) { - y = request->arg("y"); - Serial.println("y: "+y); - } //if - - //build json object of program data - StaticJsonDocument<200> jsondoc; - - jsondoc["x"] = x; - jsondoc["y"] = y; - - char jsonchar[200]; - serializeJson(jsondoc, jsonchar,200); //print to char array, takes more memory but sends in one piece - request->send(200, "application/json", jsonchar); - - }); //server.on api - - server.on("/Adem", HTTP_GET, [](AsyncWebServerRequest *request) { - Serial.println("server.on /Adem"); - request->redirect("http://home.scarlet.be/~la348750/"); - //AsyncWebServerResponse *response = request->beginResponse( 302, "text/plain",""); - //response->addHeader("Location",String("home.scarlet.be/Adem")); - //request->send(response); - }); - - server.begin(); - Serial.println("----------------------\nsetup complete."); - - test_base64(); - aes_init(); - - print_key_iv(); - - byte enc_iv[N_BLOCK] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // iv_block gets written to, provide own fresh copy... - // first decrypt after init should use aes_iv as given by server to test bare string first - String decrypted = decrypt((char*)server_b64msg.c_str(), enc_iv); // aes_iv fails here, incorrectly decoded... - Serial.print("Server Cleartext: "); - Serial.println(decrypted); - - print_key_iv(); - - loopcount = -1; - Serial.print("size of byte ");Serial.println(sizeof(byte)); - Serial.print("size of int ");Serial.println(sizeof(int)); - Serial.print("size of key ");Serial.println(sizeof(aes_key)); -} //void setup - - byte enc_iv[N_BLOCK] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // iv_block gets written to, provide own fresh copy... - byte dec_iv[N_BLOCK] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // iv_block gets written to, provide own fresh copy... - -void loop() { - //encrypt(); - //decrypt("ipYk12VCYyD+aJ7KL7lO8L5zOq71XvsLzp650gKBFgQor7GHs98QpQSjQOZdhCwggq2Ehf4nVNwTeK3VjtqMVJRGBw9YViARXCTOGqctjFc=", "+eNzSlRRPi0YZhrp5ctpnA==", 83); - //delay(8000); - - //in non-blocking mode, handleWiFi must be called in the main loop - //persWM.handleWiFi(); // no need - // do stuff with x and y - loopcount++; -/* - sprintf(cleartext, ">START; %i<", loopcount); - - print_key_iv(); - - // Encrypt - String encrypted = encrypt(cleartext, enc_iv); - sprintf(ciphertext, "%s", encrypted.c_str()); - Serial.print("Ciphertext: "); - Serial.println(encrypted); - - // Decrypt - String decrypted = decrypt( ciphertext, dec_iv); - Serial.print("Cleartext: "); - Serial.println(decrypted); - - if (decrypted.equals(cleartext)){ - Serial.println("SUCCES"); - } - else - { - Serial.println("FAILURE"); - loopcount = 0; - } - Serial.print(ESP.getFreeHeap()); - delay(1500); -*/ -} //void loop \ No newline at end of file From 5bf8b6e2ef68a395d125d5b9e61407eeecf84118 Mon Sep 17 00:00:00 2001 From: kavers1 Date: Sun, 26 May 2019 16:10:34 +0200 Subject: [PATCH 9/9] update library keyword multiAP --- keywords.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/keywords.txt b/keywords.txt index db2d9a2..cf98436 100644 --- a/keywords.txt +++ b/keywords.txt @@ -22,6 +22,14 @@ setConnectNonBlock KEYWORD2 startApMode KEYWORD2 onConnect KEYWORD2 onAp KEYWORD2 +onDisConnect KEYWORD2 +onStore KEYWORD2 +addAP KEYWORD2 +removeAP KEYWORD2 +existsAP KEYWORD2 +getAPlist KEYWORD2 +GetStatus KEYWORD2 + ####################################### # Constants (LITERAL1)