Arduino v7

This commit is contained in:
Proddy
2024-01-04 23:43:30 +01:00
parent 13a915e1f4
commit af237c4fc0
213 changed files with 3900 additions and 4479 deletions

View File

@@ -10,7 +10,7 @@ APStatus::APStatus(AsyncWebServer * server, SecurityManager * securityManager, A
}
void APStatus::apStatus(AsyncWebServerRequest * request) {
AsyncJsonResponse * response = new AsyncJsonResponse(false, MAX_AP_STATUS_SIZE);
AsyncJsonResponse * response = new AsyncJsonResponse(false);
JsonObject root = response->getRoot();
root["status"] = _apSettingsService->getAPNetworkStatus();

View File

@@ -10,7 +10,7 @@
#include <SecurityManager.h>
#include <APSettingsService.h>
#define MAX_AP_STATUS_SIZE 1024
// #define MAX_AP_STATUS_SIZE 1024
#define AP_STATUS_SERVICE_PATH "/rest/apStatus"
class APStatus {

View File

@@ -32,7 +32,7 @@ void AuthenticationService::signIn(AsyncWebServerRequest * request, JsonVariant
Authentication authentication = _securityManager->authenticate(username, password);
if (authentication.authenticated) {
User * user = authentication.user;
AsyncJsonResponse * response = new AsyncJsonResponse(false, MAX_AUTHENTICATION_SIZE);
AsyncJsonResponse * response = new AsyncJsonResponse(false);
JsonObject jsonObject = response->getRoot();
jsonObject["access_token"] = _securityManager->generateJWT(user);
response->setLength();

View File

@@ -7,18 +7,12 @@
template <class T>
class FSPersistence {
public:
FSPersistence(JsonStateReader<T> stateReader,
JsonStateUpdater<T> stateUpdater,
StatefulService<T> * statefulService,
FS * fs,
const char * filePath,
size_t bufferSize = FS_BUFFER_SIZE)
FSPersistence(JsonStateReader<T> stateReader, JsonStateUpdater<T> stateUpdater, StatefulService<T> * statefulService, FS * fs, const char * filePath)
: _stateReader(stateReader)
, _stateUpdater(stateUpdater)
, _statefulService(statefulService)
, _fs(fs)
, _filePath(filePath)
, _bufferSize(bufferSize)
, _updateHandlerId(0) {
enableUpdateHandler();
}
@@ -27,8 +21,8 @@ class FSPersistence {
File settingsFile = _fs->open(_filePath, "r");
if (settingsFile) {
DynamicJsonDocument jsonDocument = DynamicJsonDocument(_bufferSize);
DeserializationError error = deserializeJson(jsonDocument, settingsFile);
JsonDocument jsonDocument;
DeserializationError error = deserializeJson(jsonDocument, settingsFile);
if (error == DeserializationError::Ok && jsonDocument.is<JsonObject>()) {
JsonObject jsonObject = jsonDocument.as<JsonObject>();
_statefulService->updateWithoutPropagation(jsonObject, _stateUpdater);
@@ -46,8 +40,8 @@ class FSPersistence {
bool writeToFS() {
// create and populate a new json object
DynamicJsonDocument jsonDocument = DynamicJsonDocument(_bufferSize);
JsonObject jsonObject = jsonDocument.to<JsonObject>();
JsonDocument jsonDocument;
JsonObject jsonObject = jsonDocument.to<JsonObject>();
_statefulService->read(jsonObject, _stateReader);
// make directories if required, for new IDF4.2 & LittleFS
@@ -96,15 +90,14 @@ class FSPersistence {
StatefulService<T> * _statefulService;
FS * _fs;
const char * _filePath;
size_t _bufferSize;
update_handler_id_t _updateHandlerId;
protected:
// We assume the updater supplies sensible defaults if an empty object
// is supplied, this virtual function allows that to be changed.
virtual void applyDefaults() {
DynamicJsonDocument jsonDocument = DynamicJsonDocument(_bufferSize);
JsonObject jsonObject = jsonDocument.as<JsonObject>();
JsonDocument jsonDocument;
JsonObject jsonObject = jsonDocument.as<JsonObject>();
_statefulService->updateWithoutPropagation(jsonObject, _stateUpdater);
}
};

View File

@@ -8,7 +8,7 @@ FeaturesService::FeaturesService(AsyncWebServer * server) {
}
void FeaturesService::features(AsyncWebServerRequest * request) {
AsyncJsonResponse * response = new AsyncJsonResponse(false, MAX_FEATURES_SIZE);
AsyncJsonResponse * response = new AsyncJsonResponse(false);
JsonObject root = response->getRoot();
root["version"] = EMSESP_APP_VERSION;

View File

@@ -8,7 +8,7 @@
#include <AsyncJson.h>
#include <ESPAsyncWebServer.h>
#define MAX_FEATURES_SIZE 256
// #define MAX_FEATURES_SIZE 256
#define FEATURES_SERVICE_PATH "/rest/features"
class FeaturesService {

View File

@@ -20,32 +20,24 @@ class HttpGetEndpoint {
AsyncWebServer * server,
const String & servicePath,
SecurityManager * securityManager,
AuthenticationPredicate authenticationPredicate = AuthenticationPredicates::IS_ADMIN,
size_t bufferSize = DEFAULT_BUFFER_SIZE)
AuthenticationPredicate authenticationPredicate = AuthenticationPredicates::IS_ADMIN)
: _stateReader(stateReader)
, _statefulService(statefulService)
, _bufferSize(bufferSize) {
, _statefulService(statefulService) {
server->on(servicePath.c_str(), HTTP_GET, securityManager->wrapRequest(std::bind(&HttpGetEndpoint::fetchSettings, this, _1), authenticationPredicate));
}
HttpGetEndpoint(JsonStateReader<T> stateReader,
StatefulService<T> * statefulService,
AsyncWebServer * server,
const String & servicePath,
size_t bufferSize = DEFAULT_BUFFER_SIZE)
HttpGetEndpoint(JsonStateReader<T> stateReader, StatefulService<T> * statefulService, AsyncWebServer * server, const String & servicePath)
: _stateReader(stateReader)
, _statefulService(statefulService)
, _bufferSize(bufferSize) {
, _statefulService(statefulService) {
server->on(servicePath.c_str(), HTTP_GET, std::bind(&HttpGetEndpoint::fetchSettings, this, _1));
}
protected:
JsonStateReader<T> _stateReader;
StatefulService<T> * _statefulService;
size_t _bufferSize;
void fetchSettings(AsyncWebServerRequest * request) {
AsyncJsonResponse * response = new AsyncJsonResponse(false, _bufferSize);
AsyncJsonResponse * response = new AsyncJsonResponse(false);
JsonObject jsonObject = response->getRoot().to<JsonObject>();
_statefulService->read(jsonObject, _stateReader);
@@ -63,13 +55,11 @@ class HttpPostEndpoint {
AsyncWebServer * server,
const String & servicePath,
SecurityManager * securityManager,
AuthenticationPredicate authenticationPredicate = AuthenticationPredicates::IS_ADMIN,
size_t bufferSize = DEFAULT_BUFFER_SIZE)
AuthenticationPredicate authenticationPredicate = AuthenticationPredicates::IS_ADMIN)
: _stateReader(stateReader)
, _stateUpdater(stateUpdater)
, _statefulService(statefulService)
, _updateHandler(servicePath, securityManager->wrapCallback(std::bind(&HttpPostEndpoint::updateSettings, this, _1, _2), authenticationPredicate), bufferSize)
, _bufferSize(bufferSize) {
, _updateHandler(servicePath, securityManager->wrapCallback(std::bind(&HttpPostEndpoint::updateSettings, this, _1, _2), authenticationPredicate)) {
_updateHandler.setMethod(HTTP_POST);
server->addHandler(&_updateHandler);
}
@@ -78,13 +68,11 @@ class HttpPostEndpoint {
JsonStateUpdater<T> stateUpdater,
StatefulService<T> * statefulService,
AsyncWebServer * server,
const String & servicePath,
size_t bufferSize = DEFAULT_BUFFER_SIZE)
const String & servicePath)
: _stateReader(stateReader)
, _stateUpdater(stateUpdater)
, _statefulService(statefulService)
, _updateHandler(servicePath, std::bind(&HttpPostEndpoint::updateSettings, this, _1, _2), bufferSize)
, _bufferSize(bufferSize) {
, _updateHandler(servicePath, std::bind(&HttpPostEndpoint::updateSettings, this, _1, _2)) {
_updateHandler.setMethod(HTTP_POST);
server->addHandler(&_updateHandler);
}
@@ -94,7 +82,6 @@ class HttpPostEndpoint {
JsonStateUpdater<T> _stateUpdater;
StatefulService<T> * _statefulService;
AsyncCallbackJsonWebHandler _updateHandler;
size_t _bufferSize;
void updateSettings(AsyncWebServerRequest * request, JsonVariant & json) {
if (!json.is<JsonObject>()) {
@@ -109,7 +96,7 @@ class HttpPostEndpoint {
} else if ((outcome == StateUpdateResult::CHANGED) || (outcome == StateUpdateResult::CHANGED_RESTART)) {
request->onDisconnect([this]() { _statefulService->callUpdateHandlers(HTTP_ENDPOINT_ORIGIN_ID); });
}
AsyncJsonResponse * response = new AsyncJsonResponse(false, _bufferSize);
AsyncJsonResponse * response = new AsyncJsonResponse(false);
jsonObject = response->getRoot().to<JsonObject>();
_statefulService->read(jsonObject, _stateReader);
if (outcome == StateUpdateResult::CHANGED_RESTART) {
@@ -129,20 +116,18 @@ class HttpEndpoint : public HttpGetEndpoint<T>, public HttpPostEndpoint<T> {
AsyncWebServer * server,
const String & servicePath,
SecurityManager * securityManager,
AuthenticationPredicate authenticationPredicate = AuthenticationPredicates::IS_ADMIN,
size_t bufferSize = DEFAULT_BUFFER_SIZE)
: HttpGetEndpoint<T>(stateReader, statefulService, server, servicePath, securityManager, authenticationPredicate, bufferSize)
, HttpPostEndpoint<T>(stateReader, stateUpdater, statefulService, server, servicePath, securityManager, authenticationPredicate, bufferSize) {
AuthenticationPredicate authenticationPredicate = AuthenticationPredicates::IS_ADMIN)
: HttpGetEndpoint<T>(stateReader, statefulService, server, servicePath, securityManager, authenticationPredicate)
, HttpPostEndpoint<T>(stateReader, stateUpdater, statefulService, server, servicePath, securityManager, authenticationPredicate) {
}
HttpEndpoint(JsonStateReader<T> stateReader,
JsonStateUpdater<T> stateUpdater,
StatefulService<T> * statefulService,
AsyncWebServer * server,
const String & servicePath,
size_t bufferSize = DEFAULT_BUFFER_SIZE)
: HttpGetEndpoint<T>(stateReader, statefulService, server, servicePath, bufferSize)
, HttpPostEndpoint<T>(stateReader, stateUpdater, statefulService, server, servicePath, bufferSize) {
const String & servicePath)
: HttpGetEndpoint<T>(stateReader, statefulService, server, servicePath)
, HttpPostEndpoint<T>(stateReader, stateUpdater, statefulService, server, servicePath) {
}
};

View File

@@ -12,7 +12,7 @@ MqttStatus::MqttStatus(AsyncWebServer * server, MqttSettingsService * mqttSettin
}
void MqttStatus::mqttStatus(AsyncWebServerRequest * request) {
AsyncJsonResponse * response = new AsyncJsonResponse(false, MAX_MQTT_STATUS_SIZE);
AsyncJsonResponse * response = new AsyncJsonResponse(false);
JsonObject root = response->getRoot();
root["enabled"] = _mqttSettingsService->isEnabled();

View File

@@ -7,7 +7,7 @@
#include <ESPAsyncWebServer.h>
#include <SecurityManager.h>
#define MAX_MQTT_STATUS_SIZE 1024
// #define MAX_MQTT_STATUS_SIZE 1024
#define MQTT_STATUS_SERVICE_PATH "/rest/mqttStatus"
class MqttStatus {

View File

@@ -29,7 +29,7 @@ String toLocalTimeString(tm * time) {
}
void NTPStatus::ntpStatus(AsyncWebServerRequest * request) {
AsyncJsonResponse * response = new AsyncJsonResponse(false, MAX_NTP_STATUS_SIZE);
AsyncJsonResponse * response = new AsyncJsonResponse(false);
JsonObject root = response->getRoot();
// grab the current instant in unix seconds

View File

@@ -11,7 +11,7 @@
#include <SecurityManager.h>
#include <uuid/common.h>
#define MAX_NTP_STATUS_SIZE 1024
// #define MAX_NTP_STATUS_SIZE 1024
#define NTP_STATUS_SERVICE_PATH "/rest/ntpStatus"
class NTPStatus {

View File

@@ -11,7 +11,7 @@ NetworkStatus::NetworkStatus(AsyncWebServer * server, SecurityManager * security
}
void NetworkStatus::networkStatus(AsyncWebServerRequest * request) {
AsyncJsonResponse * response = new AsyncJsonResponse(false, MAX_NETWORK_STATUS_SIZE);
AsyncJsonResponse * response = new AsyncJsonResponse(false);
JsonObject root = response->getRoot();
bool ethernet_connected = emsesp::EMSESP::system_.ethernet_connected();

View File

@@ -18,7 +18,7 @@
#define AUTHORIZATION_HEADER_PREFIX "Bearer "
#define AUTHORIZATION_HEADER_PREFIX_LEN 7
#define MAX_JWT_SIZE 128
// #define MAX_JWT_SIZE 128
class User {
public:

View File

@@ -40,7 +40,7 @@ void SecuritySettingsService::configureJWTHandler() {
}
Authentication SecuritySettingsService::authenticateJWT(String & jwt) {
DynamicJsonDocument payloadDocument(MAX_JWT_SIZE);
JsonDocument payloadDocument;
_jwtHandler.parseJWT(jwt, payloadDocument);
if (payloadDocument.is<JsonObject>()) {
JsonObject parsedPayload = payloadDocument.as<JsonObject>();
@@ -69,15 +69,15 @@ inline void populateJWTPayload(JsonObject & payload, User * user) {
}
boolean SecuritySettingsService::validatePayload(JsonObject & parsedPayload, User * user) {
DynamicJsonDocument jsonDocument(MAX_JWT_SIZE);
JsonObject payload = jsonDocument.to<JsonObject>();
JsonDocument jsonDocument;
JsonObject payload = jsonDocument.to<JsonObject>();
populateJWTPayload(payload, user);
return payload == parsedPayload;
}
String SecuritySettingsService::generateJWT(User * user) {
DynamicJsonDocument jsonDocument(MAX_JWT_SIZE);
JsonObject payload = jsonDocument.to<JsonObject>();
JsonDocument jsonDocument;
JsonObject payload = jsonDocument.to<JsonObject>();
populateJWTPayload(payload, user);
return _jwtHandler.buildJWT(payload);
}
@@ -115,7 +115,7 @@ void SecuritySettingsService::generateToken(AsyncWebServerRequest * request) {
AsyncWebParameter * usernameParam = request->getParam("username");
for (User _user : _state.users) {
if (_user.username == usernameParam->value()) {
AsyncJsonResponse * response = new AsyncJsonResponse(false, GENERATE_TOKEN_SIZE);
AsyncJsonResponse * response = new AsyncJsonResponse(false);
JsonObject root = response->getRoot();
root["token"] = generateJWT(&_user);
response->setLength();

View File

@@ -40,9 +40,9 @@ class SecuritySettings {
root["jwt_secret"] = settings.jwtSecret;
// users
JsonArray users = root.createNestedArray("users");
JsonArray users = root["users"].to<JsonArray>();
for (User user : settings.users) {
JsonObject userRoot = users.createNestedObject();
JsonObject userRoot = users.add<JsonObject>();
userRoot["username"] = user.username;
userRoot["password"] = user.password;
userRoot["admin"] = user.admin;

View File

@@ -9,14 +9,6 @@
#include <freertos/FreeRTOS.h>
#include <freertos/semphr.h>
#ifndef DEFAULT_BUFFER_SIZE
#define DEFAULT_BUFFER_SIZE 2048
#endif
#ifndef FS_BUFFER_SIZE
#define FS_BUFFER_SIZE 8192
#endif
enum class StateUpdateResult {
CHANGED = 0, // The update changed the state and propagation should take place if required
CHANGED_RESTART, // a restart of the device is needed

View File

@@ -14,7 +14,7 @@ SystemStatus::SystemStatus(AsyncWebServer * server, SecurityManager * securityMa
void SystemStatus::systemStatus(AsyncWebServerRequest * request) {
emsesp::EMSESP::system_.refreshHeapMem(); // refresh free heap and max alloc heap
AsyncJsonResponse * response = new AsyncJsonResponse(false, MAX_ESP_STATUS_SIZE);
AsyncJsonResponse * response = new AsyncJsonResponse(false);
JsonObject root = response->getRoot();
root["emsesp_version"] = EMSESP_APP_VERSION;

View File

@@ -10,7 +10,7 @@
#include <ESPAsyncWebServer.h>
#include <SecurityManager.h>
#define MAX_ESP_STATUS_SIZE 1024
// #define MAX_ESP_STATUS_SIZE 1024
#define SYSTEM_STATUS_SERVICE_PATH "/rest/systemStatus"
class SystemStatus {

View File

@@ -52,7 +52,7 @@ void UploadFileService::handleUpload(AsyncWebServerRequest * request, const Stri
if (is_firmware) {
// Check firmware header, 0xE9 magic offset 0 indicates esp bin, chip offset 12: esp32:0, S2:2, C3:5
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
if (len > 12 && (data[0] != 0xE9 || data[12] != 0)) {
handleError(request, 503); // service unavailable
return;
@@ -81,7 +81,7 @@ void UploadFileService::handleUpload(AsyncWebServerRequest * request, const Stri
}
request->onDisconnect(UploadFileService::handleEarlyDisconnect); // success, let's make sure we end the update if the client hangs up
} else {
handleError(request, 507); // failed to begin, send an error response Insufficient Storage
handleError(request, 507); // failed to begin, send an error response Insufficient Storage
return;
}
} else {
@@ -133,7 +133,7 @@ void UploadFileService::uploadComplete(AsyncWebServerRequest * request) {
}
if (strlen(md5) == 32) {
auto * response = new AsyncJsonResponse(false, 256);
auto * response = new AsyncJsonResponse(false);
JsonObject root = response->getRoot();
root["md5"] = md5;
response->setLength();

View File

@@ -1,216 +0,0 @@
#ifndef WebSocketTxRx_h
#define WebSocketTxRx_h
#include <StatefulService.h>
#include <ESPAsyncWebServer.h>
#include <SecurityManager.h>
#define WEB_SOCKET_CLIENT_ID_MSG_SIZE 128
#define WEB_SOCKET_ORIGIN "websocket"
#define WEB_SOCKET_ORIGIN_CLIENT_ID_PREFIX "websocket:"
using namespace std::placeholders; // for `_1` etc
template <class T>
class WebSocketConnector {
protected:
StatefulService<T> * _statefulService;
AsyncWebServer * _server;
AsyncWebSocket _webSocket;
size_t _bufferSize;
WebSocketConnector(StatefulService<T> * statefulService,
AsyncWebServer * server,
const char * webSocketPath,
SecurityManager * securityManager,
AuthenticationPredicate authenticationPredicate,
size_t bufferSize)
: _statefulService(statefulService)
, _server(server)
, _webSocket(webSocketPath)
, _bufferSize(bufferSize) {
_webSocket.setFilter(securityManager->filterRequest(authenticationPredicate));
_webSocket.onEvent(std::bind(&WebSocketConnector::onWSEvent, this, _1, _2, _3, _4, _5, _6));
_server->addHandler(&_webSocket);
_server->on(webSocketPath, HTTP_GET, std::bind(&WebSocketConnector::forbidden, this, _1));
}
WebSocketConnector(StatefulService<T> * statefulService, AsyncWebServer * server, const char * webSocketPath, size_t bufferSize)
: _statefulService(statefulService)
, _server(server)
, _webSocket(webSocketPath)
, _bufferSize(bufferSize) {
_webSocket.onEvent(std::bind(&WebSocketConnector::onWSEvent, this, _1, _2, _3, _4, _5, _6));
_server->addHandler(&_webSocket);
}
virtual void onWSEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t * data, size_t len) = 0;
String clientId(AsyncWebSocketClient * client) {
return WEB_SOCKET_ORIGIN_CLIENT_ID_PREFIX + String(client->id());
}
private:
void forbidden(AsyncWebServerRequest * request) {
request->send(403);
}
};
template <class T>
class WebSocketTx : virtual public WebSocketConnector<T> {
public:
WebSocketTx(JsonStateReader<T> stateReader,
StatefulService<T> * statefulService,
AsyncWebServer * server,
const char * webSocketPath,
SecurityManager * securityManager,
AuthenticationPredicate authenticationPredicate = AuthenticationPredicates::IS_ADMIN,
size_t bufferSize = DEFAULT_BUFFER_SIZE)
: WebSocketConnector<T>(statefulService, server, webSocketPath, securityManager, authenticationPredicate, bufferSize)
, _stateReader(stateReader) {
WebSocketConnector<T>::_statefulService->addUpdateHandler([&](const String & originId) { transmitData(nullptr, originId); }, false);
}
WebSocketTx(JsonStateReader<T> stateReader,
StatefulService<T> * statefulService,
AsyncWebServer * server,
const char * webSocketPath,
size_t bufferSize = DEFAULT_BUFFER_SIZE)
: WebSocketConnector<T>(statefulService, server, webSocketPath, bufferSize)
, _stateReader(stateReader) {
WebSocketConnector<T>::_statefulService->addUpdateHandler([&](const String & originId) { transmitData(nullptr, originId); }, false);
}
protected:
virtual void onWSEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t * data, size_t len) {
if (type == WS_EVT_CONNECT) {
// when a client connects, we transmit it's id and the current payload
transmitId(client);
transmitData(client, WEB_SOCKET_ORIGIN);
}
}
private:
JsonStateReader<T> _stateReader;
void transmitId(AsyncWebSocketClient * client) {
DynamicJsonDocument jsonDocument = DynamicJsonDocument(WEB_SOCKET_CLIENT_ID_MSG_SIZE);
JsonObject root = jsonDocument.to<JsonObject>();
root["type"] = "id";
root["id"] = WebSocketConnector<T>::clientId(client);
size_t len = measureJson(jsonDocument);
AsyncWebSocketMessageBuffer * buffer = WebSocketConnector<T>::_webSocket.makeBuffer(len);
if (buffer) {
serializeJson(jsonDocument, (char *)buffer->get(), len + 1);
client->text(buffer);
}
}
/**
* Broadcasts the payload to the destination, if provided. Otherwise broadcasts to all clients except the origin, if
* specified.
*
* Original implementation sent clients their own IDs so they could ignore updates they initiated. This approach
* simplifies the client and the server implementation but may not be sufficent for all use-cases.
*/
void transmitData(AsyncWebSocketClient * client, const String & originId) {
DynamicJsonDocument jsonDocument = DynamicJsonDocument(WebSocketConnector<T>::_bufferSize);
JsonObject root = jsonDocument.to<JsonObject>();
root["type"] = "payload";
root["origin_id"] = originId;
JsonObject payload = root.createNestedObject("payload");
WebSocketConnector<T>::_statefulService->read(payload, _stateReader);
size_t len = measureJson(jsonDocument);
AsyncWebSocketMessageBuffer * buffer = WebSocketConnector<T>::_webSocket.makeBuffer(len);
if (buffer) {
serializeJson(jsonDocument, (char *)buffer->get(), len + 1);
if (client) {
client->text(buffer);
} else {
WebSocketConnector<T>::_webSocket.textAll(buffer);
}
}
}
};
template <class T>
class WebSocketRx : virtual public WebSocketConnector<T> {
public:
WebSocketRx(JsonStateUpdater<T> stateUpdater,
StatefulService<T> * statefulService,
AsyncWebServer * server,
const char * webSocketPath,
SecurityManager * securityManager,
AuthenticationPredicate authenticationPredicate = AuthenticationPredicates::IS_ADMIN,
size_t bufferSize = DEFAULT_BUFFER_SIZE)
: WebSocketConnector<T>(statefulService, server, webSocketPath, securityManager, authenticationPredicate, bufferSize)
, _stateUpdater(stateUpdater) {
}
WebSocketRx(JsonStateUpdater<T> stateUpdater,
StatefulService<T> * statefulService,
AsyncWebServer * server,
const char * webSocketPath,
size_t bufferSize = DEFAULT_BUFFER_SIZE)
: WebSocketConnector<T>(statefulService, server, webSocketPath, bufferSize)
, _stateUpdater(stateUpdater) {
}
protected:
virtual void onWSEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t * data, size_t len) {
if (type == WS_EVT_DATA) {
AwsFrameInfo * info = (AwsFrameInfo *)arg;
if (info->final && info->index == 0 && info->len == len) {
if (info->opcode == WS_TEXT) {
DynamicJsonDocument jsonDocument = DynamicJsonDocument(WebSocketConnector<T>::_bufferSize);
DeserializationError error = deserializeJson(jsonDocument, (char *)data);
if (!error && jsonDocument.is<JsonObject>()) {
JsonObject jsonObject = jsonDocument.as<JsonObject>();
WebSocketConnector<T>::_statefulService->update(jsonObject, _stateUpdater, WebSocketConnector<T>::clientId(client));
}
}
}
}
}
private:
JsonStateUpdater<T> _stateUpdater;
};
template <class T>
class WebSocketTxRx : public WebSocketTx<T>, public WebSocketRx<T> {
public:
WebSocketTxRx(JsonStateReader<T> stateReader,
JsonStateUpdater<T> stateUpdater,
StatefulService<T> * statefulService,
AsyncWebServer * server,
const char * webSocketPath,
SecurityManager * securityManager,
AuthenticationPredicate authenticationPredicate = AuthenticationPredicates::IS_ADMIN,
size_t bufferSize = DEFAULT_BUFFER_SIZE)
: WebSocketConnector<T>(statefulService, server, webSocketPath, securityManager, authenticationPredicate, bufferSize)
, WebSocketTx<T>(stateReader, statefulService, server, webSocketPath, securityManager, authenticationPredicate, bufferSize)
, WebSocketRx<T>(stateUpdater, statefulService, server, webSocketPath, securityManager, authenticationPredicate, bufferSize) {
}
WebSocketTxRx(JsonStateReader<T> stateReader,
JsonStateUpdater<T> stateUpdater,
StatefulService<T> * statefulService,
AsyncWebServer * server,
const char * webSocketPath,
size_t bufferSize = DEFAULT_BUFFER_SIZE)
: WebSocketConnector<T>(statefulService, server, webSocketPath, bufferSize)
, WebSocketTx<T>(stateReader, statefulService, server, webSocketPath, bufferSize)
, WebSocketRx<T>(stateUpdater, statefulService, server, webSocketPath, bufferSize) {
}
protected:
void onWSEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t * data, size_t len) {
WebSocketRx<T>::onWSEvent(server, client, type, arg, data, len);
WebSocketTx<T>::onWSEvent(server, client, type, arg, data, len);
}
};
#endif

View File

@@ -23,11 +23,11 @@ void WiFiScanner::scanNetworks(AsyncWebServerRequest * request) {
void WiFiScanner::listNetworks(AsyncWebServerRequest * request) {
int numNetworks = WiFi.scanComplete();
if (numNetworks > -1) {
AsyncJsonResponse * response = new AsyncJsonResponse(false, MAX_WIFI_SCANNER_SIZE);
AsyncJsonResponse * response = new AsyncJsonResponse(false);
JsonObject root = response->getRoot();
JsonArray networks = root.createNestedArray("networks");
JsonArray networks = root["networks"].to<JsonArray>();
for (int i = 0; i < numNetworks; i++) {
JsonObject network = networks.createNestedObject();
JsonObject network = networks.add<JsonObject>();
network["rssi"] = WiFi.RSSI(i);
network["ssid"] = WiFi.SSID(i);
network["bssid"] = WiFi.BSSIDstr(i);

View File

@@ -11,7 +11,7 @@
#define SCAN_NETWORKS_SERVICE_PATH "/rest/scanNetworks"
#define LIST_NETWORKS_SERVICE_PATH "/rest/listNetworks"
#define MAX_WIFI_SCANNER_SIZE 1024
// #define MAX_WIFI_SCANNER_SIZE 1024
class WiFiScanner {
public: