Arduinojson6 (#8)
* Remove redundant AuthSettingsService. Will re-implement properly soon using JWT. * Support ArduinoJson >= 6.0.0 * Fix ArduinoJson version to 6.x.x
This commit is contained in:
		| @@ -23,6 +23,6 @@ build_flags= | |||||||
| lib_deps = | lib_deps = | ||||||
|   https://github.com/PaulStoffregen/Time |   https://github.com/PaulStoffregen/Time | ||||||
|   https://github.com/gmag11/NtpClient |   https://github.com/gmag11/NtpClient | ||||||
|   ArduinoJson@>=5.0.0,<6.0.0 |   ArduinoJson@>=6.0.0,<7.0.0 | ||||||
|   https://github.com/me-no-dev/ESPAsyncWebServer |   https://github.com/me-no-dev/ESPAsyncWebServer | ||||||
|   https://github.com/me-no-dev/AsyncTCP |   https://github.com/me-no-dev/AsyncTCP | ||||||
|   | |||||||
| @@ -5,8 +5,8 @@ APStatus::APStatus(AsyncWebServer *server) : _server(server) { | |||||||
| } | } | ||||||
|  |  | ||||||
| void APStatus::apStatus(AsyncWebServerRequest *request) { | void APStatus::apStatus(AsyncWebServerRequest *request) { | ||||||
|   AsyncJsonResponse * response = new AsyncJsonResponse(); |   AsyncJsonResponse * response = new AsyncJsonResponse(MAX_AP_STATUS_SIZE); | ||||||
|   JsonObject& root = response->getRoot(); |   JsonObject root = response->getRoot(); | ||||||
|  |  | ||||||
|   WiFiMode_t currentWiFiMode = WiFi.getMode(); |   WiFiMode_t currentWiFiMode = WiFi.getMode(); | ||||||
|   root["active"] =  (currentWiFiMode == WIFI_AP || currentWiFiMode == WIFI_AP_STA); |   root["active"] =  (currentWiFiMode == WIFI_AP || currentWiFiMode == WIFI_AP_STA); | ||||||
|   | |||||||
| @@ -11,9 +11,10 @@ | |||||||
|  |  | ||||||
| #include <ESPAsyncWebServer.h> | #include <ESPAsyncWebServer.h> | ||||||
| #include <ArduinoJson.h> | #include <ArduinoJson.h> | ||||||
| #include <AsyncJson.h> | #include <AsyncArduinoJson6.h> | ||||||
| #include <IPAddress.h> | #include <IPAddress.h> | ||||||
|  |  | ||||||
|  | #define MAX_AP_STATUS_SIZE 1024 | ||||||
| #define AP_STATUS_SERVICE_PATH "/rest/apStatus" | #define AP_STATUS_SERVICE_PATH "/rest/apStatus" | ||||||
|  |  | ||||||
| class APStatus { | class APStatus { | ||||||
|   | |||||||
							
								
								
									
										167
									
								
								src/AsyncArduinoJson6.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										167
									
								
								src/AsyncArduinoJson6.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,167 @@ | |||||||
|  |  | ||||||
|  | /** | ||||||
|  | *  A copy of AsyncJson.h from ESPAsyncWebServer, updated for ArduinoJson6. | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | #ifndef ASYNC_ARDUINO_JSON_6_H | ||||||
|  | #define ASYNC_ARDUINO_JSON_6_H | ||||||
|  |  | ||||||
|  | #include <ArduinoJson.h> | ||||||
|  | #include <WebResponseImpl.h> | ||||||
|  | #include <ESPAsyncWebServer.h> | ||||||
|  |  | ||||||
|  | constexpr const char* JSON_MIMETYPE = "application/json"; | ||||||
|  |  | ||||||
|  | class ChunkPrint : public Print { | ||||||
|  |   private: | ||||||
|  |     uint8_t* _destination; | ||||||
|  |     size_t _to_skip; | ||||||
|  |     size_t _to_write; | ||||||
|  |     size_t _pos; | ||||||
|  |   public: | ||||||
|  |     ChunkPrint(uint8_t* destination, size_t from, size_t len) | ||||||
|  |       : _destination(destination), _to_skip(from), _to_write(len), _pos{0} {} | ||||||
|  |     virtual ~ChunkPrint(){} | ||||||
|  |     size_t write(uint8_t c){ | ||||||
|  |       if (_to_skip > 0) { | ||||||
|  |         _to_skip--; | ||||||
|  |         return 1; | ||||||
|  |       } else if (_to_write > 0) { | ||||||
|  |         _to_write--; | ||||||
|  |         _destination[_pos++] = c; | ||||||
|  |         return 1; | ||||||
|  |       } | ||||||
|  |       return 0; | ||||||
|  |     } | ||||||
|  |     size_t write(const uint8_t *buffer, size_t size) { | ||||||
|  |       size_t written = 0; | ||||||
|  |       while (written < size && write(buffer[written])) { | ||||||
|  |         written++; | ||||||
|  |       } | ||||||
|  |       return written; | ||||||
|  |     }   | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | class AsyncJsonResponse: public AsyncAbstractResponse { | ||||||
|  |   private: | ||||||
|  |     DynamicJsonDocument _jsonDocument; | ||||||
|  |     bool _isValid; | ||||||
|  |     JsonObject _root;     | ||||||
|  |  | ||||||
|  |   public: | ||||||
|  |     AsyncJsonResponse(int maxSize): _jsonDocument(maxSize), _isValid{false} { | ||||||
|  |       _code = 200; | ||||||
|  |       _contentType = JSON_MIMETYPE; | ||||||
|  |       _root = _jsonDocument.to<JsonObject>(); | ||||||
|  |     } | ||||||
|  |     ~AsyncJsonResponse() {}     | ||||||
|  |     JsonObject getRoot() { | ||||||
|  |       return _root; | ||||||
|  |     } | ||||||
|  |     bool _sourceValid() const { | ||||||
|  |       return _isValid;  | ||||||
|  |     } | ||||||
|  |     size_t setLength() { | ||||||
|  |       _contentLength = measureJson(_jsonDocument); | ||||||
|  |       if (_contentLength) { _isValid = true; } | ||||||
|  |       return _contentLength; | ||||||
|  |     } | ||||||
|  |     size_t getSize() { | ||||||
|  |       return _jsonDocument.size(); | ||||||
|  |     } | ||||||
|  |     size_t _fillBuffer(uint8_t *data, size_t len){ | ||||||
|  |       ChunkPrint dest(data, _sentLength, len); | ||||||
|  |       serializeJson(_jsonDocument, dest); | ||||||
|  |       return len; | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | typedef std::function<void(AsyncWebServerRequest *request, JsonVariant json)> ArJsonRequestHandlerFunction; | ||||||
|  |  | ||||||
|  | class AsyncCallbackJsonWebHandler: public AsyncWebHandler { | ||||||
|  | private: | ||||||
|  | protected: | ||||||
|  |   const String _uri; | ||||||
|  |   WebRequestMethodComposite _method; | ||||||
|  |   ArJsonRequestHandlerFunction _onRequest; | ||||||
|  |   size_t _contentLength; | ||||||
|  |   size_t _maxContentLength; | ||||||
|  | public: | ||||||
|  |   AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest) : _uri(uri), _method(HTTP_POST|HTTP_PUT|HTTP_PATCH), _onRequest(onRequest), _maxContentLength(16384) {} | ||||||
|  |   void setMethod(WebRequestMethodComposite method){ _method = method; } | ||||||
|  |   void setMaxContentLength(int maxContentLength){ _maxContentLength = maxContentLength; } | ||||||
|  |   void onRequest(ArJsonRequestHandlerFunction fn){ _onRequest = fn; } | ||||||
|  |   virtual bool canHandle(AsyncWebServerRequest *request) override final{ | ||||||
|  |     if(!_onRequest) | ||||||
|  |       return false; | ||||||
|  |  | ||||||
|  |     if(!(_method & request->method())) | ||||||
|  |       return false; | ||||||
|  |  | ||||||
|  |     if(_uri.length() && (_uri != request->url() && !request->url().startsWith(_uri+"/"))) | ||||||
|  |       return false; | ||||||
|  |  | ||||||
|  |     if (!request->contentType().equalsIgnoreCase(JSON_MIMETYPE)) | ||||||
|  |       return false; | ||||||
|  |  | ||||||
|  |     request->addInterestingHeader("ANY"); | ||||||
|  |     return true; | ||||||
|  |   } | ||||||
|  |   virtual void handleRequest(AsyncWebServerRequest *request) override final { | ||||||
|  |     if(_onRequest) { | ||||||
|  |       if (request->_tempObject != NULL) { | ||||||
|  |         DynamicJsonDocument _jsonDocument(_maxContentLength); | ||||||
|  |         DeserializationError err = deserializeJson(_jsonDocument, (uint8_t*)(request->_tempObject)); | ||||||
|  |         if (err == DeserializationError::Ok) { | ||||||
|  |           _onRequest(request, _jsonDocument.as<JsonVariant>()); | ||||||
|  |           return; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       request->send(_contentLength > _maxContentLength ? 413 : 400); | ||||||
|  |     } else { | ||||||
|  |       request->send(500); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   virtual void handleUpload(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final) override final { | ||||||
|  |   } | ||||||
|  |   virtual void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) override final { | ||||||
|  |     if (_onRequest) { | ||||||
|  |       _contentLength = total; | ||||||
|  |       if (total > 0 && request->_tempObject == NULL && total < _maxContentLength) { | ||||||
|  |         request->_tempObject = malloc(total); | ||||||
|  |       } | ||||||
|  |       if (request->_tempObject != NULL) { | ||||||
|  |         memcpy((uint8_t*)(request->_tempObject) + index, data, len); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   virtual bool isRequestHandlerTrivial() override final {return _onRequest ? false : true;} | ||||||
|  | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | * Listens for a response being destroyed and calls a callback during said distruction. | ||||||
|  | * | ||||||
|  | * Used so we can take action after the response has been rendered to the client. | ||||||
|  | * | ||||||
|  | * Avoids having to fork ESPAsyncWebServer with a callback feature - still not a nice use of a destructor! | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | typedef std::function<void()> AsyncJsonCallback; | ||||||
|  |  | ||||||
|  | class AsyncJsonCallbackResponse: public AsyncJsonResponse { | ||||||
|  |  | ||||||
|  |   private: | ||||||
|  |  | ||||||
|  |       AsyncJsonCallback _callback; | ||||||
|  |  | ||||||
|  |   public: | ||||||
|  |  | ||||||
|  |     AsyncJsonCallbackResponse(AsyncJsonCallback callback, int maxSize) : AsyncJsonResponse(maxSize), _callback{callback} {} | ||||||
|  |     ~AsyncJsonCallbackResponse() { | ||||||
|  |       _callback(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #endif | ||||||
| @@ -1,31 +0,0 @@ | |||||||
| #ifndef _AsyncJsonCallbackResponse_H_ |  | ||||||
| #define _AsyncJsonCallbackResponse_H_ |  | ||||||
|  |  | ||||||
| #include <ESPAsyncWebServer.h> |  | ||||||
| #include <AsyncJson.h> |  | ||||||
|  |  | ||||||
| /* |  | ||||||
| * Listens for a response being destroyed and calls a callback during said distruction. |  | ||||||
| * used so we can take action after the response has been rendered to the client. |  | ||||||
| * |  | ||||||
| * Avoids having to fork ESPAsyncWebServer with a callback feature, but not nice! |  | ||||||
| */ |  | ||||||
|  |  | ||||||
| typedef std::function<void()> AsyncJsonCallback; |  | ||||||
|  |  | ||||||
| class AsyncJsonCallbackResponse: public AsyncJsonResponse { |  | ||||||
|  |  | ||||||
|   private: |  | ||||||
|  |  | ||||||
|       AsyncJsonCallback _callback; |  | ||||||
|  |  | ||||||
|   public: |  | ||||||
|  |  | ||||||
|     AsyncJsonCallbackResponse(AsyncJsonCallback callback, bool isArray=false) : AsyncJsonResponse(isArray), _callback{callback} {} |  | ||||||
|     ~AsyncJsonCallbackResponse() { |  | ||||||
|       _callback(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| #endif // end _AsyncJsonCallbackResponse_H_ |  | ||||||
| @@ -14,7 +14,7 @@ | |||||||
| * Really only of use where there is a determinate payload size. | * Really only of use where there is a determinate payload size. | ||||||
| */ | */ | ||||||
|  |  | ||||||
| typedef std::function<void(AsyncWebServerRequest *request, JsonVariant &json)> JsonRequestCallback; | typedef std::function<void(AsyncWebServerRequest *request, JsonDocument &jsonDocument)> JsonRequestCallback; | ||||||
|  |  | ||||||
| class AsyncJsonRequestWebHandler: public AsyncWebHandler { | class AsyncJsonRequestWebHandler: public AsyncWebHandler { | ||||||
|  |  | ||||||
| @@ -72,10 +72,10 @@ class AsyncJsonRequestWebHandler: public AsyncWebHandler { | |||||||
|  |  | ||||||
|       // parse JSON and if possible handle the request |       // parse JSON and if possible handle the request | ||||||
|       if (request->_tempObject) { |       if (request->_tempObject) { | ||||||
|         DynamicJsonBuffer jsonBuffer; |         DynamicJsonDocument jsonDocument(_maxContentLength); | ||||||
|         JsonVariant json = jsonBuffer.parse((uint8_t *) request->_tempObject); |         DeserializationError error = deserializeJson(jsonDocument, (uint8_t *) request->_tempObject); | ||||||
|         if (json.success()) { |         if (error == DeserializationError::Ok) { | ||||||
|           _onRequest(request, json); |           _onRequest(request, jsonDocument); | ||||||
|         }else{ |         }else{ | ||||||
|           request->send(400); |           request->send(400); | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -1,47 +0,0 @@ | |||||||
| #include <AuthSettingsService.h> |  | ||||||
|  |  | ||||||
| AuthSettingsService::AuthSettingsService(AsyncWebServer* server, FS* fs) : SettingsService(server, fs, AUTH_SETTINGS_SERVICE_PATH, AUTH_SETTINGS_FILE) { |  | ||||||
|   _server->on(AUTH_LOGOUT_SERVICE_PATH, HTTP_GET, std::bind(&AuthSettingsService::logout, this, std::placeholders::_1)); |  | ||||||
|  |  | ||||||
|   // configure authentication handler |  | ||||||
|   _authenticationHandler.setUri(AUTH_AUTHENTICATE_SERVICE_PATH); |  | ||||||
|   _authenticationHandler.setMethod(HTTP_POST); |  | ||||||
|   _authenticationHandler.onRequest(std::bind(&AuthSettingsService::authenticate, this, std::placeholders::_1, std::placeholders::_2)); |  | ||||||
|   _server->addHandler(&_authenticationHandler); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| AuthSettingsService::~AuthSettingsService() {} |  | ||||||
|  |  | ||||||
| // checks the session is authenticated, refreshes the sessions timeout if so |  | ||||||
| bool AuthSettingsService::authenticated(AsyncWebServerRequest *request){ |  | ||||||
|   request->send(400); |  | ||||||
|   return false; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void AuthSettingsService::readFromJsonObject(JsonObject& root){ |  | ||||||
|   _username = root["username"] | AUTH_DEFAULT_USERNAME; |  | ||||||
|   _password = root["password"] | AUTH_DEFAULT_PASSWORD; |  | ||||||
|   _sessionTimeout= root["session_timeout"] | AUTH_DEFAULT_SESSION_TIMEOUT; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void AuthSettingsService::writeToJsonObject(JsonObject& root){ |  | ||||||
|   root["username"] = _username; |  | ||||||
|   root["password"] = _password; |  | ||||||
|   root["session_timeout"] = _sessionTimeout; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void AuthSettingsService::logout(AsyncWebServerRequest *request){ |  | ||||||
|   // revoke the current requests session |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void AuthSettingsService::authenticate(AsyncWebServerRequest *request, JsonVariant &json){ |  | ||||||
|   if (json.is<JsonObject>()){ |  | ||||||
|     JsonObject& credentials = json.as<JsonObject>(); |  | ||||||
|     if (credentials["username"] == _username && credentials["password"] == _password){ |  | ||||||
|       // store cookie and write to response |  | ||||||
|     } |  | ||||||
|     request->send(401); |  | ||||||
|   } else{ |  | ||||||
|     request->send(400); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @@ -1,56 +0,0 @@ | |||||||
| #ifndef AuthSettingsService_h |  | ||||||
| #define AuthSettingsService_h |  | ||||||
|  |  | ||||||
| #include <SettingsService.h> |  | ||||||
|  |  | ||||||
| #define AUTH_DEFAULT_USERNAME "admin" |  | ||||||
| #define AUTH_DEFAULT_PASSWORD "admin" |  | ||||||
| #define AUTH_DEFAULT_SESSION_TIMEOUT 3600 |  | ||||||
|  |  | ||||||
| #define AUTH_SETTINGS_FILE "/config/authSettings.json" |  | ||||||
|  |  | ||||||
| #define AUTH_SETTINGS_SERVICE_PATH "/rest/authSettings" |  | ||||||
| #define AUTH_LOGOUT_SERVICE_PATH "/rest/logout" |  | ||||||
| #define AUTH_AUTHENTICATE_SERVICE_PATH "/rest/authenticate" |  | ||||||
|  |  | ||||||
| // max number of concurrently authenticated clients |  | ||||||
| #define AUTH_MAX_CLIENTS 10 |  | ||||||
|  |  | ||||||
| /* |  | ||||||
| * TODO: Will protect services with a cookie based authentication service. |  | ||||||
| */ |  | ||||||
|  |  | ||||||
| class AuthSettingsService : public SettingsService { |  | ||||||
|  |  | ||||||
|   public: |  | ||||||
|  |  | ||||||
|     AuthSettingsService(AsyncWebServer* server, FS* fs); |  | ||||||
|     ~AuthSettingsService(); |  | ||||||
|  |  | ||||||
|     // checks the session is authenticated, |  | ||||||
|     // refreshes the sessions timeout if found |  | ||||||
|     bool authenticated(AsyncWebServerRequest *request); |  | ||||||
|  |  | ||||||
|   protected: |  | ||||||
|  |  | ||||||
|     void readFromJsonObject(JsonObject& root); |  | ||||||
|     void writeToJsonObject(JsonObject& root); |  | ||||||
|  |  | ||||||
|   private: |  | ||||||
|  |  | ||||||
|     // callback handler for authentication endpoint |  | ||||||
|     AsyncJsonRequestWebHandler _authenticationHandler; |  | ||||||
|  |  | ||||||
|     // only supporting one username at the moment |  | ||||||
|     String _username; |  | ||||||
|     String _password; |  | ||||||
|  |  | ||||||
|     // session timeout in seconds |  | ||||||
|     unsigned int _sessionTimeout; |  | ||||||
|  |  | ||||||
|     void logout(AsyncWebServerRequest *request); |  | ||||||
|     void authenticate(AsyncWebServerRequest *request, JsonVariant &json); |  | ||||||
|  |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| #endif // end AuthSettingsService_h |  | ||||||
| @@ -5,8 +5,8 @@ NTPStatus::NTPStatus(AsyncWebServer *server) : _server(server) { | |||||||
| } | } | ||||||
|  |  | ||||||
| void NTPStatus::ntpStatus(AsyncWebServerRequest *request) { | void NTPStatus::ntpStatus(AsyncWebServerRequest *request) { | ||||||
|   AsyncJsonResponse * response = new AsyncJsonResponse(); |   AsyncJsonResponse * response = new AsyncJsonResponse(MAX_NTP_STATUS_SIZE); | ||||||
|   JsonObject& root = response->getRoot(); |   JsonObject root = response->getRoot(); | ||||||
|  |  | ||||||
|   // request time now first, this can sometimes force a sync |   // request time now first, this can sometimes force a sync | ||||||
|   time_t timeNow = now(); |   time_t timeNow = now(); | ||||||
|   | |||||||
| @@ -11,10 +11,11 @@ | |||||||
|  |  | ||||||
| #include <ESPAsyncWebServer.h> | #include <ESPAsyncWebServer.h> | ||||||
| #include <ArduinoJson.h> | #include <ArduinoJson.h> | ||||||
| #include <AsyncJson.h> | #include <AsyncArduinoJson6.h> | ||||||
| #include <TimeLib.h> | #include <TimeLib.h> | ||||||
| #include <NtpClientLib.h> | #include <NtpClientLib.h> | ||||||
|  |  | ||||||
|  | #define MAX_NTP_STATUS_SIZE 1024 | ||||||
| #define NTP_STATUS_SERVICE_PATH "/rest/ntpStatus" | #define NTP_STATUS_SERVICE_PATH "/rest/ntpStatus" | ||||||
|  |  | ||||||
| class NTPStatus { | class NTPStatus { | ||||||
|   | |||||||
| @@ -3,10 +3,9 @@ | |||||||
|  |  | ||||||
| #include <ESPAsyncWebServer.h> | #include <ESPAsyncWebServer.h> | ||||||
| #include <FS.h> | #include <FS.h> | ||||||
| #include <AsyncJson.h> |  | ||||||
| #include <ArduinoJson.h> | #include <ArduinoJson.h> | ||||||
| #include <AsyncJsonRequestWebHandler.h> | #include <AsyncJsonRequestWebHandler.h> | ||||||
| #include <AsyncJsonCallbackResponse.h> | #include <AsyncArduinoJson6.h> | ||||||
|  |  | ||||||
| /** | /** | ||||||
| * At the moment, not expecting settings service to have to deal with large JSON | * At the moment, not expecting settings service to have to deal with large JSON | ||||||
| @@ -30,8 +29,8 @@ protected: | |||||||
|  |  | ||||||
|   bool writeToFS() { |   bool writeToFS() { | ||||||
|     // create and populate a new json object |     // create and populate a new json object | ||||||
|     DynamicJsonBuffer jsonBuffer; |     DynamicJsonDocument jsonDocument = DynamicJsonDocument(MAX_SETTINGS_SIZE); | ||||||
|     JsonObject& root = jsonBuffer.createObject(); |     JsonObject root = jsonDocument.to<JsonObject>(); | ||||||
|     writeToJsonObject(root); |     writeToJsonObject(root); | ||||||
|  |  | ||||||
|     // serialize it to filesystem |     // serialize it to filesystem | ||||||
| @@ -42,7 +41,7 @@ protected: | |||||||
|       return false; |       return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     root.printTo(configFile); |     serializeJson(jsonDocument, configFile); | ||||||
|     configFile.close(); |     configFile.close(); | ||||||
|  |  | ||||||
|     return true; |     return true; | ||||||
| @@ -57,9 +56,10 @@ protected: | |||||||
|       // We never expect the config file to get very large, so cap it. |       // We never expect the config file to get very large, so cap it. | ||||||
|       size_t size = configFile.size(); |       size_t size = configFile.size(); | ||||||
|       if (size <= MAX_SETTINGS_SIZE) { |       if (size <= MAX_SETTINGS_SIZE) { | ||||||
|         DynamicJsonBuffer jsonBuffer; |         DynamicJsonDocument jsonDocument = DynamicJsonDocument(MAX_SETTINGS_SIZE); | ||||||
|         JsonObject& root = jsonBuffer.parseObject(configFile); |         DeserializationError error = deserializeJson(jsonDocument, configFile); | ||||||
|         if (root.success()) { |         if (error == DeserializationError::Ok && jsonDocument.is<JsonObject>()){ | ||||||
|  |           JsonObject root = jsonDocument.as<JsonObject>(); | ||||||
|           readFromJsonObject(root); |           readFromJsonObject(root); | ||||||
|           configFile.close(); |           configFile.close(); | ||||||
|           return;      |           return;      | ||||||
| @@ -81,8 +81,8 @@ protected: | |||||||
|     // We assume the readFromJsonObject supplies sensible defaults if an empty object |     // We assume the readFromJsonObject supplies sensible defaults if an empty object | ||||||
|     // is supplied, this virtual function allows that to be changed. |     // is supplied, this virtual function allows that to be changed. | ||||||
|     virtual void applyDefaultConfig(){ |     virtual void applyDefaultConfig(){ | ||||||
|       DynamicJsonBuffer jsonBuffer; |       DynamicJsonDocument jsonDocument = DynamicJsonDocument(MAX_SETTINGS_SIZE); | ||||||
|       JsonObject& root = jsonBuffer.createObject(); |       JsonObject root = jsonDocument.to<JsonObject>(); | ||||||
|       readFromJsonObject(root); |       readFromJsonObject(root); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -11,10 +11,9 @@ | |||||||
|  |  | ||||||
| #include <SettingsPersistence.h> | #include <SettingsPersistence.h> | ||||||
| #include <ESPAsyncWebServer.h> | #include <ESPAsyncWebServer.h> | ||||||
| #include <AsyncJson.h> |  | ||||||
| #include <ArduinoJson.h> | #include <ArduinoJson.h> | ||||||
| #include <AsyncJsonRequestWebHandler.h> | #include <AsyncJsonRequestWebHandler.h> | ||||||
| #include <AsyncJsonCallbackResponse.h> | #include <AsyncArduinoJson6.h> | ||||||
|  |  | ||||||
| /* | /* | ||||||
| * Abstraction of a service which stores it's settings as JSON in a file system. | * Abstraction of a service which stores it's settings as JSON in a file system. | ||||||
| @@ -26,24 +25,26 @@ private: | |||||||
|   AsyncJsonRequestWebHandler _updateHandler; |   AsyncJsonRequestWebHandler _updateHandler; | ||||||
|  |  | ||||||
|   void fetchConfig(AsyncWebServerRequest *request){ |   void fetchConfig(AsyncWebServerRequest *request){ | ||||||
|     AsyncJsonResponse * response = new AsyncJsonResponse(); |     AsyncJsonResponse * response = new AsyncJsonResponse(MAX_SETTINGS_SIZE); | ||||||
|     writeToJsonObject(response->getRoot()); |     JsonObject jsonObject = response->getRoot();   | ||||||
|  |     writeToJsonObject(jsonObject); | ||||||
|     response->setLength(); |     response->setLength(); | ||||||
|     request->send(response); |     request->send(response); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void updateConfig(AsyncWebServerRequest *request, JsonVariant &json){ |   void updateConfig(AsyncWebServerRequest *request, JsonDocument &jsonDocument){ | ||||||
|     if (json.is<JsonObject>()){ |     if (jsonDocument.is<JsonObject>()){ | ||||||
|       JsonObject& newConfig = json.as<JsonObject>(); |       JsonObject newConfig = jsonDocument.as<JsonObject>(); | ||||||
|       readFromJsonObject(newConfig); |       readFromJsonObject(newConfig); | ||||||
|       writeToFS(); |       writeToFS(); | ||||||
|  |  | ||||||
|       // write settings back with a callback to reconfigure the wifi |       // write settings back with a callback to reconfigure the wifi | ||||||
|       AsyncJsonCallbackResponse * response = new AsyncJsonCallbackResponse([this] () {onConfigUpdated();}); |       AsyncJsonCallbackResponse * response = new AsyncJsonCallbackResponse([this] () {onConfigUpdated();}, MAX_SETTINGS_SIZE); | ||||||
|       writeToJsonObject(response->getRoot()); |       JsonObject jsonObject = response->getRoot();    | ||||||
|  |       writeToJsonObject(jsonObject); | ||||||
|       response->setLength(); |       response->setLength(); | ||||||
|       request->send(response); |       request->send(response); | ||||||
|     } else{ |     } else { | ||||||
|       request->send(400); |       request->send(400); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -10,10 +10,9 @@ | |||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #include <ESPAsyncWebServer.h> | #include <ESPAsyncWebServer.h> | ||||||
| #include <AsyncJson.h> |  | ||||||
| #include <ArduinoJson.h> | #include <ArduinoJson.h> | ||||||
|  | #include <AsyncArduinoJson6.h> | ||||||
| #include <AsyncJsonRequestWebHandler.h> | #include <AsyncJsonRequestWebHandler.h> | ||||||
| #include <AsyncJsonCallbackResponse.h> |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
| * At the moment, not expecting services to have to deal with large JSON | * At the moment, not expecting services to have to deal with large JSON | ||||||
| @@ -35,23 +34,25 @@ private: | |||||||
|   AsyncJsonRequestWebHandler _updateHandler; |   AsyncJsonRequestWebHandler _updateHandler; | ||||||
|  |  | ||||||
|   void fetchConfig(AsyncWebServerRequest *request){ |   void fetchConfig(AsyncWebServerRequest *request){ | ||||||
|     AsyncJsonResponse * response = new AsyncJsonResponse(); |     AsyncJsonResponse * response = new AsyncJsonResponse(MAX_SETTINGS_SIZE); | ||||||
|     writeToJsonObject(response->getRoot()); |     JsonObject jsonObject = response->getRoot();     | ||||||
|  |     writeToJsonObject(jsonObject); | ||||||
|     response->setLength(); |     response->setLength(); | ||||||
|     request->send(response); |     request->send(response); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void updateConfig(AsyncWebServerRequest *request, JsonVariant &json){ |   void updateConfig(AsyncWebServerRequest *request, JsonDocument &jsonDocument){ | ||||||
|     if (json.is<JsonObject>()){ |     if (jsonDocument.is<JsonObject>()){ | ||||||
|       JsonObject& newConfig = json.as<JsonObject>(); |       JsonObject newConfig = jsonDocument.as<JsonObject>(); | ||||||
|       readFromJsonObject(newConfig); |       readFromJsonObject(newConfig); | ||||||
|   |   | ||||||
|       // write settings back with a callback to reconfigure the wifi |       // write settings back with a callback to reconfigure the wifi | ||||||
|       AsyncJsonCallbackResponse * response = new AsyncJsonCallbackResponse([this] () {onConfigUpdated();}); |       AsyncJsonCallbackResponse * response = new AsyncJsonCallbackResponse([this] () {onConfigUpdated();}, MAX_SETTINGS_SIZE); | ||||||
|       writeToJsonObject(response->getRoot()); |       JsonObject jsonObject = response->getRoot();     | ||||||
|  |       writeToJsonObject(jsonObject); | ||||||
|       response->setLength(); |       response->setLength(); | ||||||
|       request->send(response); |       request->send(response); | ||||||
|     } else{ |     } else { | ||||||
|       request->send(400); |       request->send(400); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -16,11 +16,11 @@ void WiFiScanner::scanNetworks(AsyncWebServerRequest *request) { | |||||||
| void WiFiScanner::listNetworks(AsyncWebServerRequest *request) { | void WiFiScanner::listNetworks(AsyncWebServerRequest *request) { | ||||||
|   int numNetworks = WiFi.scanComplete(); |   int numNetworks = WiFi.scanComplete(); | ||||||
|   if (numNetworks > -1){ |   if (numNetworks > -1){ | ||||||
|     AsyncJsonResponse * response = new AsyncJsonResponse(); |     AsyncJsonResponse * response = new AsyncJsonResponse(MAX_WIFI_SCANNER_SIZE); | ||||||
|     JsonObject& root = response->getRoot(); |     JsonObject root = response->getRoot(); | ||||||
|     JsonArray& networks = root.createNestedArray("networks"); |     JsonArray networks = root.createNestedArray("networks"); | ||||||
|     for (int i=0; i<numNetworks ; i++){ |     for (int i=0; i<numNetworks ; i++){ | ||||||
|       JsonObject& network =  networks.createNestedObject(); |       JsonObject network = networks.createNestedObject(); | ||||||
|       network["rssi"] = WiFi.RSSI(i); |       network["rssi"] = WiFi.RSSI(i); | ||||||
|       network["ssid"] = WiFi.SSID(i); |       network["ssid"] = WiFi.SSID(i); | ||||||
|       network["bssid"] = WiFi.BSSIDstr(i); |       network["bssid"] = WiFi.BSSIDstr(i); | ||||||
|   | |||||||
| @@ -11,12 +11,14 @@ | |||||||
|  |  | ||||||
| #include <ESPAsyncWebServer.h> | #include <ESPAsyncWebServer.h> | ||||||
| #include <ArduinoJson.h> | #include <ArduinoJson.h> | ||||||
| #include <AsyncJson.h> | #include <AsyncArduinoJson6.h> | ||||||
| #include <TimeLib.h> | #include <TimeLib.h> | ||||||
|  |  | ||||||
| #define SCAN_NETWORKS_SERVICE_PATH "/rest/scanNetworks" | #define SCAN_NETWORKS_SERVICE_PATH "/rest/scanNetworks" | ||||||
| #define LIST_NETWORKS_SERVICE_PATH "/rest/listNetworks" | #define LIST_NETWORKS_SERVICE_PATH "/rest/listNetworks" | ||||||
|  |  | ||||||
|  | #define MAX_WIFI_SCANNER_SIZE 1024 | ||||||
|  |  | ||||||
| class WiFiScanner { | class WiFiScanner { | ||||||
|  |  | ||||||
|   public: |   public: | ||||||
|   | |||||||
| @@ -49,8 +49,8 @@ void WiFiStatus::onStationModeGotIP(WiFiEvent_t event, WiFiEventInfo_t info) { | |||||||
| #endif | #endif | ||||||
|  |  | ||||||
| void WiFiStatus::wifiStatus(AsyncWebServerRequest *request) { | void WiFiStatus::wifiStatus(AsyncWebServerRequest *request) { | ||||||
|   AsyncJsonResponse * response = new AsyncJsonResponse(); |   AsyncJsonResponse * response = new AsyncJsonResponse(MAX_WIFI_STATUS_SIZE); | ||||||
|   JsonObject& root = response->getRoot(); |   JsonObject root = response->getRoot(); | ||||||
|   wl_status_t status = WiFi.status(); |   wl_status_t status = WiFi.status(); | ||||||
|   root["status"] = (uint8_t) status; |   root["status"] = (uint8_t) status; | ||||||
|   if (status == WL_CONNECTED){ |   if (status == WL_CONNECTED){ | ||||||
|   | |||||||
| @@ -11,9 +11,10 @@ | |||||||
|  |  | ||||||
| #include <ESPAsyncWebServer.h> | #include <ESPAsyncWebServer.h> | ||||||
| #include <ArduinoJson.h> | #include <ArduinoJson.h> | ||||||
| #include <AsyncJson.h> | #include <AsyncArduinoJson6.h> | ||||||
| #include <IPAddress.h> | #include <IPAddress.h> | ||||||
|  |  | ||||||
|  | #define MAX_WIFI_STATUS_SIZE 1024 | ||||||
| #define WIFI_STATUS_SERVICE_PATH "/rest/wifiStatus" | #define WIFI_STATUS_SERVICE_PATH "/rest/wifiStatus" | ||||||
|  |  | ||||||
| class WiFiStatus { | class WiFiStatus { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user