From 94e0918ccb8c0e38bd1086771431d6ce5177a524 Mon Sep 17 00:00:00 2001 From: Matthias Akstaller <63792403+matth-x@users.noreply.github.com> Date: Tue, 13 Aug 2024 16:35:51 +0200 Subject: [PATCH] Custom allocator / heap profiler (#350) * custom allocators layout (WIP) * custom allocator proof-of-concept with Request and Operation * fix Allocator tag handling * keep tag in dynamic memory * use allocators for Configs * revert allocator in Operation interface * use allocators in more Core modules * add memory tag to Request factory * simple heap profiler implementation * add vector with custom allocator type * use allocators in Model and Time * facilitate memory tag concatenation * use allocators for Variables * add type MemJsonDoc and factory method * use custom allocators for Operation classes * find tags for untagged memory blocks * capture maximum heap usage per memory tag * cover remaining allocations and debug * add missing custom alloc statements * fix compilation, remove Debug.h include * fix compilation on Arduino * fix compilation warnings / errors * fix UBSan reported error * add function to reset maximum heap usage * update Memory interface and function names * update changelog * fix building on ESP * fix building on ESP8266 * clean up custom allocator changes --- CHANGELOG.md | 1 + CMakeLists.txt | 7 +- src/MicroOcpp.cpp | 34 +- src/MicroOcpp.h | 17 +- src/MicroOcpp/Core/Configuration.cpp | 18 +- src/MicroOcpp/Core/Configuration.h | 4 +- src/MicroOcpp/Core/ConfigurationContainer.cpp | 5 +- src/MicroOcpp/Core/ConfigurationContainer.h | 6 +- .../Core/ConfigurationContainerFlash.cpp | 71 ++- src/MicroOcpp/Core/ConfigurationKeyValue.cpp | 20 +- src/MicroOcpp/Core/Configuration_c.cpp | 10 +- src/MicroOcpp/Core/Connection.cpp | 4 +- src/MicroOcpp/Core/Connection.h | 7 +- src/MicroOcpp/Core/Context.cpp | 2 +- src/MicroOcpp/Core/Context.h | 3 +- src/MicroOcpp/Core/FilesystemAdapter.cpp | 99 ++-- src/MicroOcpp/Core/FilesystemUtils.cpp | 8 +- src/MicroOcpp/Core/FilesystemUtils.h | 5 +- src/MicroOcpp/Core/FtpMbedTLS.cpp | 64 ++- src/MicroOcpp/Core/Memory.cpp | 294 ++++++++++++ src/MicroOcpp/Core/Memory.h | 444 ++++++++++++++++++ src/MicroOcpp/Core/OcppError.h | 15 +- src/MicroOcpp/Core/Operation.cpp | 10 +- src/MicroOcpp/Core/Operation.h | 9 +- src/MicroOcpp/Core/OperationRegistry.cpp | 2 +- src/MicroOcpp/Core/OperationRegistry.h | 5 +- src/MicroOcpp/Core/Request.cpp | 26 +- src/MicroOcpp/Core/Request.h | 15 +- src/MicroOcpp/Core/RequestQueue.cpp | 18 +- src/MicroOcpp/Core/RequestQueue.h | 5 +- src/MicroOcpp/Core/Time.cpp | 8 +- src/MicroOcpp/Core/Time.h | 3 +- .../Model/Authorization/AuthorizationData.cpp | 41 +- .../Model/Authorization/AuthorizationData.h | 13 +- .../Model/Authorization/AuthorizationList.cpp | 14 +- .../Model/Authorization/AuthorizationList.h | 6 +- .../Authorization/AuthorizationService.cpp | 8 +- .../Authorization/AuthorizationService.h | 3 +- src/MicroOcpp/Model/Authorization/IdToken.cpp | 21 +- src/MicroOcpp/Model/Authorization/IdToken.h | 9 +- src/MicroOcpp/Model/Boot/BootService.cpp | 12 +- src/MicroOcpp/Model/Boot/BootService.h | 7 +- .../Model/Certificates/Certificate.h | 10 +- .../Model/Certificates/CertificateMbedTLS.cpp | 16 +- .../Model/Certificates/CertificateService.cpp | 2 +- .../Model/Certificates/CertificateService.h | 3 +- .../Model/Certificates/Certificate_c.cpp | 7 +- .../Model/ConnectorBase/Connector.cpp | 3 +- src/MicroOcpp/Model/ConnectorBase/Connector.h | 8 +- .../Model/ConnectorBase/ConnectorsCommon.cpp | 4 +- .../Model/ConnectorBase/ConnectorsCommon.h | 3 +- .../Model/Diagnostics/DiagnosticsService.cpp | 50 +- .../Model/Diagnostics/DiagnosticsService.h | 13 +- .../FirmwareManagement/FirmwareService.cpp | 5 +- .../FirmwareManagement/FirmwareService.h | 7 +- .../Model/Heartbeat/HeartbeatService.cpp | 2 +- .../Model/Heartbeat/HeartbeatService.h | 6 +- src/MicroOcpp/Model/Metering/MeterStore.cpp | 10 +- src/MicroOcpp/Model/Metering/MeterStore.h | 14 +- src/MicroOcpp/Model/Metering/MeterValue.cpp | 37 +- src/MicroOcpp/Model/Metering/MeterValue.h | 20 +- .../Model/Metering/MeteringConnector.cpp | 10 +- .../Model/Metering/MeteringConnector.h | 8 +- .../Model/Metering/MeteringService.cpp | 36 +- .../Model/Metering/MeteringService.h | 6 +- src/MicroOcpp/Model/Metering/SampledValue.cpp | 29 +- src/MicroOcpp/Model/Metering/SampledValue.h | 50 +- src/MicroOcpp/Model/Model.cpp | 8 +- src/MicroOcpp/Model/Model.h | 7 +- .../Model/Reservation/Reservation.cpp | 2 +- src/MicroOcpp/Model/Reservation/Reservation.h | 3 +- .../Model/Reservation/ReservationService.cpp | 2 +- .../Model/Reservation/ReservationService.h | 5 +- src/MicroOcpp/Model/Reset/ResetService.cpp | 4 +- src/MicroOcpp/Model/Reset/ResetService.h | 8 +- .../SmartCharging/SmartChargingModel.cpp | 20 +- .../Model/SmartCharging/SmartChargingModel.h | 16 +- .../SmartCharging/SmartChargingService.cpp | 12 +- .../SmartCharging/SmartChargingService.h | 7 +- .../Model/Transactions/Transaction.h | 12 +- .../Transactions/TransactionDeserialize.cpp | 4 +- .../Transactions/TransactionDeserialize.h | 3 +- .../Model/Transactions/TransactionService.cpp | 20 +- .../Model/Transactions/TransactionService.h | 14 +- .../Model/Transactions/TransactionStore.cpp | 13 +- .../Model/Transactions/TransactionStore.h | 12 +- src/MicroOcpp/Model/Variables/Variable.cpp | 16 +- src/MicroOcpp/Model/Variables/Variable.h | 8 +- .../Model/Variables/VariableContainer.cpp | 2 +- .../Model/Variables/VariableContainer.h | 14 +- .../Model/Variables/VariableService.cpp | 16 +- .../Model/Variables/VariableService.h | 14 +- src/MicroOcpp/Operations/Authorize.cpp | 22 +- src/MicroOcpp/Operations/Authorize.h | 12 +- src/MicroOcpp/Operations/BootNotification.cpp | 13 +- src/MicroOcpp/Operations/BootNotification.h | 10 +- .../Operations/CancelReservation.cpp | 9 +- src/MicroOcpp/Operations/CancelReservation.h | 4 +- .../Operations/ChangeAvailability.cpp | 7 +- src/MicroOcpp/Operations/ChangeAvailability.h | 4 +- .../Operations/ChangeConfiguration.cpp | 7 +- .../Operations/ChangeConfiguration.h | 4 +- src/MicroOcpp/Operations/ClearCache.cpp | 7 +- src/MicroOcpp/Operations/ClearCache.h | 4 +- .../Operations/ClearChargingProfile.cpp | 7 +- .../Operations/ClearChargingProfile.h | 4 +- src/MicroOcpp/Operations/CustomOperation.cpp | 19 +- src/MicroOcpp/Operations/CustomOperation.h | 22 +- src/MicroOcpp/Operations/DataTransfer.cpp | 21 +- src/MicroOcpp/Operations/DataTransfer.h | 12 +- .../Operations/DeleteCertificate.cpp | 7 +- src/MicroOcpp/Operations/DeleteCertificate.h | 4 +- .../DiagnosticsStatusNotification.cpp | 7 +- .../DiagnosticsStatusNotification.h | 4 +- .../Operations/FirmwareStatusNotification.cpp | 7 +- .../Operations/FirmwareStatusNotification.h | 4 +- src/MicroOcpp/Operations/GetBaseReport.cpp | 7 +- src/MicroOcpp/Operations/GetBaseReport.h | 7 +- .../Operations/GetCompositeSchedule.cpp | 13 +- .../Operations/GetCompositeSchedule.h | 4 +- src/MicroOcpp/Operations/GetConfiguration.cpp | 15 +- src/MicroOcpp/Operations/GetConfiguration.h | 9 +- src/MicroOcpp/Operations/GetDiagnostics.cpp | 9 +- src/MicroOcpp/Operations/GetDiagnostics.h | 6 +- .../Operations/GetInstalledCertificateIds.cpp | 9 +- .../Operations/GetInstalledCertificateIds.h | 6 +- .../Operations/GetLocalListVersion.cpp | 7 +- .../Operations/GetLocalListVersion.h | 4 +- src/MicroOcpp/Operations/GetVariables.cpp | 16 +- src/MicroOcpp/Operations/GetVariables.h | 16 +- src/MicroOcpp/Operations/Heartbeat.cpp | 9 +- src/MicroOcpp/Operations/Heartbeat.h | 6 +- .../Operations/InstallCertificate.cpp | 7 +- src/MicroOcpp/Operations/InstallCertificate.h | 4 +- src/MicroOcpp/Operations/MeterValues.cpp | 15 +- src/MicroOcpp/Operations/MeterValues.h | 13 +- src/MicroOcpp/Operations/NotifyReport.cpp | 10 +- src/MicroOcpp/Operations/NotifyReport.h | 11 +- .../Operations/RemoteStartTransaction.cpp | 11 +- .../Operations/RemoteStartTransaction.h | 6 +- .../Operations/RemoteStopTransaction.cpp | 7 +- .../Operations/RemoteStopTransaction.h | 4 +- .../Operations/RequestStartTransaction.cpp | 7 +- .../Operations/RequestStartTransaction.h | 6 +- .../Operations/RequestStopTransaction.cpp | 7 +- .../Operations/RequestStopTransaction.h | 6 +- src/MicroOcpp/Operations/ReserveNow.cpp | 7 +- src/MicroOcpp/Operations/ReserveNow.h | 4 +- src/MicroOcpp/Operations/Reset.cpp | 13 +- src/MicroOcpp/Operations/Reset.h | 8 +- src/MicroOcpp/Operations/SendLocalList.cpp | 7 +- src/MicroOcpp/Operations/SendLocalList.h | 4 +- .../Operations/SetChargingProfile.cpp | 7 +- src/MicroOcpp/Operations/SetChargingProfile.h | 4 +- src/MicroOcpp/Operations/SetVariables.cpp | 14 +- src/MicroOcpp/Operations/SetVariables.h | 16 +- src/MicroOcpp/Operations/StartTransaction.cpp | 13 +- src/MicroOcpp/Operations/StartTransaction.h | 6 +- .../Operations/StatusNotification.cpp | 14 +- src/MicroOcpp/Operations/StatusNotification.h | 10 +- src/MicroOcpp/Operations/StopTransaction.cpp | 21 +- src/MicroOcpp/Operations/StopTransaction.h | 12 +- src/MicroOcpp/Operations/TransactionEvent.cpp | 12 +- src/MicroOcpp/Operations/TransactionEvent.h | 6 +- src/MicroOcpp/Operations/TriggerMessage.cpp | 7 +- src/MicroOcpp/Operations/TriggerMessage.h | 7 +- src/MicroOcpp/Operations/UnlockConnector.cpp | 7 +- src/MicroOcpp/Operations/UnlockConnector.h | 4 +- src/MicroOcpp/Operations/UpdateFirmware.cpp | 5 +- src/MicroOcpp/Operations/UpdateFirmware.h | 4 +- src/MicroOcpp_c.cpp | 3 +- tests/Api.cpp | 16 +- tests/Certificates.cpp | 18 +- tests/ChargePointError.cpp | 2 +- tests/ChargingSessions.cpp | 24 +- tests/Configuration.cpp | 16 +- tests/ConfigurationBehavior.cpp | 10 +- tests/FirmwareManagement.cpp | 32 +- tests/LocalAuthList.cpp | 44 +- tests/Metering.cpp | 6 +- tests/Reservation.cpp | 30 +- tests/Reset.cpp | 10 +- tests/SmartCharging.cpp | 30 +- tests/TransactionSafety.cpp | 2 +- tests/Transactions.cpp | 4 +- tests/Variables.cpp | 16 +- tests/helpers/testHelper.cpp | 16 + tests/ocppEngineLifecycle.cpp | 2 +- 188 files changed, 1964 insertions(+), 981 deletions(-) create mode 100644 src/MicroOcpp/Core/Memory.cpp create mode 100644 src/MicroOcpp/Core/Memory.h diff --git a/CHANGELOG.md b/CHANGELOG.md index eca02c88..0ad9de8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ - Support for `parentIdTag` ([#344](https://github.com/matth-x/MicroOcpp/pull/344)) - Input validation for unsigned int Configs ([#344](https://github.com/matth-x/MicroOcpp/pull/344)) - Support for TransactionMessageAttempts/-RetryInterval ([#345](https://github.com/matth-x/MicroOcpp/pull/345)) +- Heap profiler and custom allocator support ([#350](https://github.com/matth-x/MicroOcpp/pull/350)) ### Removed diff --git a/CMakeLists.txt b/CMakeLists.txt index f86ebf25..a3f085b1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,7 @@ set(MO_SRC src/MicroOcpp/Core/FilesystemAdapter.cpp src/MicroOcpp/Core/FilesystemUtils.cpp src/MicroOcpp/Core/FtpMbedTLS.cpp + src/MicroOcpp/Core/Memory.cpp src/MicroOcpp/Core/RequestQueue.cpp src/MicroOcpp/Core/Context.cpp src/MicroOcpp/Core/Operation.cpp @@ -169,7 +170,7 @@ if (MO_BUILD_UNIT_MBEDTLS) endif() target_include_directories(mo_unit_tests PUBLIC - "./tests/catch2" + "./tests" "./tests/helpers" "./src" ) @@ -190,6 +191,10 @@ target_compile_definitions(mo_unit_tests PUBLIC MO_ENABLE_CERT_MGMT=1 MO_ENABLE_CONNECTOR_LOCK=1 MO_REPORT_NOERROR=1 + MO_OVERRIDE_ALLOCATION=1 + MO_ENABLE_HEAP_PROFILER=1 + MO_HEAP_PROFILER_EXTERNAL_CONTROL=1 + CATCH_CONFIG_EXTERNAL_INTERFACES ) target_compile_options(mo_unit_tests PUBLIC diff --git a/src/MicroOcpp.cpp b/src/MicroOcpp.cpp index 73231056..2fc39ba3 100644 --- a/src/MicroOcpp.cpp +++ b/src/MicroOcpp.cpp @@ -56,6 +56,12 @@ std::shared_ptr filesystem; } //end namespace MicroOcpp::Facade } //end namespace MicroOcpp +#if MO_ENABLE_HEAP_PROFILER +#ifndef MO_HEAP_PROFILER_EXTERNAL_CONTROL +#define MO_HEAP_PROFILER_EXTERNAL_CONTROL 0 //enable if you want to manually reset the heap profiler (e.g. for keeping stats over multiple MO lifecycles) +#endif +#endif + using namespace MicroOcpp; using namespace MicroOcpp::Facade; using namespace MicroOcpp::Ocpp16; @@ -79,7 +85,7 @@ void mocpp_initialize(const char *backendUrl, const char *chargeBoxId, const cha /* * parse backendUrl so that it suits the links2004/arduinoWebSockets interface */ - std::string url = backendUrl; + auto url = makeString("MicroOcpp.cpp", backendUrl); //tolower protocol specifier for (auto c = url.begin(); *c != ':' && c != url.end(); c++) { @@ -97,16 +103,16 @@ void mocpp_initialize(const char *backendUrl, const char *chargeBoxId, const cha } //parse host, port - std::string host_port_path = url.substr(url.find_first_of("://") + strlen("://")); - std::string host_port = host_port_path.substr(0, host_port_path.find_first_of('/')); - std::string path = host_port_path.substr(host_port.length()); - std::string host = host_port.substr(0, host_port.find_first_of(':')); + auto host_port_path = url.substr(url.find_first_of("://") + strlen("://")); + auto host_port = host_port_path.substr(0, host_port_path.find_first_of('/')); + auto path = host_port_path.substr(host_port.length()); + auto host = host_port.substr(0, host_port.find_first_of(':')); if (host.empty()) { MO_DBG_ERR("could not parse host: %s", url.c_str()); return; } uint16_t port = 0; - std::string port_str = host_port.substr(host.length()); + auto port_str = host_port.substr(host.length()); if (port_str.empty()) { port = isTLS ? 443U : 80U; } else { @@ -287,7 +293,7 @@ void mocpp_initialize(Connection& connection, const char *bootNotificationCreden new BootService(*context, filesystem))); model.setConnectorsCommon(std::unique_ptr( new ConnectorsCommon(*context, MO_NUMCONNECTORS, filesystem))); - std::vector> connectors; + auto connectors = makeVector>("v16.ConnectorBase.Connector"); for (unsigned int connectorId = 0; connectorId < MO_NUMCONNECTORS; connectorId++) { connectors.emplace_back(new Connector(*context, filesystem, connectorId)); } @@ -404,6 +410,10 @@ void mocpp_deinitialize() { configuration_deinit(); +#if !MO_HEAP_PROFILER_EXTERNAL_CONTROL + MO_MEM_DEINIT(); +#endif + MO_DBG_DEBUG("deinitialized OCPP\n"); } @@ -470,8 +480,8 @@ bool endTransaction(const char *idTag, const char *reason, unsigned int connecto { // We have a parent ID tag, so we need to check if this new card also has one auto authorize = makeRequest(new Ocpp16::Authorize(context->getModel(), idTag)); - std::string idTag_capture = idTag; - std::string reason_capture = reason ? reason : ""; + auto idTag_capture = makeString("MicroOcpp.cpp", idTag); + auto reason_capture = makeString("MicroOcpp.cpp", reason ? reason : ""); authorize->setOnReceiveConfListener([idTag_capture, reason_capture, connectorId, tx] (JsonObject response) { JsonObject idTagInfo = response["idTagInfo"]; @@ -1087,7 +1097,7 @@ void setOnSendConf(const char *operationType, OnSendConfListener onSendConf) { } void sendRequest(const char *operationType, - std::function ()> fn_createReq, + std::function ()> fn_createReq, std::function fn_processConf) { if (!context) { @@ -1105,7 +1115,7 @@ void sendRequest(const char *operationType, void setRequestHandler(const char *operationType, std::function fn_processReq, - std::function ()> fn_createConf) { + std::function ()> fn_createConf) { if (!context) { MO_DBG_ERR("OCPP uninitialized"); //need to call mocpp_initialize before @@ -1116,7 +1126,7 @@ void setRequestHandler(const char *operationType, return; } - std::string captureOpType = operationType; + auto captureOpType = makeString("MicroOcpp.cpp", operationType); context->getOperationRegistry().registerOperation(operationType, [captureOpType, fn_processReq, fn_createConf] () { return new CustomOperation(captureOpType.c_str(), fn_processReq, fn_createConf); diff --git a/src/MicroOcpp.h b/src/MicroOcpp.h index 0567ea15..25896a26 100644 --- a/src/MicroOcpp.h +++ b/src/MicroOcpp.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -436,11 +437,11 @@ void setOnSendConf(const char *operationType, OnSendConfListener onSendConf); * * Use case 1, extend the library by sending additional operations. E.g. DataTransfer: * - * sendRequest("DataTransfer", [] () -> std::unique_ptr { + * sendRequest("DataTransfer", [] () -> std::unique_ptr { * //will be called to create the request once this operation is being sent out * size_t capacity = JSON_OBJECT_SIZE(3) + * JSON_OBJECT_SIZE(2); //for calculating the required capacity, see https://arduinojson.org/v6/assistant/ - * auto res = std::unique_ptr(new DynamicJsonDocument(capacity)); + * auto res = std::unique_ptr(new MicroOcpp::JsonDoc(capacity)); * JsonObject request = *res; * request["vendorId"] = "My company Ltd."; * request["messageId"] = "TargetValues"; @@ -457,10 +458,10 @@ void setOnSendConf(const char *operationType, OnSendConfListener onSendConf); * * Use case 2, bypass the business logic of this library for custom behavior. E.g. StartTransaction: * - * sendRequest("StartTransaction", [] () -> std::unique_ptr { + * sendRequest("StartTransaction", [] () -> std::unique_ptr { * //will be called to create the request once this operation is being sent out * size_t capacity = JSON_OBJECT_SIZE(4); //for calculating the required capacity, see https://arduinojson.org/v6/assistant/ - * auto res = std::unique_ptr(new DynamicJsonDocument(capacity)); + * auto res = std::unique_ptr(new MicroOcpp::JsonDoc(capacity)); * JsonObject request = res->to(); * request["connectorId"] = 1; * request["idTag"] = "A9C3CE1D7B71EA"; @@ -477,7 +478,7 @@ void setOnSendConf(const char *operationType, OnSendConfListener onSendConf); * its own. */ void sendRequest(const char *operationType, - std::function ()> fn_createReq, + std::function ()> fn_createReq, std::function fn_processConf); /* @@ -495,11 +496,11 @@ void sendRequest(const char *operationType, * const char *messageId = request["messageId"]; * int battery_capacity = request["data"]["battery_capacity"]; * int battery_soc = request["data"]["battery_soc"]; - * }, [] () -> std::unique_ptr { + * }, [] () -> std::unique_ptr { * //will be called to create the response once this operation is being sent out * size_t capacity = JSON_OBJECT_SIZE(2) + * JSON_OBJECT_SIZE(1); //for calculating the required capacity, see https://arduinojson.org/v6/assistant/ - * auto res = std::unique_ptr(new DynamicJsonDocument(capacity)); + * auto res = std::unique_ptr(new MicroOcpp::JsonDoc(capacity)); * JsonObject response = res->to(); * response["status"] = "Accepted"; * response["data"]["max_energy"] = 59; @@ -508,7 +509,7 @@ void sendRequest(const char *operationType, */ void setRequestHandler(const char *operationType, std::function fn_processReq, - std::function ()> fn_createConf); + std::function ()> fn_createConf); /* * Send OCPP operations manually not bypassing the internal business logic diff --git a/src/MicroOcpp/Core/Configuration.cpp b/src/MicroOcpp/Core/Configuration.cpp index 4ef802fa..ec1b9841 100644 --- a/src/MicroOcpp/Core/Configuration.cpp +++ b/src/MicroOcpp/Core/Configuration.cpp @@ -4,10 +4,10 @@ #include #include +#include #include #include -#include #include #include @@ -24,8 +24,8 @@ struct Validator { namespace ConfigurationLocal { std::shared_ptr filesystem; -std::vector> configurationContainers; -std::vector validators; +auto configurationContainers = makeVector>("v16.Configuration.Containers"); +auto validators = makeVector("v16.Configuration.Validators"); } @@ -50,8 +50,8 @@ void addConfigurationContainer(std::shared_ptr container } std::shared_ptr getContainer(const char *filename) { - std::vector>::iterator container = std::find_if(configurationContainers.begin(), configurationContainers.end(), - [filename](std::shared_ptr &elem) { + auto container = std::find_if(configurationContainers.begin(), configurationContainers.end(), + [filename](decltype(configurationContainers)::value_type &elem) { return !strcmp(elem->getFilename(), filename); }); @@ -192,8 +192,8 @@ Configuration *getConfigurationPublic(const char *key) { return nullptr; } -std::vector getConfigurationContainersPublic() { - std::vector res; +Vector getConfigurationContainersPublic() { + auto res = makeVector("v16.Configuration.Containers"); for (auto& container : configurationContainers) { if (container->isAccessible()) { @@ -210,8 +210,8 @@ bool configuration_init(std::shared_ptr _filesystem) { } void configuration_deinit() { - configurationContainers.clear(); - validators.clear(); + makeVector("v16.Configuration.Containers").swap(configurationContainers); //release allocated memory (see https://cplusplus.com/reference/vector/vector/clear/) + makeVector("v16.Configuration.Validators").swap(validators); filesystem.reset(); } diff --git a/src/MicroOcpp/Core/Configuration.h b/src/MicroOcpp/Core/Configuration.h index d6d09226..6b33f43c 100644 --- a/src/MicroOcpp/Core/Configuration.h +++ b/src/MicroOcpp/Core/Configuration.h @@ -8,9 +8,9 @@ #include #include #include +#include #include -#include #define CONFIGURATION_FN (MO_FILENAME_PREFIX "ocpp-config.jsn") #define CONFIGURATION_VOLATILE "/volatile" @@ -27,7 +27,7 @@ void registerConfigurationValidator(const char *key, std::function container); Configuration *getConfigurationPublic(const char *key); -std::vector getConfigurationContainersPublic(); +Vector getConfigurationContainersPublic(); bool configuration_init(std::shared_ptr filesytem); void configuration_deinit(); diff --git a/src/MicroOcpp/Core/ConfigurationContainer.cpp b/src/MicroOcpp/Core/ConfigurationContainer.cpp index e0554fe7..af0cba2f 100644 --- a/src/MicroOcpp/Core/ConfigurationContainer.cpp +++ b/src/MicroOcpp/Core/ConfigurationContainer.cpp @@ -12,7 +12,8 @@ ConfigurationContainer::~ConfigurationContainer() { } -ConfigurationContainerVolatile::ConfigurationContainerVolatile(const char *filename, bool accessible) : ConfigurationContainer(filename, accessible) { +ConfigurationContainerVolatile::ConfigurationContainerVolatile(const char *filename, bool accessible) : + ConfigurationContainer(filename, accessible), MemoryManaged("v16.Configuration.ContainerVoltaile.", filename), configurations(makeVector>(getMemoryTag())) { } @@ -25,7 +26,7 @@ bool ConfigurationContainerVolatile::save() { } std::shared_ptr ConfigurationContainerVolatile::createConfiguration(TConfig type, const char *key) { - std::shared_ptr res = makeConfiguration(type, key); + auto res = std::shared_ptr(makeConfiguration(type, key).release(), std::default_delete(), makeAllocator("v16.Configuration.", key)); if (!res) { //allocation failure - OOM MO_DBG_ERR("OOM"); diff --git a/src/MicroOcpp/Core/ConfigurationContainer.h b/src/MicroOcpp/Core/ConfigurationContainer.h index 44382a08..f31c613c 100644 --- a/src/MicroOcpp/Core/ConfigurationContainer.h +++ b/src/MicroOcpp/Core/ConfigurationContainer.h @@ -5,10 +5,10 @@ #ifndef MO_CONFIGURATIONCONTAINER_H #define MO_CONFIGURATIONCONTAINER_H -#include #include #include +#include namespace MicroOcpp { @@ -37,9 +37,9 @@ class ConfigurationContainer { virtual void loadStaticKey(Configuration& config, const char *key) { } //possible optimization: can replace internal key with passed static key }; -class ConfigurationContainerVolatile : public ConfigurationContainer { +class ConfigurationContainerVolatile : public ConfigurationContainer, public MemoryManaged { private: - std::vector> configurations; + Vector> configurations; public: ConfigurationContainerVolatile(const char *filename, bool accessible); diff --git a/src/MicroOcpp/Core/ConfigurationContainerFlash.cpp b/src/MicroOcpp/Core/ConfigurationContainerFlash.cpp index ccffc9dc..9f83631f 100644 --- a/src/MicroOcpp/Core/ConfigurationContainerFlash.cpp +++ b/src/MicroOcpp/Core/ConfigurationContainerFlash.cpp @@ -6,32 +6,34 @@ #include #include +#include #include #define MAX_CONFIGURATIONS 50 namespace MicroOcpp { -class ConfigurationContainerFlash : public ConfigurationContainer { +class ConfigurationContainerFlash : public ConfigurationContainer, public MemoryManaged { private: - std::vector> configurations; + Vector> configurations; std::shared_ptr filesystem; uint16_t revisionSum = 0; bool loaded = false; - std::vector> keyPool; + Vector keyPool; void clearKeyPool(const char *key) { - keyPool.erase(std::remove_if(keyPool.begin(), keyPool.end(), - [key] (const std::unique_ptr& k) { - #if MO_DBG_LEVEL >= MO_DL_VERBOSE - if (!strcmp(k.get(), key)) { - MO_DBG_VERBOSE("clear key %s", key); - } - #endif - return !strcmp(k.get(), key); - }), keyPool.end()); + auto it = keyPool.begin(); + while (it != keyPool.end()) { + if (!strcmp(*it, key)) { + MO_DBG_VERBOSE("clear key %s", key); + MO_FREE(*it); + it = keyPool.erase(it); + } else { + ++it; + } + } } bool configurationsUpdated() { @@ -46,8 +48,16 @@ class ConfigurationContainerFlash : public ConfigurationContainer { } public: ConfigurationContainerFlash(std::shared_ptr filesystem, const char *filename, bool accessible) : - ConfigurationContainer(filename, accessible), filesystem(filesystem) { } + ConfigurationContainer(filename, accessible), MemoryManaged("v16.Configuration.ContainerFlash.", filename), configurations(makeVector>(getMemoryTag())), filesystem(filesystem), keyPool(makeVector(getMemoryTag())) { } + ~ConfigurationContainerFlash() { + auto it = keyPool.begin(); + while (it != keyPool.end()) { + MO_FREE(*it); + it = keyPool.erase(it); + } + } + bool load() override { if (loaded) { @@ -65,7 +75,7 @@ class ConfigurationContainerFlash : public ConfigurationContainer { return save(); } - auto doc = FilesystemUtils::loadJson(filesystem, getFilename()); + auto doc = FilesystemUtils::loadJson(filesystem, getFilename(), getMemoryTag()); if (!doc) { MO_DBG_ERR("failed to load %s", getFilename()); return false; @@ -110,8 +120,8 @@ class ConfigurationContainerFlash : public ConfigurationContainer { MO_DBG_ERR("corrupt config"); continue; } - - std::unique_ptr key_pooled; + + char *key_pooled = nullptr; auto config = getConfiguration(key).get(); if (config && config->getType() != type) { @@ -120,20 +130,32 @@ class ConfigurationContainerFlash : public ConfigurationContainer { config = nullptr; } if (!config) { - key_pooled.reset(new char[strlen(key) + 1]); - strcpy(key_pooled.get(), key); + #if MO_ENABLE_HEAP_PROFILER + char memoryTag [64]; + snprintf(memoryTag, sizeof(memoryTag), "%s%s", "v16.Configuration.", key); + #else + const char *memoryTag = nullptr; + (void)memoryTag; + #endif + key_pooled = static_cast(MO_MALLOC(memoryTag, strlen(key) + 1)); + if (!key_pooled) { + MO_DBG_ERR("OOM: %s", key); + return false; + } + strcpy(key_pooled, key); } switch (type) { case TConfig::Int: { if (!stored["value"].is()) { MO_DBG_ERR("corrupt config"); + MO_FREE(key_pooled); continue; } int value = stored["value"] | 0; if (!config) { //create new config - config = createConfiguration(TConfig::Int, key_pooled.get()).get(); + config = createConfiguration(TConfig::Int, key_pooled).get(); } if (config) { config->setInt(value); @@ -143,12 +165,13 @@ class ConfigurationContainerFlash : public ConfigurationContainer { case TConfig::Bool: { if (!stored["value"].is()) { MO_DBG_ERR("corrupt config"); + MO_FREE(key_pooled); continue; } bool value = stored["value"] | false; if (!config) { //create new config - config = createConfiguration(TConfig::Bool, key_pooled.get()).get(); + config = createConfiguration(TConfig::Bool, key_pooled).get(); } if (config) { config->setBool(value); @@ -158,12 +181,13 @@ class ConfigurationContainerFlash : public ConfigurationContainer { case TConfig::String: { if (!stored["value"].is()) { MO_DBG_ERR("corrupt config"); + MO_FREE(key_pooled); continue; } const char *value = stored["value"] | ""; if (!config) { //create new config - config = createConfiguration(TConfig::String, key_pooled.get()).get(); + config = createConfiguration(TConfig::String, key_pooled).get(); } if (config) { config->setString(value); @@ -181,6 +205,7 @@ class ConfigurationContainerFlash : public ConfigurationContainer { } } else { MO_DBG_ERR("OOM: %s", key); + MO_FREE(key_pooled); } } @@ -218,7 +243,7 @@ class ConfigurationContainerFlash : public ConfigurationContainer { jsonCapacity = MO_MAX_JSON_CAPACITY; } - DynamicJsonDocument doc {jsonCapacity}; + auto doc = initJsonDoc(getMemoryTag(), jsonCapacity); JsonObject head = doc.createNestedObject("head"); head["content-type"] = "ocpp_config_file"; head["version"] = "2.0"; @@ -267,7 +292,7 @@ class ConfigurationContainerFlash : public ConfigurationContainer { } std::shared_ptr createConfiguration(TConfig type, const char *key) override { - std::shared_ptr res = makeConfiguration(type, key); + auto res = std::shared_ptr(makeConfiguration(type, key).release(), std::default_delete(), makeAllocator("v16.Configuration.", key)); if (!res) { //allocation failure - OOM MO_DBG_ERR("OOM"); diff --git a/src/MicroOcpp/Core/ConfigurationKeyValue.cpp b/src/MicroOcpp/Core/ConfigurationKeyValue.cpp index 9307cd40..033e371a 100644 --- a/src/MicroOcpp/Core/ConfigurationKeyValue.cpp +++ b/src/MicroOcpp/Core/ConfigurationKeyValue.cpp @@ -3,10 +3,10 @@ // MIT License #include +#include #include #include -#include #include #define KEY_MAXLEN 60 @@ -89,7 +89,7 @@ bool Configuration::isReadOnly() { * before its initialization stage. Then the library won't create new config objects but */ -class ConfigInt : public Configuration { +class ConfigInt : public Configuration, public MemoryManaged { private: const char *key = nullptr; int val = 0; @@ -99,6 +99,7 @@ class ConfigInt : public Configuration { bool setKey(const char *key) override { this->key = key; + updateMemoryTag("v16.Configuration.", key); return true; } @@ -120,7 +121,7 @@ class ConfigInt : public Configuration { } }; -class ConfigBool : public Configuration { +class ConfigBool : public Configuration, public MemoryManaged { private: const char *key = nullptr; bool val = false; @@ -130,6 +131,7 @@ class ConfigBool : public Configuration { bool setKey(const char *key) override { this->key = key; + updateMemoryTag("v16.Configuration.", key); return true; } @@ -151,7 +153,7 @@ class ConfigBool : public Configuration { } }; -class ConfigString : public Configuration { +class ConfigString : public Configuration, public MemoryManaged { private: const char *key = nullptr; char *val = nullptr; @@ -162,11 +164,15 @@ class ConfigString : public Configuration { ConfigString& operator=(const ConfigString&) = delete; ~ConfigString() { - free(val); + MO_FREE(val); } bool setKey(const char *key) override { this->key = key; + updateMemoryTag("v16.Configuration.", key); + if (val) { + MO_MEM_SET_TAG(val, getMemoryTag()); + } return true; } @@ -201,12 +207,12 @@ class ConfigString : public Configuration { value_revision++; if (this->val) { - free(this->val); + MO_FREE(this->val); this->val = nullptr; } if (!src_empty) { - this->val = (char*) malloc(size); + this->val = (char*) MO_MALLOC(getMemoryTag(), size); if (!this->val) { return false; } diff --git a/src/MicroOcpp/Core/Configuration_c.cpp b/src/MicroOcpp/Core/Configuration_c.cpp index ef4903e7..f04101f2 100644 --- a/src/MicroOcpp/Core/Configuration_c.cpp +++ b/src/MicroOcpp/Core/Configuration_c.cpp @@ -4,11 +4,12 @@ #include #include +#include #include using namespace MicroOcpp; -class ConfigurationC : public Configuration { +class ConfigurationC : public Configuration, public MemoryManaged { private: ocpp_configuration *config; public: @@ -18,6 +19,7 @@ class ConfigurationC : public Configuration { } bool setKey(const char *key) override { + updateMemoryTag("v16.Configuration.", key); return config->set_key(config->user_data, key); } @@ -114,12 +116,12 @@ class ConfigurationC : public Configuration { } }; -class ConfigurationContainerC : public ConfigurationContainer { +class ConfigurationContainerC : public ConfigurationContainer, public MemoryManaged { private: ocpp_configuration_container *container; public: ConfigurationContainerC(ocpp_configuration_container *container, const char *filename, bool accessible) : - ConfigurationContainer(filename, accessible), container(container) { + ConfigurationContainer(filename, accessible), MemoryManaged("v16.Configuration.ContainerC.", filename), container(container) { } @@ -150,7 +152,7 @@ class ConfigurationContainerC : public ConfigurationContainer { ocpp_configuration *config = container->create_configuration(container->user_data, dt, key); if (config) { - return std::make_shared(config); + return std::allocate_shared(makeAllocator(getMemoryTag()), config); } else { MO_DBG_ERR("could not create config: %s", key); return nullptr; diff --git a/src/MicroOcpp/Core/Connection.cpp b/src/MicroOcpp/Core/Connection.cpp index 21164e4b..ae2ee2fb 100644 --- a/src/MicroOcpp/Core/Connection.cpp +++ b/src/MicroOcpp/Core/Connection.cpp @@ -7,6 +7,8 @@ using namespace MicroOcpp; +LoopbackConnection::LoopbackConnection() : MemoryManaged("WebSocketLoopback") { } + void LoopbackConnection::loop() { } bool LoopbackConnection::sendTXT(const char *msg, size_t length) { @@ -51,7 +53,7 @@ void LoopbackConnection::setConnected(bool connected) { using namespace MicroOcpp::EspWiFi; -WSClient::WSClient(WebSocketsClient *wsock) : wsock(wsock) { +WSClient::WSClient(WebSocketsClient *wsock) : MemoryManaged("WebSocketsClient"), wsock(wsock) { } diff --git a/src/MicroOcpp/Core/Connection.h b/src/MicroOcpp/Core/Connection.h index f1df512f..2c2f7d5c 100644 --- a/src/MicroOcpp/Core/Connection.h +++ b/src/MicroOcpp/Core/Connection.h @@ -8,6 +8,7 @@ #include #include +#include #include //On all platforms other than Arduino, the integrated WS lib (links2004/arduinoWebSockets) cannot be @@ -71,7 +72,7 @@ class Connection { virtual bool isConnected() {return true;} //MO ignores true. This default implementation keeps backwards-compatibility }; -class LoopbackConnection : public Connection { +class LoopbackConnection : public Connection, public MemoryManaged { private: ReceiveTXTcallback receiveTXT; @@ -81,6 +82,8 @@ class LoopbackConnection : public Connection { unsigned long lastRecv = 0; unsigned long lastConn = 0; public: + LoopbackConnection(); + void loop() override; bool sendTXT(const char *msg, size_t length) override; void setReceiveTXTcallback(ReceiveTXTcallback &receiveTXT) override; @@ -102,7 +105,7 @@ class LoopbackConnection : public Connection { namespace MicroOcpp { namespace EspWiFi { -class WSClient : public Connection { +class WSClient : public Connection, public MemoryManaged { private: WebSocketsClient *wsock; unsigned long lastRecv = 0, lastConnected = 0; diff --git a/src/MicroOcpp/Core/Context.cpp b/src/MicroOcpp/Core/Context.cpp index f3efd3ea..1ab65fcb 100644 --- a/src/MicroOcpp/Core/Context.cpp +++ b/src/MicroOcpp/Core/Context.cpp @@ -12,7 +12,7 @@ using namespace MicroOcpp; Context::Context(Connection& connection, std::shared_ptr filesystem, uint16_t bootNr, ProtocolVersion version) - : connection(connection), model{version, bootNr}, reqQueue{connection, operationRegistry} { + : MemoryManaged("Context"), connection(connection), model{version, bootNr}, reqQueue{connection, operationRegistry} { } diff --git a/src/MicroOcpp/Core/Context.h b/src/MicroOcpp/Core/Context.h index eb8c0aef..2df691d1 100644 --- a/src/MicroOcpp/Core/Context.h +++ b/src/MicroOcpp/Core/Context.h @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -18,7 +19,7 @@ namespace MicroOcpp { class Connection; class FilesystemAdapter; -class Context { +class Context : public MemoryManaged { private: Connection& connection; OperationRegistry operationRegistry; diff --git a/src/MicroOcpp/Core/FilesystemAdapter.cpp b/src/MicroOcpp/Core/FilesystemAdapter.cpp index 983d0925..b442e583 100644 --- a/src/MicroOcpp/Core/FilesystemAdapter.cpp +++ b/src/MicroOcpp/Core/FilesystemAdapter.cpp @@ -4,6 +4,7 @@ #include #include //FilesystemOpt +#include #include #include @@ -21,15 +22,13 @@ #if MO_ENABLE_FILE_INDEX -#include #include -#include namespace MicroOcpp { class FilesystemAdapterIndex; -class IndexedFileAdapter : public FileAdapter { +class IndexedFileAdapter : public FileAdapter, public MemoryManaged { private: FilesystemAdapterIndex& index; char fn [MO_MAX_PATH_SIZE]; @@ -38,7 +37,7 @@ class IndexedFileAdapter : public FileAdapter { size_t written = 0; public: IndexedFileAdapter(FilesystemAdapterIndex& index, const char *fn, std::unique_ptr file) - : index(index), file(std::move(file)) { + : MemoryManaged("FilesystemIndex"), index(index), file(std::move(file)) { snprintf(this->fn, sizeof(this->fn), "%s", fn); } @@ -65,18 +64,18 @@ class IndexedFileAdapter : public FileAdapter { } }; -class FilesystemAdapterIndex : public FilesystemAdapter { +class FilesystemAdapterIndex : public FilesystemAdapter, public MemoryManaged { private: std::shared_ptr filesystem; struct IndexEntry { - std::string fname; + String fname; size_t size; - IndexEntry(const char *fname, size_t size) : fname(fname), size(size) { } + IndexEntry(const char *fname, size_t size) : fname(makeString("FilesystemIndex", fname)), size(size) { } }; - std::vector index; + Vector index; IndexEntry *getEntryByFname(const char *fn) { auto entry = std::find_if(index.begin(), index.end(), @@ -100,10 +99,16 @@ class FilesystemAdapterIndex : public FilesystemAdapter { const char *fn = path + sizeof(MO_FILENAME_PREFIX) - 1; return getEntryByFname(fn); } + + void (*onDestruct)(void*) = nullptr; public: - FilesystemAdapterIndex(std::shared_ptr filesystem) : filesystem(std::move(filesystem)) { } + FilesystemAdapterIndex(std::shared_ptr filesystem, void (*onDestruct)(void*) = nullptr) : MemoryManaged("FilesystemIndex"), filesystem(std::move(filesystem)), index(makeVector("FilesystemIndex")), onDestruct(onDestruct) { } - ~FilesystemAdapterIndex() = default; + ~FilesystemAdapterIndex() { + if (onDestruct) { + onDestruct(this); + } + } int stat(const char *path, size_t *size) override { if (auto file = getEntryByPath(path)) { @@ -227,9 +232,9 @@ IndexedFileAdapter::~IndexedFileAdapter() { index.updateFilesize(fn, written); } -std::shared_ptr decorateIndex(std::shared_ptr filesystem) { +std::shared_ptr decorateIndex(std::shared_ptr filesystem, void (*onDestruct)(void*) = nullptr) { - auto fsIndex = std::make_shared(std::move(filesystem)); + auto fsIndex = std::allocate_shared(makeAllocator("FilesystemIndex"), std::move(filesystem), onDestruct); if (!fsIndex) { MO_DBG_ERR("OOM"); return nullptr; @@ -260,10 +265,10 @@ std::shared_ptr decorateIndex(std::shared_ptr filesystemCache; +void resetFilesystemCache(void*) { + filesystemCache.reset(); +} + std::shared_ptr makeDefaultFilesystemAdapter(FilesystemOpt config) { if (auto cached = filesystemCache.lock()) { @@ -438,11 +453,11 @@ std::shared_ptr makeDefaultFilesystemAdapter(FilesystemOpt co return nullptr; } - auto fs_concrete = new ArduinoFilesystemAdapter(config); - auto fs = std::shared_ptr(fs_concrete); + auto fs_concrete = new ArduinoFilesystemAdapter(config, resetFilesystemCache); + auto fs = std::shared_ptr(fs_concrete, std::default_delete(), makeAllocator("Filesystem")); #if MO_ENABLE_FILE_INDEX - fs = decorateIndex(fs); + fs = decorateIndex(fs, resetFilesystemCache); #endif // MO_ENABLE_FILE_INDEX filesystemCache = fs; @@ -468,10 +483,10 @@ std::shared_ptr makeDefaultFilesystemAdapter(FilesystemOpt co namespace MicroOcpp { -class EspIdfFileAdapter : public FileAdapter { +class EspIdfFileAdapter : public FileAdapter, public MemoryManaged { FILE *file {nullptr}; public: - EspIdfFileAdapter(FILE *file) : file(file) {} + EspIdfFileAdapter(FILE *file) : MemoryManaged("Filesystem"), file(file) {} ~EspIdfFileAdapter() { fclose(file); @@ -494,17 +509,23 @@ class EspIdfFileAdapter : public FileAdapter { } }; -class EspIdfFilesystemAdapter : public FilesystemAdapter { +class EspIdfFilesystemAdapter : public FilesystemAdapter, public MemoryManaged { public: FilesystemOpt config; + + void (* onDestruct)(void*) = nullptr; public: - EspIdfFilesystemAdapter(FilesystemOpt config) : config(config) { } + EspIdfFilesystemAdapter(FilesystemOpt config, void (* onDestruct)(void*) = nullptr) : MemoryManaged("Filesystem"), config(config), onDestruct(onDestruct) { } ~EspIdfFilesystemAdapter() { if (config.mustMount()) { esp_vfs_spiffs_unregister(MO_PARTITION_LABEL); MO_DBG_DEBUG("SPIFFS unmounted"); } + + if (onDestruct) { + onDestruct(this); + } } int stat(const char *path, size_t *size) override { @@ -565,6 +586,10 @@ class EspIdfFilesystemAdapter : public FilesystemAdapter { std::weak_ptr filesystemCache; +void resetFilesystemCache(void*) { + filesystemCache.reset(); +} + std::shared_ptr makeDefaultFilesystemAdapter(FilesystemOpt config) { if (auto cached = filesystemCache.lock()) { @@ -620,10 +645,10 @@ std::shared_ptr makeDefaultFilesystemAdapter(FilesystemOpt co } if (mounted) { - auto fs = std::shared_ptr(new EspIdfFilesystemAdapter(config)); + auto fs = std::shared_ptr(new EspIdfFilesystemAdapter(config, resetFilesystemCache), std::default_delete(), makeAllocator("Filesystem")); #if MO_ENABLE_FILE_INDEX - fs = decorateIndex(fs); + fs = decorateIndex(fs, resetFilesystemCache); #endif // MO_ENABLE_FILE_INDEX filesystemCache = fs; @@ -643,10 +668,10 @@ std::shared_ptr makeDefaultFilesystemAdapter(FilesystemOpt co namespace MicroOcpp { -class PosixFileAdapter : public FileAdapter { +class PosixFileAdapter : public FileAdapter, public MemoryManaged { FILE *file {nullptr}; public: - PosixFileAdapter(FILE *file) : file(file) {} + PosixFileAdapter(FILE *file) : MemoryManaged("Filesystem"), file(file) {} ~PosixFileAdapter() { fclose(file); @@ -669,13 +694,19 @@ class PosixFileAdapter : public FileAdapter { } }; -class PosixFilesystemAdapter : public FilesystemAdapter { +class PosixFilesystemAdapter : public FilesystemAdapter, public MemoryManaged { public: FilesystemOpt config; + + void (* onDestruct)(void*) = nullptr; public: - PosixFilesystemAdapter(FilesystemOpt config) : config(config) { } + PosixFilesystemAdapter(FilesystemOpt config, void (* onDestruct)(void*) = nullptr) : MemoryManaged("Filesystem"), config(config), onDestruct(onDestruct) { } - ~PosixFilesystemAdapter() = default; + ~PosixFilesystemAdapter() { + if (onDestruct) { + onDestruct(this); + } + } int stat(const char *path, size_t *size) override { struct ::stat st; @@ -725,6 +756,10 @@ class PosixFilesystemAdapter : public FilesystemAdapter { std::weak_ptr filesystemCache; +void resetFilesystemCache(void*) { + filesystemCache.reset(); +} + std::shared_ptr makeDefaultFilesystemAdapter(FilesystemOpt config) { if (auto cached = filesystemCache.lock()) { @@ -740,10 +775,10 @@ std::shared_ptr makeDefaultFilesystemAdapter(FilesystemOpt co MO_DBG_DEBUG("Skip mounting on UNIX host"); } - auto fs = std::shared_ptr(new PosixFilesystemAdapter(config)); + auto fs = std::shared_ptr(new PosixFilesystemAdapter(config, resetFilesystemCache), std::default_delete(), makeAllocator("Filesystem")); #if MO_ENABLE_FILE_INDEX - fs = decorateIndex(fs); + fs = decorateIndex(fs, resetFilesystemCache); #endif // MO_ENABLE_FILE_INDEX filesystemCache = fs; diff --git a/src/MicroOcpp/Core/FilesystemUtils.cpp b/src/MicroOcpp/Core/FilesystemUtils.cpp index a6bd916c..de6a034d 100644 --- a/src/MicroOcpp/Core/FilesystemUtils.cpp +++ b/src/MicroOcpp/Core/FilesystemUtils.cpp @@ -9,7 +9,7 @@ using namespace MicroOcpp; -std::unique_ptr FilesystemUtils::loadJson(std::shared_ptr filesystem, const char *fn) { +std::unique_ptr FilesystemUtils::loadJson(std::shared_ptr filesystem, const char *fn, const char *memoryTag) { if (!filesystem || !fn || *fn == '\0') { MO_DBG_ERR("Format error"); return nullptr; @@ -50,13 +50,13 @@ std::unique_ptr FilesystemUtils::loadJson(std::shared_ptr(nullptr); + std::unique_ptr doc; DeserializationError err = DeserializationError::NoMemory; ArduinoJsonFileAdapter fileReader {file.get()}; while (err == DeserializationError::NoMemory && capacity <= MO_MAX_JSON_CAPACITY) { - doc.reset(new DynamicJsonDocument(capacity)); + doc = makeJsonDoc(memoryTag, capacity); err = deserializeJson(*doc, fileReader); capacity *= 2; @@ -75,7 +75,7 @@ std::unique_ptr FilesystemUtils::loadJson(std::shared_ptr filesystem, const char *fn, const DynamicJsonDocument& doc) { +bool FilesystemUtils::storeJson(std::shared_ptr filesystem, const char *fn, const JsonDoc& doc) { if (!filesystem || !fn || *fn == '\0') { MO_DBG_ERR("Format error"); return false; diff --git a/src/MicroOcpp/Core/FilesystemUtils.h b/src/MicroOcpp/Core/FilesystemUtils.h index 962ca353..31a36a73 100644 --- a/src/MicroOcpp/Core/FilesystemUtils.h +++ b/src/MicroOcpp/Core/FilesystemUtils.h @@ -6,6 +6,7 @@ #define MO_FILESYSTEMUTILS_H #include +#include #include #include @@ -36,8 +37,8 @@ class ArduinoJsonFileAdapter { namespace FilesystemUtils { -std::unique_ptr loadJson(std::shared_ptr filesystem, const char *fn); -bool storeJson(std::shared_ptr filesystem, const char *fn, const DynamicJsonDocument& doc); +std::unique_ptr loadJson(std::shared_ptr filesystem, const char *fn, const char *memoryTag = nullptr); +bool storeJson(std::shared_ptr filesystem, const char *fn, const JsonDoc& doc); bool remove_if(std::shared_ptr filesystem, std::function pred); diff --git a/src/MicroOcpp/Core/FtpMbedTLS.cpp b/src/MicroOcpp/Core/FtpMbedTLS.cpp index dac7bbe4..b40015b9 100644 --- a/src/MicroOcpp/Core/FtpMbedTLS.cpp +++ b/src/MicroOcpp/Core/FtpMbedTLS.cpp @@ -6,7 +6,6 @@ #if MO_ENABLE_MBEDTLS -#include #include #include @@ -17,11 +16,12 @@ #include "mbedtls/x509.h" #include "mbedtls/error.h" +#include #include namespace MicroOcpp { -class FtpTransferMbedTLS : public FtpUpload, public FtpDownload { +class FtpTransferMbedTLS : public FtpUpload, public FtpDownload, public MemoryManaged { private: //MbedTLS common mbedtls_entropy_context entropy; @@ -49,15 +49,15 @@ class FtpTransferMbedTLS : public FtpUpload, public FtpDownload { bool data_conn_accepted = false; //Server sent okay to upload / download data //FTP URL - std::string user; - std::string pass; - std::string ctrl_host; - std::string ctrl_port; - std::string dir; - std::string fname; + String user; + String pass; + String ctrl_host; + String ctrl_port; + String dir; + String fname; - std::string data_host; - std::string data_port; + String data_host; + String data_port; bool read_url_ctrl(const char *ftp_url); bool read_url_data(const char *data_url); @@ -111,7 +111,7 @@ class FtpTransferMbedTLS : public FtpUpload, public FtpDownload { const char *ca_cert = nullptr); // nullptr to disable cert check; will be ignored for non-TLS connections }; -class FtpClientMbedTLS : public FtpClient { +class FtpClientMbedTLS : public FtpClient, public MemoryManaged { private: const char *client_cert = nullptr; const char *client_key = nullptr; @@ -163,8 +163,20 @@ void mo_mbedtls_log(void *user, int level, const char *file, int line, const cha * FTP implementation */ -FtpTransferMbedTLS::FtpTransferMbedTLS(bool tls_only, const char *client_cert, const char *client_key) - : client_cert(client_cert), client_key(client_key), isSecure(tls_only) { +FtpTransferMbedTLS::FtpTransferMbedTLS(bool tls_only, const char *client_cert, const char *client_key) : + MemoryManaged("FTP.TransferMbedTLS"), + client_cert(client_cert), + client_key(client_key), + isSecure(tls_only), + user(makeString(getMemoryTag())), + pass(makeString(getMemoryTag())), + ctrl_host(makeString(getMemoryTag())), + ctrl_port(makeString(getMemoryTag())), + dir(makeString(getMemoryTag())), + fname(makeString(getMemoryTag())), + data_host(makeString(getMemoryTag())), + data_port(makeString(getMemoryTag())) { + mbedtls_net_init(&ctrl_fd); mbedtls_ssl_init(&ctrl_ssl); mbedtls_net_init(&data_fd); @@ -182,7 +194,7 @@ FtpTransferMbedTLS::~FtpTransferMbedTLS() { onClose(MO_FtpCloseReason_Failure); //data connection not closed properly onClose = nullptr; } - delete[] data_buf; + MO_FREE(data_buf); mbedtls_x509_crt_free(&clicert); mbedtls_x509_crt_free(&cacert); mbedtls_pk_free(&pkey); @@ -319,11 +331,12 @@ int FtpTransferMbedTLS::connect_data() { } if (!data_buf) { - data_buf = new unsigned char[data_buf_size]; + data_buf = static_cast(MO_MALLOC(getMemoryTag(), data_buf_size)); if (!data_buf) { MO_DBG_ERR("OOM"); return -1; } + memset(data_buf, 0, data_buf_size); } return 0; //success @@ -779,7 +792,7 @@ bool FtpTransferMbedTLS::isActive() { } bool FtpTransferMbedTLS::read_url_ctrl(const char *ftp_url_raw) { - std::string ftp_url = ftp_url_raw; //copy input ftp_url + String ftp_url = makeString(getMemoryTag(), ftp_url_raw); //copy input ftp_url //tolower protocol specifier for (auto c = ftp_url.begin(); *c != ':' && c != ftp_url.end(); c++) { @@ -787,7 +800,7 @@ bool FtpTransferMbedTLS::read_url_ctrl(const char *ftp_url_raw) { } //parse FTP URL: protocol specifier - std::string proto; + String proto = makeString(getMemoryTag()); if (!strncmp(ftp_url.c_str(), "ftps://", strlen("ftps://"))) { //FTP over TLS (RFC 4217) proto = "ftps://"; @@ -802,7 +815,7 @@ bool FtpTransferMbedTLS::read_url_ctrl(const char *ftp_url_raw) { //parse FTP URL: dir and fname auto dir_pos = ftp_url.find_first_of('/', proto.length()); - if (dir_pos != std::string::npos) { + if (dir_pos != String::npos) { auto fname_pos = ftp_url.find_last_of('/'); dir = ftp_url.substr(dir_pos, fname_pos - dir_pos); fname = ftp_url.substr(fname_pos + 1); @@ -817,10 +830,11 @@ bool FtpTransferMbedTLS::read_url_ctrl(const char *ftp_url_raw) { //parse FTP URL: user, pass, host, port - std::string user_pass_host_port = ftp_url.substr(proto.length(), dir_pos - proto.length()); - std::string user_pass, host_port; + String user_pass_host_port = ftp_url.substr(proto.length(), dir_pos - proto.length()); + String user_pass = makeString(getMemoryTag()); + String host_port = makeString(getMemoryTag()); auto user_pass_delim = user_pass_host_port.find_first_of('@'); - if (user_pass_delim != std::string::npos) { + if (user_pass_delim != String::npos) { host_port = user_pass_host_port.substr(user_pass_delim + 1); user_pass = user_pass_host_port.substr(0, user_pass_delim); } else { @@ -829,7 +843,7 @@ bool FtpTransferMbedTLS::read_url_ctrl(const char *ftp_url_raw) { if (!user_pass.empty()) { auto user_delim = user_pass.find_first_of(':'); - if (user_delim != std::string::npos) { + if (user_delim != String::npos) { user = user_pass.substr(0, user_delim); pass = user_pass.substr(user_delim + 1); } else { @@ -845,7 +859,7 @@ bool FtpTransferMbedTLS::read_url_ctrl(const char *ftp_url_raw) { } auto host_port_delim = host_port.find(':'); - if (host_port_delim != std::string::npos) { + if (host_port_delim != String::npos) { ctrl_host = host_port.substr(0, host_port_delim); ctrl_port = host_port.substr(host_port_delim + 1); } else { @@ -861,7 +875,7 @@ bool FtpTransferMbedTLS::read_url_ctrl(const char *ftp_url_raw) { bool FtpTransferMbedTLS::read_url_data(const char *data_url_raw) { - std::string data_url = data_url_raw; //format like " Entering Passive Mode (h1,h2,h3,h4,p1,p2)" + String data_url = makeString(getMemoryTag(), data_url_raw); //format like " Entering Passive Mode (h1,h2,h3,h4,p1,p2)" // parse address field. Replace all non-digits by delimiter character ' ' for (char& c : data_url) { @@ -899,7 +913,7 @@ bool FtpTransferMbedTLS::read_url_data(const char *data_url_raw) { } FtpClientMbedTLS::FtpClientMbedTLS(bool tls_only, const char *client_cert, const char *client_key) - : client_cert(client_cert), client_key(client_key), tls_only(tls_only) { + : MemoryManaged("FTP.ClientMbedTLS"), client_cert(client_cert), client_key(client_key), tls_only(tls_only) { } diff --git a/src/MicroOcpp/Core/Memory.cpp b/src/MicroOcpp/Core/Memory.cpp new file mode 100644 index 00000000..26500b2b --- /dev/null +++ b/src/MicroOcpp/Core/Memory.cpp @@ -0,0 +1,294 @@ +// matth-x/MicroOcpp +// Copyright Matthias Akstaller 2019 - 2024 +// MIT License + +#include +#include + +#if MO_OVERRIDE_ALLOCATION && MO_ENABLE_HEAP_PROFILER + +#include + +namespace MicroOcpp { +namespace Memory { + +struct MemBlockInfo { + void* tagger_ptr = nullptr; + std::string tag; + size_t size = 0; + + MemBlockInfo(void* ptr, const char *tag, size_t size) : size{size} { + updateTag(ptr, tag); + } + + void updateTag(void* ptr, const char *tag); +}; + +std::map memBlocks; //key: memory address of malloc'd block + +struct MemTagInfo { + size_t current_size = 0; + size_t max_size = 0; + + MemTagInfo(size_t size) { + operator+=(size); + } + + void operator+=(size_t size) { + current_size += size; + max_size = std::max(max_size, current_size); + } + + void operator-=(size_t size) { + if (size > current_size) { + MO_DBG_ERR("captured size does not fit"); + //return; let it happen for now + } + current_size -= size; + } + + void reset() { + max_size = current_size; + } +}; + +std::map memTags; + +size_t memTotal, memTotalMax; + +void MemBlockInfo::updateTag(void* ptr, const char *tag) { + if (!tag) { + return; + } + if (tagger_ptr == nullptr || ptr < tagger_ptr) { + MO_DBG_VERBOSE("update tag from %s to %s, ptr from %p to %p", this->tag.c_str(), tag, tagger_ptr, ptr); + + auto tagInfo = memTags.find(this->tag); + if (tagInfo != memTags.end()) { + tagInfo->second -= size; + } + + tagInfo = memTags.find(tag); + if (tagInfo != memTags.end()) { + tagInfo->second += size; + } else { + memTags.emplace(tag, size); + } + + tagger_ptr = ptr; + this->tag = tag; + } +} + +} //namespace Memory +} //namespace MicroOcpp + +#endif //MO_OVERRIDE_ALLOCATION && MO_ENABLE_HEAP_PROFILER + +#if MO_OVERRIDE_ALLOCATION + +namespace MicroOcpp { +namespace Memory { + +void* (*malloc_override)(size_t); +void (*free_override)(void*); + +} +} + +using namespace MicroOcpp::Memory; + +void mo_mem_set_malloc_free(void* (*malloc_override)(size_t), void (*free_override)(void*)) { + MicroOcpp::Memory::malloc_override = malloc_override; + MicroOcpp::Memory::free_override = free_override; +} + +void *mo_mem_malloc(const char *tag, size_t size) { + MO_DBG_VERBOSE("malloc %zu B (%s)", size, tag ? tag : "unspecified"); + + void *ptr; + if (malloc_override) { + ptr = malloc_override(size); + } else { + ptr = malloc(size); + } + + #if MO_ENABLE_HEAP_PROFILER + if (ptr) { + memBlocks.emplace(ptr, MemBlockInfo(ptr, tag, size)); + + memTotal += size; + memTotalMax = std::max(memTotalMax, memTotal); + } + #endif + return ptr; +} + +void mo_mem_free(void* ptr) { + MO_DBG_VERBOSE("free"); + + #if MO_ENABLE_HEAP_PROFILER + if (ptr) { + + auto blockInfo = memBlocks.find(ptr); + if (blockInfo != memBlocks.end()) { + auto tagInfo = memTags.find(blockInfo->second.tag); + if (tagInfo != memTags.end()) { + tagInfo->second -= blockInfo->second.size; + } + memTotal -= blockInfo->second.size; + } + + if (blockInfo != memBlocks.end()) { + memBlocks.erase(blockInfo); + } + } + #endif + + if (free_override) { + free_override(ptr); + } else { + free(ptr); + } +} + +#endif //MO_OVERRIDE_ALLOCATION + +#if MO_OVERRIDE_ALLOCATION && MO_ENABLE_HEAP_PROFILER + +void mo_mem_deinit() { + memBlocks.clear(); + memTags.clear(); +} + +void mo_mem_reset() { + MO_DBG_DEBUG("Reset all maximum values to current values"); + + auto tagInfo = memTags.begin(); + if (tagInfo != memTags.end()) { + tagInfo->second.reset(); + } + + memTotalMax = memTotal; +} + +void mo_mem_set_tag(void *ptr, const char *tag) { + MO_DBG_VERBOSE("set tag (%s)", tag ? tag : "unspecified"); + + if (!tag) { + return; + } + + bool hasTagged = false; + + if (tag) { + auto foundBlock = memBlocks.upper_bound(ptr); + if (foundBlock != memBlocks.begin()) { + --foundBlock; + } + if (foundBlock != memBlocks.end() && + (unsigned char*)ptr - (unsigned char*)foundBlock->first < (std::ptrdiff_t)foundBlock->second.size) { + foundBlock->second.updateTag(ptr, tag); + hasTagged = true; + } + } + + if (!hasTagged) { + MO_DBG_VERBOSE("memory area doesn't apply"); + } +} + +void mo_mem_print_stats() { + + MO_CONSOLE_PRINTF("\n *** Heap usage statistics ***\n"); + + size_t size = 0; + + size_t untagged = 0, untagged_size = 0; + + for (const auto& heapEntry : memBlocks) { + size += heapEntry.second.size; + #if MO_DBG_LEVEL >= MO_DL_DEBUG + { + MO_CONSOLE_PRINTF("@%p - %zu B (%s)\n", heapEntry.first, heapEntry.second.size, heapEntry.second.tag.c_str()); + } + #endif + + if (heapEntry.second.tag.empty()) { + untagged ++; + untagged_size += heapEntry.second.size; + } + } + + std::map tags; + for (const auto& heapEntry : memBlocks) { + auto foundTag = tags.find(heapEntry.second.tag); + if (foundTag != tags.end()) { + foundTag->second += heapEntry.second.size; + } else { + tags.emplace(heapEntry.second.tag, heapEntry.second.size); + } + } + + size_t size_control = 0; + + for (const auto& tag : tags) { + size_control += tag.second; + #if MO_DBG_LEVEL >= MO_DL_VERBOSE + { + MO_CONSOLE_PRINTF("%s - %zu B\n", tag.first.c_str(), tag.second); + } + #endif + } + + size_t size_control2 = 0; + for (const auto& tag : memTags) { + size_control2 += tag.second.current_size; + MO_CONSOLE_PRINTF("%s - %zu B (max. %zu B)\n", tag.first.c_str(), tag.second.current_size, tag.second.max_size); + } + + MO_CONSOLE_PRINTF(" *** Summary ***\nBlocks: %zu\nTags: %zu\nCurrent usage: %zu B\nMaximum usage: %zu B\n", memBlocks.size(), memTags.size(), memTotal, memTotalMax); + #if MO_DBG_LEVEL >= MO_DL_DEBUG + { + MO_CONSOLE_PRINTF(" *** Debug information ***\nTotal blocks (control value 1): %zu B\nTags (control value): %zu\nTotal tagged (control value 2): %zu B\nTotal tagged (control value 3): %zu B\nUntagged: %zu\nTotal untagged: %zu B\n", size, tags.size(), size_control, size_control2, untagged, untagged_size); + } + #endif +} + +#endif //MO_OVERRIDE_ALLOCATION && MO_ENABLE_HEAP_PROFILER + +namespace MicroOcpp { + +String makeString(const char *tag, const char *val) { +#if MO_OVERRIDE_ALLOCATION + if (val) { + return String(val, Allocator(tag)); + } else { + return String(Allocator(tag)); + } +#else + if (val) { + return String(val); + } else { + return String(); + } +#endif +} + +JsonDoc initJsonDoc(const char *tag, size_t capacity) { +#if MO_OVERRIDE_ALLOCATION + return JsonDoc(capacity, ArduinoJsonAllocator(tag)); +#else + return JsonDoc(capacity); +#endif +} + +std::unique_ptr makeJsonDoc(const char *tag, size_t capacity) { +#if MO_OVERRIDE_ALLOCATION + return std::unique_ptr(new JsonDoc(capacity, ArduinoJsonAllocator(tag))); +#else + return std::unique_ptr(new JsonDoc(capacity)); +#endif +} + +} diff --git a/src/MicroOcpp/Core/Memory.h b/src/MicroOcpp/Core/Memory.h new file mode 100644 index 00000000..bca25a84 --- /dev/null +++ b/src/MicroOcpp/Core/Memory.h @@ -0,0 +1,444 @@ +// matth-x/MicroOcpp +// Copyright Matthias Akstaller 2019 - 2024 +// MIT License + +#ifndef MO_MEMORY_H +#define MO_MEMORY_H + +#include + +#ifndef MO_OVERRIDE_ALLOCATION +#define MO_OVERRIDE_ALLOCATION 0 +#endif + +#ifndef MO_ENABLE_EXTERNAL_RAM +#define MO_ENABLE_EXTERNAL_RAM 0 +#endif + +#ifndef MO_ENABLE_HEAP_PROFILER +#define MO_ENABLE_HEAP_PROFILER 0 +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +#if MO_OVERRIDE_ALLOCATION + +void mo_mem_set_malloc_free(void* (*malloc_override)(size_t), void (*free_override)(void*)); //pass custom malloc and free function to be used with the OCPP lib. If not set or NULL, defaults to standard malloc + +void *mo_mem_malloc(const char *tag, size_t size); + +void mo_mem_free(void* ptr); + +#define MO_MALLOC mo_mem_malloc +#define MO_FREE mo_mem_free + +#else +#define MO_MALLOC(TAG, SIZE) malloc(SIZE) //default malloc provided by host system +#define MO_FREE(PTR) free(PTR) //default free provided by host system +#endif //MO_OVERRIDE_ALLOCATION + + +#if MO_OVERRIDE_ALLOCATION && MO_ENABLE_HEAP_PROFILER + +void mo_mem_deinit(); //release allocated memory and deinit +void mo_mem_reset(); //reset maximum heap occuption + +void mo_mem_set_tag(void *ptr, const char *tag); + +void mo_mem_get_current_heap(const char *tag); +void mo_mem_get_maximum_heap(const char *tag); +void mo_mem_get_current_heap_by_tag(const char *tag); +void mo_mem_get_maximum_heap_by_tag(const char *tag); + +int mo_mem_write_stats_json(char *buf, size_t size); + +void mo_mem_print_stats(); + +#define MO_MEM_DEINIT mo_mem_deinit +#define MO_MEM_RESET mo_mem_reset +#define MO_MEM_SET_TAG mo_mem_set_tag +#define MO_MEM_PRINT_STATS mo_mem_print_stats + +#else +#define MO_MEM_DEINIT(...) (void)0 +#define MO_MEM_RESET(...) (void)0 +#define MO_MEM_SET_TAG(...) (void)0 +#define MO_MEM_PRINT_STATS(...) (void)0 +#endif //MO_OVERRIDE_ALLOCATION && MO_ENABLE_HEAP_PROFILER + + +#if MO_ENABLE_EXTERNAL_RAM + +void mo_mem_set_malloc_free_ext(void* (*malloc_override)(size_t), void (*free_override)(void*)); //pass malloc and free function to external RAM to be used with the OCPP lib. If not set or NULL, defaults to standard malloc + +void *mo_mem_malloc_ext(const char *tag, size_t size); + +void mo_mem_free_ext(void* ptr); + +#define MO_MALLOC_EXT(TAG, SIZE) mo_mem_malloc_ext(TAG, SIZE) +#define MO_FREE_EXT(PTR) mo_mem_free_ext(PTR) + +#else +#define MO_MALLOC_EXT MO_MALLOC +#define MO_FREE_EXT MO_FREE +#endif //MO_ENABLE_EXTERNAL_RAM + + +#ifdef __cplusplus +} + + +#include +#include +#include + +#include + +#if MO_OVERRIDE_ALLOCATION + +#include + +namespace MicroOcpp { + +class MemoryManaged { +private: + #if MO_ENABLE_HEAP_PROFILER + char *tag = nullptr; + #endif +protected: + void updateMemoryTag(const char *src1, const char *src2 = nullptr) { + #if MO_ENABLE_HEAP_PROFILER + if (!src1 && !src2) { + //empty source does not update tag + return; + } + char src [64]; + snprintf(src, sizeof(src), "%s%s", src1 ? src1 : "", src2 ? src2 : ""); + if (tag) { + if (!strcmp(src, tag)) { + //nothing to do + return; + } + MO_FREE(tag); + tag = nullptr; + } + size_t size = strlen(src) + 1; + tag = static_cast(malloc(size)); //heap profiler bypasses custom malloc to not count into the statistics + memset(tag, 0, size); + snprintf(tag, size, "%s", src); + mo_mem_set_tag(this, tag); + #else + (void)src1; + (void)src2; + #endif + } + const char *getMemoryTag() const { + #if MO_ENABLE_HEAP_PROFILER + return tag; + #else + return nullptr; + #endif + } +public: + void *operator new(size_t size) { + return MO_MALLOC(nullptr, size); + } + void operator delete(void * ptr) { + MO_FREE(ptr); + } + + MemoryManaged(const char *tag = nullptr, const char *tag_suffix = nullptr) { + #if MO_ENABLE_HEAP_PROFILER + updateMemoryTag(tag, tag_suffix); + #endif + } + + MemoryManaged(MemoryManaged&& other) { + #if MO_ENABLE_HEAP_PROFILER + tag = other.tag; + other.tag = nullptr; + #endif + } + + ~MemoryManaged() { + #if MO_ENABLE_HEAP_PROFILER + MO_FREE(tag); + tag = nullptr; + #endif + } + + void operator=(const MemoryManaged& other) { + #if MO_ENABLE_HEAP_PROFILER + updateMemoryTag(other.tag); + #endif + } +}; + +template +struct Allocator { + + Allocator(const char *tag = nullptr, const char *tag_suffix = nullptr) { + #if MO_ENABLE_HEAP_PROFILER + updateMemoryTag(tag, tag_suffix); + #endif + } + + template + Allocator(const Allocator& other) { + #if MO_ENABLE_HEAP_PROFILER + updateMemoryTag(other.tag); + #endif + } + + Allocator(const Allocator& other) { + #if MO_ENABLE_HEAP_PROFILER + updateMemoryTag(other.tag); + #endif + } + + //template + //Allocator(Allocator&& other) { + Allocator(Allocator&& other) { + #if MO_ENABLE_HEAP_PROFILER + updateMemoryTag(other.tag); //ignore move semantics for allocators as it simplifies moving std::vector>. This is okay because the Allocator's state is only the memory tag which is not exclusively owned + #endif + } + + ~Allocator() { + #if MO_ENABLE_HEAP_PROFILER + if (tag) { + //MO_FREE(tag); + free(tag); + tag = nullptr; + } + #endif + } + + T *allocate(size_t count) { + #if MO_ENABLE_HEAP_PROFILER + return static_cast(MO_MALLOC(tag, sizeof(T) * count)); + #else + return static_cast(MO_MALLOC(nullptr, sizeof(T) * count)); + #endif + } + + void deallocate(T *ptr, size_t count) { + MO_FREE(ptr); + } + + bool operator==(const Allocator& other) { + #if MO_ENABLE_HEAP_PROFILER + if (!tag && !other.tag) { + return true; + } else if (tag && other.tag) { + return !strcmp(tag, other.tag); + } else { + return false; + } + #else + return true; + #endif + } + + bool operator!=(const Allocator& other) { + return !operator==(other); + } + + typedef T value_type; + + #if MO_ENABLE_HEAP_PROFILER + char *tag = nullptr; + + void updateMemoryTag(const char *src1, const char *src2 = nullptr) { + if (!src1 && !src2) { + //empty source does not update tag + return; + } + char src [64]; + snprintf(src, sizeof(src), "%s%s", src1 ? src1 : "", src2 ? src2 : ""); + if (tag) { + if (!strcmp(src, tag)) { + //nothing to do + return; + } + //MO_FREE(tag); + free(tag); + tag = nullptr; + } + size_t size = strlen(src) + 1; + tag = static_cast(malloc(size)); + memset(tag, 0, size); + snprintf(tag, size, "%s", src); + } + #endif +}; + +template +Allocator makeAllocator(const char *tag, const char *tag_suffix = nullptr) { + return Allocator(tag, tag_suffix); +} + +using String = std::basic_string, MicroOcpp::Allocator>; + +template +using Vector = std::vector>; + +template +Vector makeVector(const char *tag) { + return Vector(Allocator(tag)); +} + +class ArduinoJsonAllocator { +private: + #if MO_ENABLE_HEAP_PROFILER + char *tag = nullptr; + + void updateMemoryTag(const char *src1, const char *src2 = nullptr) { + if (!src1 && !src2) { + //empty source does not update tag + return; + } + char src [64]; + snprintf(src, sizeof(src), "%s%s", src1 ? src1 : "", src2 ? src2 : ""); + if (tag) { + if (!strcmp(src, tag)) { + //nothing to do + return; + } + MO_FREE(tag); + tag = nullptr; + } + size_t size = strlen(src) + 1; + //tag = static_cast(MO_MALLOC("HeapProfilerInternal", size)); + tag = static_cast(malloc(size)); + memset(tag, 0, size); + snprintf(tag, size, "%s", src); + } + #endif +public: + + ArduinoJsonAllocator(const char *tag = nullptr, const char *tag_suffix = nullptr) { + #if MO_ENABLE_HEAP_PROFILER + updateMemoryTag(tag, tag_suffix); + #endif + } + + ArduinoJsonAllocator(const ArduinoJsonAllocator& other) { + #if MO_ENABLE_HEAP_PROFILER + updateMemoryTag(other.tag); + #endif + } + + ArduinoJsonAllocator(ArduinoJsonAllocator&& other) { + #if MO_ENABLE_HEAP_PROFILER + tag = other.tag; + other.tag = nullptr; + #endif + } + + ~ArduinoJsonAllocator() { + #if MO_ENABLE_HEAP_PROFILER + if (tag) { + MO_FREE(tag); + tag = nullptr; + } + #endif + } + + void *allocate(size_t size) { + #if MO_ENABLE_HEAP_PROFILER + return MO_MALLOC(tag, size); + #else + return MO_MALLOC(nullptr, size); + #endif + } + void deallocate(void *ptr) { + MO_FREE(ptr); + } +}; + +using JsonDoc = BasicJsonDocument; + +template +T *mo_mem_new(const char *tag, Args&& ...args) { + if (auto ptr = MO_MALLOC(tag, sizeof(T))) { + return new(ptr) T(std::forward(args)...); + } + return nullptr; //OOM +} + +template +void mo_mem_delete(T *ptr) { + if (ptr) { + ptr->~T(); + MO_FREE(ptr); + } +} + +} //namespace MicroOcpp + +#else + +#include + +namespace MicroOcpp { + +class MemoryManaged { +protected: + const char *getMemoryTag() const {return nullptr;} + void updateMemoryTag(const char*,const char*) { } +public: + MemoryManaged() { } + MemoryManaged(const char*) { } + MemoryManaged(const char*,const char*) { } +}; + +template +using Allocator = ::std::allocator; + +template +Allocator makeAllocator(const char *, const char *unused = nullptr) { + (void)unused; + return Allocator(); +} + +using String = std::string; + +template +using Vector = std::vector; + +template +Vector makeVector(const char *tag) { + return Vector(); +} + +using JsonDoc = DynamicJsonDocument; + +template +T *mo_mem_new(Args&& ...args) { + return new T(std::forward(args)...); +} + +template +void mo_mem_delete(T *ptr) { + delete ptr; +} + +} //namespace MicroOcpp + +#endif //MO_OVERRIDE_ALLOCATION + +namespace MicroOcpp { + +String makeString(const char *tag, const char *val = nullptr); + +JsonDoc initJsonDoc(const char *tag, size_t capacity = 0); +std::unique_ptr makeJsonDoc(const char *tag, size_t capacity = 0); + +} + +#endif //__cplusplus +#endif diff --git a/src/MicroOcpp/Core/OcppError.h b/src/MicroOcpp/Core/OcppError.h index 759eac40..826c3215 100644 --- a/src/MicroOcpp/Core/OcppError.h +++ b/src/MicroOcpp/Core/OcppError.h @@ -5,33 +5,34 @@ #ifndef MO_OCPPERROR_H #define MO_OCPPERROR_H -#include - #include +#include namespace MicroOcpp { -class NotImplemented : public Operation { +class NotImplemented : public Operation, public MemoryManaged { public: + NotImplemented() : MemoryManaged("v16.CallError.", "NotImplemented") { } + const char *getErrorCode() override { return "NotImplemented"; } }; -class MsgBufferExceeded : public Operation { +class MsgBufferExceeded : public Operation, public MemoryManaged { private: size_t maxCapacity; size_t msgLen; public: - MsgBufferExceeded(size_t maxCapacity, size_t msgLen) : maxCapacity(maxCapacity), msgLen(msgLen) { } + MsgBufferExceeded(size_t maxCapacity, size_t msgLen) : MemoryManaged("v16.CallError.", "GenericError"), maxCapacity(maxCapacity), msgLen(msgLen) { } const char *getErrorCode() override { return "GenericError"; } const char *getErrorDescription() override { return "JSON too long or too many fields. Cannot deserialize"; } - std::unique_ptr getErrorDetails() override { - auto errDoc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(2))); + std::unique_ptr getErrorDetails() override { + auto errDoc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(2)); JsonObject err = errDoc->to(); err["max_capacity"] = maxCapacity; err["msg_length"] = msgLen; diff --git a/src/MicroOcpp/Core/Operation.cpp b/src/MicroOcpp/Core/Operation.cpp index 63d76a20..1289381b 100644 --- a/src/MicroOcpp/Core/Operation.cpp +++ b/src/MicroOcpp/Core/Operation.cpp @@ -6,7 +6,7 @@ #include -using MicroOcpp::Operation; +using namespace MicroOcpp; Operation::Operation() {} @@ -17,7 +17,7 @@ const char* Operation::getOperationType(){ return "CustomOperation"; } -std::unique_ptr Operation::createReq() { +std::unique_ptr Operation::createReq() { MO_DBG_ERR("Unsupported operation: createReq() is not implemented"); return createEmptyDocument(); } @@ -30,13 +30,13 @@ void Operation::processReq(JsonObject payload) { MO_DBG_ERR("Unsupported operation: processReq() is not implemented"); } -std::unique_ptr Operation::createConf() { +std::unique_ptr Operation::createConf() { MO_DBG_ERR("Unsupported operation: createConf() is not implemented"); return createEmptyDocument(); } -std::unique_ptr MicroOcpp::createEmptyDocument() { - auto emptyDoc = std::unique_ptr(new DynamicJsonDocument(0)); +std::unique_ptr MicroOcpp::createEmptyDocument() { + auto emptyDoc = makeJsonDoc("EmptyJsonDoc", 0); emptyDoc->to(); return emptyDoc; } diff --git a/src/MicroOcpp/Core/Operation.h b/src/MicroOcpp/Core/Operation.h index 5da9aa56..9c1756a1 100644 --- a/src/MicroOcpp/Core/Operation.h +++ b/src/MicroOcpp/Core/Operation.h @@ -20,10 +20,11 @@ #include #include +#include namespace MicroOcpp { -std::unique_ptr createEmptyDocument(); +std::unique_ptr createEmptyDocument(); class Operation { public: @@ -41,7 +42,7 @@ class Operation { * This function is usually called multiple times by the Arduino loop(). On first call, the request is initially sent. In the * succeeding calls, the implementers decide to either recreate the request, or do nothing as the operation is still pending. */ - virtual std::unique_ptr createReq(); + virtual std::unique_ptr createReq(); virtual void processConf(JsonObject payload); @@ -60,11 +61,11 @@ class Operation { * After successfully processing a request sent by the communication counterpart, this function creates the payload for a confirmation * message. */ - virtual std::unique_ptr createConf(); + virtual std::unique_ptr createConf(); virtual const char *getErrorCode() {return nullptr;} //nullptr means no error virtual const char *getErrorDescription() {return "";} - virtual std::unique_ptr getErrorDetails() {return createEmptyDocument();} + virtual std::unique_ptr getErrorDetails() {return createEmptyDocument();} }; } //end namespace MicroOcpp diff --git a/src/MicroOcpp/Core/OperationRegistry.cpp b/src/MicroOcpp/Core/OperationRegistry.cpp index 38d9e459..0bd17d45 100644 --- a/src/MicroOcpp/Core/OperationRegistry.cpp +++ b/src/MicroOcpp/Core/OperationRegistry.cpp @@ -11,7 +11,7 @@ using namespace MicroOcpp; -OperationRegistry::OperationRegistry() { +OperationRegistry::OperationRegistry() : registry(makeVector("OperationRegistry")) { } diff --git a/src/MicroOcpp/Core/OperationRegistry.h b/src/MicroOcpp/Core/OperationRegistry.h index 959111eb..0d0d44b5 100644 --- a/src/MicroOcpp/Core/OperationRegistry.h +++ b/src/MicroOcpp/Core/OperationRegistry.h @@ -6,9 +6,8 @@ #define MO_OPERATIONREGISTRY_H #include -#include #include -#include +#include #include namespace MicroOcpp { @@ -25,7 +24,7 @@ struct OperationCreator { class OperationRegistry { private: - std::vector registry; + Vector registry; OperationCreator *findCreator(const char *operationType); public: diff --git a/src/MicroOcpp/Core/Request.cpp b/src/MicroOcpp/Core/Request.cpp index a9d63677..56477fa8 100644 --- a/src/MicroOcpp/Core/Request.cpp +++ b/src/MicroOcpp/Core/Request.cpp @@ -29,7 +29,7 @@ namespace MicroOcpp { using namespace MicroOcpp; -Request::Request(std::unique_ptr msg) : operation(std::move(msg)) { +Request::Request(std::unique_ptr msg, const char *memory_tag) : MemoryManaged(memory_tag), messageID(makeString(getMemoryTag())), operation(std::move(msg)) { timeout_start = mocpp_tick_ms(); debugRequest_start = mocpp_tick_ms(); } @@ -65,7 +65,7 @@ void Request::setMessageID(const char *id){ messageID = id; } -Request::CreateRequestResult Request::createRequest(DynamicJsonDocument& requestJson) { +Request::CreateRequestResult Request::createRequest(JsonDoc& requestJson) { if (messageID.empty()) { unsigned char random [18]; @@ -92,7 +92,7 @@ Request::CreateRequestResult Request::createRequest(DynamicJsonDocument& request * Create OCPP-J Remote Procedure Call header */ size_t json_buffsize = JSON_ARRAY_SIZE(4) + (messageID.length() + 1) + requestPayload->capacity(); - requestJson = DynamicJsonDocument(json_buffsize); + requestJson = initJsonDoc(getMemoryTag(), json_buffsize); requestJson.add(MESSAGE_TYPE_CALL); //MessageType requestJson.add(messageID); //Unique message ID @@ -124,7 +124,7 @@ bool Request::receiveResponse(JsonArray response){ /* * check if messageIDs match. If yes, continue with this function. If not, return false for message not consumed */ - if (messageID != response[1].as()){ + if (messageID.compare(response[1].as())){ return false; } @@ -193,13 +193,13 @@ bool Request::receiveRequest(JsonArray request) { return true; //success } -Request::CreateResponseResult Request::createResponse(DynamicJsonDocument& response) { +Request::CreateResponseResult Request::createResponse(JsonDoc& response) { bool operationFailure = operation->getErrorCode() != nullptr; if (!operationFailure) { - std::unique_ptr payload = operation->createConf(); + std::unique_ptr payload = operation->createConf(); if (!payload) { return CreateResponseResult::Pending; //confirmation message still pending @@ -209,7 +209,7 @@ Request::CreateResponseResult Request::createResponse(DynamicJsonDocument& respo * Create OCPP-J Remote Procedure Call header */ size_t json_buffsize = JSON_ARRAY_SIZE(3) + payload->capacity(); - response = DynamicJsonDocument(json_buffsize); + response = initJsonDoc(getMemoryTag(), json_buffsize); response.add(MESSAGE_TYPE_CALLRESULT); //MessageType response.add(messageID.c_str()); //Unique message ID @@ -223,14 +223,14 @@ Request::CreateResponseResult Request::createResponse(DynamicJsonDocument& respo const char *errorCode = operation->getErrorCode(); const char *errorDescription = operation->getErrorDescription(); - std::unique_ptr errorDetails = operation->getErrorDetails(); + std::unique_ptr errorDetails = operation->getErrorDetails(); /* * Create OCPP-J Remote Procedure Call header */ size_t json_buffsize = JSON_ARRAY_SIZE(5) + errorDetails->capacity(); - response = DynamicJsonDocument(json_buffsize); + response = initJsonDoc(getMemoryTag(), json_buffsize); response.add(MESSAGE_TYPE_CALLERROR); //MessageType response.add(messageID.c_str()); //Unique message ID @@ -289,15 +289,19 @@ bool Request::isRequestSent() { namespace MicroOcpp { -std::unique_ptr makeRequest(std::unique_ptr operation){ +std::unique_ptr makeRequest(std::unique_ptr operation, const char *memoryTag){ if (operation == nullptr) { return nullptr; } - return std::unique_ptr(new Request(std::move(operation))); + return std::unique_ptr(new Request(std::move(operation), memoryTag)); } std::unique_ptr makeRequest(Operation *operation) { return makeRequest(std::unique_ptr(operation)); } +std::unique_ptr makeRequest(const char *memoryTag, Operation *operation) { + return makeRequest(std::unique_ptr(operation), memoryTag); +} + } //end namespace MicroOcpp diff --git a/src/MicroOcpp/Core/Request.h b/src/MicroOcpp/Core/Request.h index fde0eb91..4b608217 100644 --- a/src/MicroOcpp/Core/Request.h +++ b/src/MicroOcpp/Core/Request.h @@ -13,14 +13,16 @@ #include +#include + namespace MicroOcpp { class Operation; class Model; -class Request { +class Request : public MemoryManaged { private: - std::string messageID {}; + String messageID; std::unique_ptr operation; void setMessageID(const char *id); OnReceiveConfListener onReceiveConfListener = [] (JsonObject payload) {}; @@ -39,7 +41,7 @@ class Request { bool requestSent = false; public: - Request(std::unique_ptr msg); + Request(std::unique_ptr msg, const char *memory_tag = "Request"); ~Request(); @@ -62,7 +64,7 @@ class Request { Success, Failure }; - CreateRequestResult createRequest(DynamicJsonDocument& out); + CreateRequestResult createRequest(JsonDoc& out); /** * Decides if message belongs to this operation instance and if yes, proccesses it. Receives both Confirmations and Errors @@ -89,7 +91,7 @@ class Request { Failure }; - CreateResponseResult createResponse(DynamicJsonDocument& out); + CreateResponseResult createResponse(JsonDoc& out); void setOnReceiveConfListener(OnReceiveConfListener onReceiveConf); //listener executed when we received the .conf() to a .req() we sent void setOnReceiveReqListener(OnReceiveReqListener onReceiveReq); //listener executed when we receive a .req() @@ -119,8 +121,9 @@ class Request { /* * Simple factory functions */ -std::unique_ptr makeRequest(std::unique_ptr op); +std::unique_ptr makeRequest(std::unique_ptr op, const char *memoryTag = "Request"); std::unique_ptr makeRequest(Operation *op); //takes ownership of op +std::unique_ptr makeRequest(const char *memoryTag, Operation *op); //takes ownership of op } //end namespace MicroOcpp diff --git a/src/MicroOcpp/Core/RequestQueue.cpp b/src/MicroOcpp/Core/RequestQueue.cpp index 5f9722c2..551175a7 100644 --- a/src/MicroOcpp/Core/RequestQueue.cpp +++ b/src/MicroOcpp/Core/RequestQueue.cpp @@ -17,7 +17,7 @@ size_t removePayload(const char *src, size_t src_size, char *dst, size_t dst_siz using namespace MicroOcpp; -VolatileRequestQueue::VolatileRequestQueue(unsigned int priority) : priority{priority} { +VolatileRequestQueue::VolatileRequestQueue(unsigned int priority) : MemoryManaged("VolatileRequestQueue"), priority{priority} { } @@ -118,7 +118,7 @@ bool VolatileRequestQueue::pushRequestBack(std::unique_ptr request) { } RequestQueue::RequestQueue(Connection& connection, OperationRegistry& operationRegistry) - : connection(connection), operationRegistry(operationRegistry) { + : MemoryManaged("RequestQueue"), connection(connection), operationRegistry(operationRegistry) { ReceiveTXTcallback callback = [this] (const char *payload, size_t length) { return this->receiveMessage(payload, length); @@ -167,11 +167,11 @@ void RequestQueue::loop() { if (recvReqFront) { - DynamicJsonDocument response {0}; + auto response = initJsonDoc(getMemoryTag()); auto ret = recvReqFront->createResponse(response); if (ret == Request::CreateResponseResult::Success) { - std::string out; + auto out = makeString(getMemoryTag()); serializeJson(response, out); bool success = connection.sendTXT(out.c_str(), out.length()); @@ -208,13 +208,13 @@ void RequestQueue::loop() { if (sendReqFront && !sendReqFront->isRequestSent()) { - DynamicJsonDocument request {0}; + auto request = initJsonDoc(getMemoryTag()); auto ret = sendReqFront->createRequest(request); if (ret == Request::CreateRequestResult::Success) { //send request - std::string out; + auto out = makeString(getMemoryTag()); serializeJson(request, out); bool success = connection.sendTXT(out.c_str(), out.length()); @@ -267,12 +267,12 @@ bool RequestQueue::receiveMessage(const char* payload, size_t length) { capacity = MO_MAX_JSON_CAPACITY; } - DynamicJsonDocument doc {0}; + auto doc = initJsonDoc(getMemoryTag()); DeserializationError err = DeserializationError::NoMemory; while (err == DeserializationError::NoMemory && capacity <= MO_MAX_JSON_CAPACITY) { - doc = DynamicJsonDocument(capacity); + doc = initJsonDoc(getMemoryTag(), capacity); err = deserializeJson(doc, payload, length); capacity *= 2; @@ -308,7 +308,7 @@ bool RequestQueue::receiveMessage(const char* payload, size_t length) { * If the input type is MESSAGE_TYPE_CALLRESULT, then abort the operation to avoid getting stalled. */ - doc = DynamicJsonDocument(200); + doc = initJsonDoc(getMemoryTag(), 200); char onlyRpcHeader[200]; size_t onlyRpcHeader_len = removePayload(payload, length, onlyRpcHeader, sizeof(onlyRpcHeader)); DeserializationError err2 = deserializeJson(doc, onlyRpcHeader, onlyRpcHeader_len); diff --git a/src/MicroOcpp/Core/RequestQueue.h b/src/MicroOcpp/Core/RequestQueue.h index 7eba5355..5213272e 100644 --- a/src/MicroOcpp/Core/RequestQueue.h +++ b/src/MicroOcpp/Core/RequestQueue.h @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -34,7 +35,7 @@ class RequestEmitter { virtual std::unique_ptr fetchFrontRequest() = 0; }; -class VolatileRequestQueue : public RequestEmitter { +class VolatileRequestQueue : public RequestEmitter, public MemoryManaged { private: std::unique_ptr requests [MO_REQUEST_CACHE_MAXSIZE]; size_t front = 0, len = 0; @@ -50,7 +51,7 @@ class VolatileRequestQueue : public RequestEmitter { bool pushRequestBack(std::unique_ptr request); }; -class RequestQueue { +class RequestQueue : public MemoryManaged { private: Connection& connection; OperationRegistry& operationRegistry; diff --git a/src/MicroOcpp/Core/Time.cpp b/src/MicroOcpp/Core/Time.cpp index 6db1f852..ae25bf5e 100644 --- a/src/MicroOcpp/Core/Time.cpp +++ b/src/MicroOcpp/Core/Time.cpp @@ -11,20 +11,20 @@ namespace MicroOcpp { const Timestamp MIN_TIME = Timestamp(2010, 0, 0, 0, 0, 0); const Timestamp MAX_TIME = Timestamp(2037, 0, 0, 0, 0, 0); -Timestamp::Timestamp() { +Timestamp::Timestamp() : MemoryManaged("Timestamp") { } -Timestamp::Timestamp(const Timestamp& other) { +Timestamp::Timestamp(const Timestamp& other) : MemoryManaged("Timestamp") { *this = other; } #if MO_ENABLE_TIMESTAMP_MILLISECONDS Timestamp::Timestamp(int16_t year, int16_t month, int16_t day, int32_t hour, int32_t minute, int32_t second, int32_t ms) : - year(year), month(month), day(day), hour(hour), minute(minute), second(second), ms(ms) { }; + MemoryManaged("Timestamp"), year(year), month(month), day(day), hour(hour), minute(minute), second(second), ms(ms) { } #else Timestamp::Timestamp(int16_t year, int16_t month, int16_t day, int32_t hour, int32_t minute, int32_t second) : - year(year), month(month), day(day), hour(hour), minute(minute), second(second) { }; + MemoryManaged("Timestamp"), year(year), month(month), day(day), hour(hour), minute(minute), second(second) { } #endif //MO_ENABLE_TIMESTAMP_MILLISECONDS int noDays(int month, int year) { diff --git a/src/MicroOcpp/Core/Time.h b/src/MicroOcpp/Core/Time.h index 349fb01b..9a82753b 100644 --- a/src/MicroOcpp/Core/Time.h +++ b/src/MicroOcpp/Core/Time.h @@ -9,6 +9,7 @@ #include #include +#include #include #ifndef MO_ENABLE_TIMESTAMP_MILLISECONDS @@ -23,7 +24,7 @@ namespace MicroOcpp { -class Timestamp { +class Timestamp : public MemoryManaged { private: /* * Internal representation of the current time. The initial values correspond to UNIX-time 0. January diff --git a/src/MicroOcpp/Model/Authorization/AuthorizationData.cpp b/src/MicroOcpp/Model/Authorization/AuthorizationData.cpp index ac95e70d..08cbfbca 100644 --- a/src/MicroOcpp/Model/Authorization/AuthorizationData.cpp +++ b/src/MicroOcpp/Model/Authorization/AuthorizationData.cpp @@ -7,23 +7,26 @@ #if MO_ENABLE_LOCAL_AUTH #include +#include using namespace MicroOcpp; -AuthorizationData::AuthorizationData() { +AuthorizationData::AuthorizationData() : MemoryManaged("v16.Authorization.AuthorizationData") { } -AuthorizationData::AuthorizationData(AuthorizationData&& other) { +AuthorizationData::AuthorizationData(AuthorizationData&& other) : MemoryManaged("v16.Authorization.AuthorizationData") { operator=(std::move(other)); } AuthorizationData::~AuthorizationData() { - + MO_FREE(parentIdTag); + parentIdTag = nullptr; } AuthorizationData& AuthorizationData::operator=(AuthorizationData&& other) { - parentIdTag = std::move(other.parentIdTag); + parentIdTag = other.parentIdTag; + other.parentIdTag = nullptr; expiryDate = std::move(other.expiryDate); strncpy(idTag, other.idTag, IDTAG_LEN_MAX + 1); idTag[IDTAG_LEN_MAX] = '\0'; @@ -56,11 +59,18 @@ void AuthorizationData::readJson(JsonObject entry, bool compact) { } if (idTagInfo.containsKey(AUTHDATA_KEY_PARENTIDTAG(compact))) { - parentIdTag = std::unique_ptr(new char[IDTAG_LEN_MAX + 1]); - strncpy(parentIdTag.get(), idTagInfo[AUTHDATA_KEY_PARENTIDTAG(compact)], IDTAG_LEN_MAX + 1); - parentIdTag.get()[IDTAG_LEN_MAX] = '\0'; + MO_FREE(parentIdTag); + parentIdTag = nullptr; + parentIdTag = static_cast(MO_MALLOC(getMemoryTag(), IDTAG_LEN_MAX + 1)); + if (parentIdTag) { + strncpy(parentIdTag, idTagInfo[AUTHDATA_KEY_PARENTIDTAG(compact)], IDTAG_LEN_MAX + 1); + parentIdTag[IDTAG_LEN_MAX] = '\0'; + } else { + MO_DBG_ERR("OOM"); + } } else { - parentIdTag.reset(); + MO_FREE(parentIdTag); + parentIdTag = nullptr; } if (idTagInfo.containsKey(AUTHDATA_KEY_STATUS(compact))) { @@ -106,7 +116,7 @@ void AuthorizationData::writeJson(JsonObject& entry, bool compact) { } if (parentIdTag) { - idTagInfo[AUTHDATA_KEY_PARENTIDTAG(compact)] = (const char *) parentIdTag.get(); + idTagInfo[AUTHDATA_KEY_PARENTIDTAG(compact)] = (const char *) parentIdTag; } if (status != AuthorizationStatus::Accepted) { @@ -116,6 +126,19 @@ void AuthorizationData::writeJson(JsonObject& entry, bool compact) { } } +const char *AuthorizationData::getIdTag() const { + return idTag; +} +Timestamp *AuthorizationData::getExpiryDate() const { + return expiryDate.get(); +} +const char *AuthorizationData::getParentIdTag() const { + return parentIdTag; +} +AuthorizationStatus AuthorizationData::getAuthorizationStatus() const { + return status; +} + void AuthorizationData::reset() { idTag[0] = '\0'; } diff --git a/src/MicroOcpp/Model/Authorization/AuthorizationData.h b/src/MicroOcpp/Model/Authorization/AuthorizationData.h index 074e24a8..7bcdccd7 100644 --- a/src/MicroOcpp/Model/Authorization/AuthorizationData.h +++ b/src/MicroOcpp/Model/Authorization/AuthorizationData.h @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -36,11 +37,11 @@ enum class AuthorizationStatus : uint8_t { const char *serializeAuthorizationStatus(AuthorizationStatus status); AuthorizationStatus deserializeAuthorizationStatus(const char *cstr); -class AuthorizationData { +class AuthorizationData : public MemoryManaged { private: //data structure optimized for memory consumption - std::unique_ptr parentIdTag; + char *parentIdTag = nullptr; std::unique_ptr expiryDate; char idTag [IDTAG_LEN_MAX + 1] = {'\0'}; @@ -58,10 +59,10 @@ class AuthorizationData { size_t getJsonCapacity() const; void writeJson(JsonObject& entry, bool compact = false); //compact: compressed representation for flash storage - const char *getIdTag() const {return idTag;} - Timestamp *getExpiryDate() const {return expiryDate.get();} - const char *getParentIdTag() const {return parentIdTag.get();} - AuthorizationStatus getAuthorizationStatus() const {return status;} + const char *getIdTag() const; + Timestamp *getExpiryDate() const; + const char *getParentIdTag() const; + AuthorizationStatus getAuthorizationStatus() const; void reset(); }; diff --git a/src/MicroOcpp/Model/Authorization/AuthorizationList.cpp b/src/MicroOcpp/Model/Authorization/AuthorizationList.cpp index bcbc8678..dd438ff8 100644 --- a/src/MicroOcpp/Model/Authorization/AuthorizationList.cpp +++ b/src/MicroOcpp/Model/Authorization/AuthorizationList.cpp @@ -14,7 +14,7 @@ using namespace MicroOcpp; -AuthorizationList::AuthorizationList() { +AuthorizationList::AuthorizationList() : MemoryManaged("v16.Authorization.AuthorizationList"), localAuthorizationList(makeVector(getMemoryTag())) { } @@ -60,8 +60,8 @@ bool AuthorizationList::readJson(JsonArray authlistJson, int listVersion, bool d } } - std::vector authlist_index; - std::vector remove_list; + auto authlist_index = makeVector(getMemoryTag()); + auto remove_list = makeVector(getMemoryTag()); unsigned int resultingListLength = 0; @@ -74,7 +74,7 @@ bool AuthorizationList::readJson(JsonArray authlistJson, int listVersion, bool d resultingListLength = localAuthorizationList.size(); //also, build index here - authlist_index = std::vector(authlistJson.size(), -1); + authlist_index.resize(authlistJson.size(), -1); for (size_t i = 0; i < authlistJson.size(); i++) { @@ -113,7 +113,7 @@ bool AuthorizationList::readJson(JsonArray authlistJson, int listVersion, bool d localAuthorizationList.clear(); for (size_t i = 0; i < authlistJson.size(); i++) { - localAuthorizationList.push_back(AuthorizationData()); + localAuthorizationList.emplace_back(); localAuthorizationList.back().readJson(authlistJson[i], compact); } } else if (differential) { @@ -138,7 +138,7 @@ bool AuthorizationList::readJson(JsonArray authlistJson, int listVersion, bool d } else { //no, create new authlist_index[i] = localAuthorizationList.size(); - localAuthorizationList.push_back(AuthorizationData()); + localAuthorizationList.emplace_back(); } } @@ -150,7 +150,7 @@ bool AuthorizationList::readJson(JsonArray authlistJson, int listVersion, bool d for (size_t i = 0; i < authlistJson.size(); i++) { if (authlistJson[i].as().containsKey(AUTHDATA_KEY_IDTAGINFO)) { - localAuthorizationList.push_back(AuthorizationData()); + localAuthorizationList.emplace_back(); localAuthorizationList.back().readJson(authlistJson[i], compact); } } diff --git a/src/MicroOcpp/Model/Authorization/AuthorizationList.h b/src/MicroOcpp/Model/Authorization/AuthorizationList.h index 7b0d33c5..0a083777 100644 --- a/src/MicroOcpp/Model/Authorization/AuthorizationList.h +++ b/src/MicroOcpp/Model/Authorization/AuthorizationList.h @@ -10,7 +10,7 @@ #if MO_ENABLE_LOCAL_AUTH #include -#include +#include #ifndef MO_LocalAuthListMaxLength #define MO_LocalAuthListMaxLength 48 @@ -22,10 +22,10 @@ namespace MicroOcpp { -class AuthorizationList { +class AuthorizationList : public MemoryManaged { private: int listVersion = 0; - std::vector localAuthorizationList; //sorted list + Vector localAuthorizationList; //sorted list public: AuthorizationList(); ~AuthorizationList(); diff --git a/src/MicroOcpp/Model/Authorization/AuthorizationService.cpp b/src/MicroOcpp/Model/Authorization/AuthorizationService.cpp index fd15c0b9..e9dc39d2 100644 --- a/src/MicroOcpp/Model/Authorization/AuthorizationService.cpp +++ b/src/MicroOcpp/Model/Authorization/AuthorizationService.cpp @@ -22,8 +22,8 @@ using namespace MicroOcpp; -AuthorizationService::AuthorizationService(Context& context, std::shared_ptr filesystem) : context(context), filesystem(filesystem) { - +AuthorizationService::AuthorizationService(Context& context, std::shared_ptr filesystem) : MemoryManaged("v16.Authorization.AuthorizationService"), context(context), filesystem(filesystem) { + localAuthListEnabledBool = declareConfiguration("LocalAuthListEnabled", true); declareConfiguration("LocalAuthListMaxLength", MO_LocalAuthListMaxLength, CONFIGURATION_VOLATILE, true); declareConfiguration("SendLocalListMaxLength", MO_SendLocalListMaxLength, CONFIGURATION_VOLATILE, true); @@ -56,7 +56,7 @@ bool AuthorizationService::loadLists() { return true; } - auto doc = FilesystemUtils::loadJson(filesystem, MO_LOCALAUTHORIZATIONLIST_FN); + auto doc = FilesystemUtils::loadJson(filesystem, MO_LOCALAUTHORIZATIONLIST_FN, getMemoryTag()); if (!doc) { MO_DBG_ERR("failed to load %s", MO_LOCALAUTHORIZATIONLIST_FN); return false; @@ -106,7 +106,7 @@ bool AuthorizationService::updateLocalList(JsonArray localAuthorizationListJson, if (success) { - DynamicJsonDocument doc ( + auto doc = initJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(3) + localAuthorizationList.getJsonCapacity()); diff --git a/src/MicroOcpp/Model/Authorization/AuthorizationService.h b/src/MicroOcpp/Model/Authorization/AuthorizationService.h index 85972c50..88ba7936 100644 --- a/src/MicroOcpp/Model/Authorization/AuthorizationService.h +++ b/src/MicroOcpp/Model/Authorization/AuthorizationService.h @@ -12,12 +12,13 @@ #include #include #include +#include namespace MicroOcpp { class Context; -class AuthorizationService { +class AuthorizationService : public MemoryManaged { private: Context& context; std::shared_ptr filesystem; diff --git a/src/MicroOcpp/Model/Authorization/IdToken.cpp b/src/MicroOcpp/Model/Authorization/IdToken.cpp index 8983c5cd..f6ceec10 100644 --- a/src/MicroOcpp/Model/Authorization/IdToken.cpp +++ b/src/MicroOcpp/Model/Authorization/IdToken.cpp @@ -15,21 +15,22 @@ using namespace MicroOcpp; -IdToken::IdToken() { - idToken[0] = '\0'; +IdToken::IdToken(const char *token, Type type, const char *memoryTag) : MemoryManaged(memoryTag ? memoryTag : "v201.Authorization.IdToken"), type(type) { + if (token) { + auto ret = snprintf(idToken, MO_IDTOKEN_LEN_MAX + 1, "%s", token); + if (ret < 0 || ret >= MO_IDTOKEN_LEN_MAX + 1) { + MO_DBG_ERR("invalid token"); + *idToken = '\0'; + } + } } -IdToken::IdToken(const char *token, Type type) : type(type) { - auto ret = snprintf(idToken, MO_IDTOKEN_LEN_MAX + 1, "%s", token); - if (ret < 0 || ret >= MO_IDTOKEN_LEN_MAX + 1) { - MO_DBG_ERR("invalid token"); - *idToken = '\0'; - } +IdToken::IdToken(const IdToken& other, const char *memoryTag) : IdToken(other.idToken, other.type, memoryTag ? memoryTag : other.getMemoryTag()) { + } bool IdToken::parseCstr(const char *token, const char *typeCstr) { if (!token || !typeCstr) { - MO_DBG_DEBUG("TRACE"); return false; } @@ -42,7 +43,6 @@ bool IdToken::parseCstr(const char *token, const char *typeCstr) { } else if (!strcmp(typeCstr, "ISO15693")) { type = Type::ISO15693; } else if (!strcmp(typeCstr, "KeyCode")) { - MO_DBG_DEBUG("TRACE"); type = Type::KeyCode; } else if (!strcmp(typeCstr, "Local")) { type = Type::Local; @@ -51,7 +51,6 @@ bool IdToken::parseCstr(const char *token, const char *typeCstr) { } else if (!strcmp(typeCstr, "NoAuthorization")) { type = Type::NoAuthorization; } else { - MO_DBG_DEBUG("TRACE"); return false; } diff --git a/src/MicroOcpp/Model/Authorization/IdToken.h b/src/MicroOcpp/Model/Authorization/IdToken.h index 8f4ba190..cb209872 100644 --- a/src/MicroOcpp/Model/Authorization/IdToken.h +++ b/src/MicroOcpp/Model/Authorization/IdToken.h @@ -11,12 +11,14 @@ #include +#include + #define MO_IDTOKEN_LEN_MAX 36 namespace MicroOcpp { // IdTokenType (2.28) -class IdToken { +class IdToken : public MemoryManaged { public: // IdTokenEnumType (3.43) @@ -36,8 +38,9 @@ class IdToken { char idToken [MO_IDTOKEN_LEN_MAX + 1]; Type type = Type::UNDEFINED; public: - IdToken(); - IdToken(const char *token, Type type = Type::ISO14443); + IdToken(const char *token = nullptr, Type type = Type::ISO14443, const char *memoryTag = nullptr); + + IdToken(const IdToken& other, const char *memoryTag = nullptr); bool parseCstr(const char *token, const char *typeCstr); diff --git a/src/MicroOcpp/Model/Boot/BootService.cpp b/src/MicroOcpp/Model/Boot/BootService.cpp index d44a4b71..3d027f03 100644 --- a/src/MicroOcpp/Model/Boot/BootService.cpp +++ b/src/MicroOcpp/Model/Boot/BootService.cpp @@ -33,7 +33,7 @@ RegistrationStatus MicroOcpp::deserializeRegistrationStatus(const char *serializ } } -BootService::BootService(Context& context, std::shared_ptr filesystem) : context(context), filesystem(filesystem) { +BootService::BootService(Context& context, std::shared_ptr filesystem) : MemoryManaged("v16.Boot.BootService"), context(context), filesystem(filesystem), cpCredentials{makeString(getMemoryTag())} { //if transactions can start before the BootNotification succeeds preBootTransactionsBool = declareConfiguration(MO_CONFIG_EXT_PREFIX "PreBootTransactions", false); @@ -102,16 +102,16 @@ void BootService::setChargePointCredentials(const char *credentials) { } } -std::unique_ptr BootService::getChargePointCredentials() { +std::unique_ptr BootService::getChargePointCredentials() { if (cpCredentials.size() <= 2) { return createEmptyDocument(); } - std::unique_ptr doc; + std::unique_ptr doc; size_t capacity = JSON_OBJECT_SIZE(9) + cpCredentials.size(); DeserializationError err = DeserializationError::NoMemory; while (err == DeserializationError::NoMemory && capacity <= MO_MAX_JSON_CAPACITY) { - doc.reset(new DynamicJsonDocument(capacity)); + doc = makeJsonDoc(getMemoryTag(), capacity); err = deserializeJson(*doc, cpCredentials); capacity *= 2; @@ -149,7 +149,7 @@ bool BootService::loadBootStats(std::shared_ptr filesystem, B bool success = true; - auto json = FilesystemUtils::loadJson(filesystem, MO_FILENAME_PREFIX "bootstats.jsn"); + auto json = FilesystemUtils::loadJson(filesystem, MO_FILENAME_PREFIX "bootstats.jsn", "v16.Boot.BootService"); if (json) { int bootNrIn = (*json)["bootNr"] | -1; if (bootNrIn >= 0 && bootNrIn <= std::numeric_limits::max()) { @@ -185,7 +185,7 @@ bool BootService::storeBootStats(std::shared_ptr filesystem, return false; } - DynamicJsonDocument json {JSON_OBJECT_SIZE(2)}; + auto json = initJsonDoc("v16.Boot.BootService", JSON_OBJECT_SIZE(2)); json["bootNr"] = bstats.bootNr; json["lastSuccess"] = bstats.lastBootSuccess; diff --git a/src/MicroOcpp/Model/Boot/BootService.h b/src/MicroOcpp/Model/Boot/BootService.h index e00559bd..e5144be1 100644 --- a/src/MicroOcpp/Model/Boot/BootService.h +++ b/src/MicroOcpp/Model/Boot/BootService.h @@ -7,6 +7,7 @@ #include #include +#include #include #define MO_BOOT_INTERVAL_DEFAULT 60 @@ -33,7 +34,7 @@ RegistrationStatus deserializeRegistrationStatus(const char *serialized); class Context; -class BootService { +class BootService : public MemoryManaged { private: Context& context; std::shared_ptr filesystem; @@ -43,7 +44,7 @@ class BootService { RegistrationStatus status = RegistrationStatus::Pending; - std::string cpCredentials; + String cpCredentials; std::shared_ptr preBootTransactionsBool; @@ -60,7 +61,7 @@ class BootService { void setChargePointCredentials(JsonObject credentials); void setChargePointCredentials(const char *credentials); //credentials: serialized BootNotification payload - std::unique_ptr getChargePointCredentials(); + std::unique_ptr getChargePointCredentials(); void notifyRegistrationStatus(RegistrationStatus status); void setRetryInterval(unsigned long interval); diff --git a/src/MicroOcpp/Model/Certificates/Certificate.h b/src/MicroOcpp/Model/Certificates/Certificate.h index d9975bf7..33574351 100644 --- a/src/MicroOcpp/Model/Certificates/Certificate.h +++ b/src/MicroOcpp/Model/Certificates/Certificate.h @@ -128,7 +128,7 @@ int ocpp_cert_set_serialNumber(ocpp_cert_hash *dst, const char *hex_src); #ifdef __cplusplus } //extern "C" -#include +#include namespace MicroOcpp { @@ -137,10 +137,12 @@ using CertificateHash = ocpp_cert_hash; /* * See OCPP 2.0.1 part 2 Data Type 2.5 */ -struct CertificateChainHash { +struct CertificateChainHash : public MemoryManaged { GetCertificateIdType certificateType; CertificateHash certificateHashData; - std::vector childCertificateHashData; + Vector childCertificateHashData; + + CertificateChainHash() : MemoryManaged("v2.0.1.Certificates.CertificateChainHash"), childCertificateHashData(makeVector(getMemoryTag())) { } }; /* @@ -150,7 +152,7 @@ class CertificateStore { public: virtual ~CertificateStore() = default; - virtual GetInstalledCertificateStatus getCertificateIds(const std::vector& certificateType, std::vector& out) = 0; + virtual GetInstalledCertificateStatus getCertificateIds(const Vector& certificateType, Vector& out) = 0; virtual DeleteCertificateStatus deleteCertificate(const CertificateHash& hash) = 0; virtual InstallCertificateStatus installCertificate(InstallCertificateType certificateType, const char *certificate) = 0; }; diff --git a/src/MicroOcpp/Model/Certificates/CertificateMbedTLS.cpp b/src/MicroOcpp/Model/Certificates/CertificateMbedTLS.cpp index 05609f80..73314158 100644 --- a/src/MicroOcpp/Model/Certificates/CertificateMbedTLS.cpp +++ b/src/MicroOcpp/Model/Certificates/CertificateMbedTLS.cpp @@ -69,7 +69,7 @@ bool ocpp_get_cert_hash(mbedtls_x509_crt& cacert, HashAlgorithmType hashAlg, ocp // copy public key into pk_buf to create issuerKeyHash size_t pk_size = cacert.pk_raw.len; - unsigned char *pk_buf = new unsigned char[pk_size]; + unsigned char *pk_buf = static_cast(MO_MALLOC("v201.Certificates.CertificateStoreMbedTLS", pk_size)); if (!pk_buf) { MO_DBG_ERR("OOM (alloc size %zu)", pk_size); return false; @@ -94,7 +94,7 @@ bool ocpp_get_cert_hash(mbedtls_x509_crt& cacert, HashAlgorithmType hashAlg, ocp } } - delete[] pk_buf; + MO_FREE(pk_buf); if (pk_err) { return false; } @@ -134,7 +134,7 @@ bool ocpp_get_cert_hash(const unsigned char *buf, size_t len, HashAlgorithmType namespace MicroOcpp { -class CertificateStoreMbedTLS : public CertificateStore { +class CertificateStoreMbedTLS : public CertificateStore, public MemoryManaged { private: std::shared_ptr filesystem; @@ -156,7 +156,7 @@ class CertificateStoreMbedTLS : public CertificateStore { return false; } - unsigned char *buf = new unsigned char[fsize + 1]; + unsigned char *buf = static_cast(MO_MALLOC(getMemoryTag(), fsize + 1)); if (!buf) { MO_DBG_ERR("OOM"); return false; @@ -180,16 +180,16 @@ class CertificateStoreMbedTLS : public CertificateStore { MO_DBG_ERR("could not read cert: %s", fn); } - delete[] buf; + MO_FREE(buf); return success; } public: CertificateStoreMbedTLS(std::shared_ptr filesystem) - : filesystem(filesystem) { + : MemoryManaged("v201.Certificates.CertificateStoreMbedTLS"), filesystem(filesystem) { } - GetInstalledCertificateStatus getCertificateIds(const std::vector& certificateType, std::vector& out) override { + GetInstalledCertificateStatus getCertificateIds(const Vector& certificateType, Vector& out) override { out.clear(); for (auto certType : certificateType) { @@ -325,7 +325,7 @@ class CertificateStoreMbedTLS : public CertificateStore { #endif // MO_DBG_LEVEL >= MO_DL_DEBUG //check if cert is already stored on flash - std::vector installedCerts; + auto installedCerts = makeVector(getMemoryTag()); auto ret = getCertificateIds({certTypeGetType}, installedCerts); if (ret == GetInstalledCertificateStatus_Accepted) { for (auto &installedCert : installedCerts) { diff --git a/src/MicroOcpp/Model/Certificates/CertificateService.cpp b/src/MicroOcpp/Model/Certificates/CertificateService.cpp index b07c2f72..22e5ab6d 100644 --- a/src/MicroOcpp/Model/Certificates/CertificateService.cpp +++ b/src/MicroOcpp/Model/Certificates/CertificateService.cpp @@ -14,7 +14,7 @@ using namespace MicroOcpp; CertificateService::CertificateService(Context& context) - : context(context) { + : MemoryManaged("v201.Certificates.CertificateService"), context(context) { context.getOperationRegistry().registerOperation("DeleteCertificate", [this] () { return new Ocpp201::DeleteCertificate(*this);}); diff --git a/src/MicroOcpp/Model/Certificates/CertificateService.h b/src/MicroOcpp/Model/Certificates/CertificateService.h index 6d11d026..31d10048 100644 --- a/src/MicroOcpp/Model/Certificates/CertificateService.h +++ b/src/MicroOcpp/Model/Certificates/CertificateService.h @@ -22,12 +22,13 @@ #include #include +#include namespace MicroOcpp { class Context; -class CertificateService { +class CertificateService : public MemoryManaged { private: Context& context; std::unique_ptr certStore; diff --git a/src/MicroOcpp/Model/Certificates/Certificate_c.cpp b/src/MicroOcpp/Model/Certificates/Certificate_c.cpp index 1152af3b..d316140c 100644 --- a/src/MicroOcpp/Model/Certificates/Certificate_c.cpp +++ b/src/MicroOcpp/Model/Certificates/Certificate_c.cpp @@ -6,6 +6,7 @@ #if MO_ENABLE_CERT_MGMT +#include #include #include @@ -15,17 +16,17 @@ namespace MicroOcpp { /* * C++ wrapper for the C-style certificate interface */ -class CertificateStoreC : public CertificateStore { +class CertificateStoreC : public CertificateStore, public MemoryManaged { private: ocpp_cert_store *certstore = nullptr; public: - CertificateStoreC(ocpp_cert_store *certstore) : certstore(certstore) { + CertificateStoreC(ocpp_cert_store *certstore) : MemoryManaged("v201.Certificates.CertificateStoreC"), certstore(certstore) { } ~CertificateStoreC() = default; - GetInstalledCertificateStatus getCertificateIds(const std::vector& certificateType, std::vector& out) override { + GetInstalledCertificateStatus getCertificateIds(const Vector& certificateType, Vector& out) override { out.clear(); ocpp_cert_chain_hash *cch; diff --git a/src/MicroOcpp/Model/ConnectorBase/Connector.cpp b/src/MicroOcpp/Model/ConnectorBase/Connector.cpp index 56eaa7e8..04f04e9e 100644 --- a/src/MicroOcpp/Model/ConnectorBase/Connector.cpp +++ b/src/MicroOcpp/Model/ConnectorBase/Connector.cpp @@ -34,7 +34,8 @@ using namespace MicroOcpp; Connector::Connector(Context& context, std::shared_ptr filesystem, unsigned int connectorId) - : context(context), model(context.getModel()), filesystem(filesystem), connectorId(connectorId) { + : MemoryManaged("v16.ConnectorBase.Connector"), context(context), model(context.getModel()), filesystem(filesystem), connectorId(connectorId), + errorDataInputs(makeVector>(getMemoryTag())), trackErrorDataInputs(makeVector(getMemoryTag())) { context.getRequestQueue().addSendQueue(this); //register at RequestQueue as Request emitter diff --git a/src/MicroOcpp/Model/ConnectorBase/Connector.h b/src/MicroOcpp/Model/ConnectorBase/Connector.h index 637313e0..84d2722f 100644 --- a/src/MicroOcpp/Model/ConnectorBase/Connector.h +++ b/src/MicroOcpp/Model/ConnectorBase/Connector.h @@ -12,9 +12,9 @@ #include #include #include +#include #include -#include #include #include @@ -35,7 +35,7 @@ class Model; class Operation; class Transaction; -class Connector : public RequestEmitter { +class Connector : public RequestEmitter, public MemoryManaged { private: Context& context; Model& model; @@ -52,8 +52,8 @@ class Connector : public RequestEmitter { std::function connectorPluggedInput; std::function evReadyInput; std::function evseReadyInput; - std::vector> errorDataInputs; - std::vector trackErrorDataInputs; + Vector> errorDataInputs; + Vector trackErrorDataInputs; int reportedErrorIndex = -1; //last reported error bool isFaulted(); const char *getErrorCode(); diff --git a/src/MicroOcpp/Model/ConnectorBase/ConnectorsCommon.cpp b/src/MicroOcpp/Model/ConnectorBase/ConnectorsCommon.cpp index 3eb9d596..f08b3483 100644 --- a/src/MicroOcpp/Model/ConnectorBase/ConnectorsCommon.cpp +++ b/src/MicroOcpp/Model/ConnectorBase/ConnectorsCommon.cpp @@ -2,8 +2,6 @@ // Copyright Matthias Akstaller 2019 - 2024 // MIT License -#include - #include #include #include @@ -30,7 +28,7 @@ using namespace MicroOcpp; ConnectorsCommon::ConnectorsCommon(Context& context, unsigned int numConn, std::shared_ptr filesystem) : - context(context) { + MemoryManaged("v16.ConnectorBase.ConnectorsCommon"), context(context) { declareConfiguration("NumberOfConnectors", numConn >= 1 ? numConn - 1 : 0, CONFIGURATION_VOLATILE, true); diff --git a/src/MicroOcpp/Model/ConnectorBase/ConnectorsCommon.h b/src/MicroOcpp/Model/ConnectorBase/ConnectorsCommon.h index 2fa856b8..4bc9f78a 100644 --- a/src/MicroOcpp/Model/ConnectorBase/ConnectorsCommon.h +++ b/src/MicroOcpp/Model/ConnectorBase/ConnectorsCommon.h @@ -6,12 +6,13 @@ #define MO_CHARGECONTROLCOMMON_H #include +#include namespace MicroOcpp { class Context; -class ConnectorsCommon { +class ConnectorsCommon : public MemoryManaged { private: Context& context; public: diff --git a/src/MicroOcpp/Model/Diagnostics/DiagnosticsService.cpp b/src/MicroOcpp/Model/Diagnostics/DiagnosticsService.cpp index c4cb6b9a..6eb9a3e0 100644 --- a/src/MicroOcpp/Model/Diagnostics/DiagnosticsService.cpp +++ b/src/MicroOcpp/Model/Diagnostics/DiagnosticsService.cpp @@ -22,8 +22,8 @@ using namespace MicroOcpp; using Ocpp16::DiagnosticsStatus; -DiagnosticsService::DiagnosticsService(Context& context) : context(context) { - +DiagnosticsService::DiagnosticsService(Context& context) : MemoryManaged("v16.Diagnostics.DiagnosticsService"), context(context), location(makeString(getMemoryTag())), diagFileList(makeVector(getMemoryTag())) { + context.getOperationRegistry().registerOperation("GetDiagnostics", [this] () { return new Ocpp16::GetDiagnostics(*this);}); @@ -33,8 +33,8 @@ DiagnosticsService::DiagnosticsService(Context& context) : context(context) { } DiagnosticsService::~DiagnosticsService() { - free(diagPreamble); - free(diagPostamble); + MO_FREE(diagPreamble); + MO_FREE(diagPostamble); } void DiagnosticsService::loop() { @@ -118,14 +118,14 @@ void DiagnosticsService::loop() { } //timestamps before year 2021 will be treated as "undefined" -std::string DiagnosticsService::requestDiagnosticsUpload(const char *location, unsigned int retries, unsigned int retryInterval, Timestamp startTime, Timestamp stopTime) { +MicroOcpp::String DiagnosticsService::requestDiagnosticsUpload(const char *location, unsigned int retries, unsigned int retryInterval, Timestamp startTime, Timestamp stopTime) { if (onUpload == nullptr) { - return std::string{}; + return makeString(getMemoryTag()); } - std::string fileName; + String fileName; if (refreshFilename) { - fileName = refreshFilename(); + fileName = refreshFilename().c_str(); } else { fileName = "diagnostics.log"; } @@ -247,7 +247,7 @@ void DiagnosticsService::setDiagnosticsReader(std::function(MO_MALLOC(getMemoryTag(), diagPreambleSize)); if (!diagPreamble) { MO_DBG_ERR("OOM"); this->ftpUploadStatus = UploadStatus::UploadFailed; @@ -259,11 +259,11 @@ void DiagnosticsService::setDiagnosticsReader(std::function(MO_MALLOC(getMemoryTag(), diagPostambleSize)); if (!diagPostamble) { MO_DBG_ERR("OOM"); this->ftpUploadStatus = UploadStatus::UploadFailed; - free(diagPreamble); + MO_FREE(diagPreamble); return false; } diagPostambleLen = 0; @@ -271,8 +271,8 @@ void DiagnosticsService::setDiagnosticsReader(std::functiongetChargePointCredentials()) { @@ -295,8 +295,8 @@ void DiagnosticsService::setDiagnosticsReader(std::function= diagPreambleSize) { MO_DBG_ERR("snprintf: %i", ret); this->ftpUploadStatus = UploadStatus::UploadFailed; - free(diagPreamble); - free(diagPostamble); + MO_FREE(diagPreamble); + MO_FREE(diagPostamble); return false; } @@ -413,21 +413,21 @@ void DiagnosticsService::setDiagnosticsReader(std::function= sizeof(fpath)) { MO_DBG_ERR("fn error: %i", ret); - diagFileList.pop_front(); + diagFileList.pop_back(); continue; } if (auto file = filesystem->open(fpath, "r")) { - if (diagFilesFrontTransferred == 0) { + if (diagFilesBackTransferred == 0) { char fileHeading [30 + MO_MAX_PATH_SIZE]; - auto writeLen = snprintf(fileHeading, sizeof(fileHeading), "\n\n# File %s:\n", diagFileList.front().c_str()); + auto writeLen = snprintf(fileHeading, sizeof(fileHeading), "\n\n# File %s:\n", diagFileList.back().c_str()); if (writeLen < 0 || (size_t)writeLen >= sizeof(fileHeading)) { MO_DBG_ERR("fn error: %i", ret); - diagFileList.pop_front(); + diagFileList.pop_back(); continue; } if (writeLen + written > size || //heading doesn't fit anymore, return with a bit unused buffer space and print heading the next time @@ -441,16 +441,16 @@ void DiagnosticsService::setDiagnosticsReader(std::functionseek(diagFilesFrontTransferred); + file->seek(diagFilesBackTransferred); size_t writeLen = file->read((char*)buf + written, size - written); if (writeLen < size - written) { - diagFileList.pop_front(); + diagFileList.pop_back(); } written += writeLen; } else { MO_DBG_ERR("could not open file: %s", fpath); - diagFileList.pop_front(); + diagFileList.pop_back(); } } @@ -466,8 +466,8 @@ void DiagnosticsService::setDiagnosticsReader(std::functionftpUploadStatus = UploadStatus::UploadFailed; } - free(diagPreamble); - free(diagPostamble); + MO_FREE(diagPreamble); + MO_FREE(diagPostamble); diagFileList.clear(); if (onClose) { diff --git a/src/MicroOcpp/Model/Diagnostics/DiagnosticsService.h b/src/MicroOcpp/Model/Diagnostics/DiagnosticsService.h index 7df0e788..ed3ae3c0 100644 --- a/src/MicroOcpp/Model/Diagnostics/DiagnosticsService.h +++ b/src/MicroOcpp/Model/Diagnostics/DiagnosticsService.h @@ -7,10 +7,9 @@ #include #include -#include -#include #include #include +#include #include namespace MicroOcpp { @@ -25,11 +24,11 @@ class Context; class Request; class FilesystemAdapter; -class DiagnosticsService { +class DiagnosticsService : public MemoryManaged { private: Context& context; - std::string location; + String location; unsigned int retries = 0; unsigned int retryInterval = 0; Timestamp startTime; @@ -53,8 +52,8 @@ class DiagnosticsService { char *diagPostamble = nullptr; size_t diagPostambleLen = 0; size_t diagPostambleTransferred = 0; - std::deque diagFileList; - size_t diagFilesFrontTransferred = 0; + Vector diagFileList; + size_t diagFilesBackTransferred = 0; std::unique_ptr getDiagnosticsStatusNotification(); @@ -69,7 +68,7 @@ class DiagnosticsService { //timestamps before year 2021 will be treated as "undefined" //returns empty std::string if onUpload is missing or upload cannot be scheduled for another reason //returns fileName of diagnostics file to be uploaded if upload has been scheduled - std::string requestDiagnosticsUpload(const char *location, unsigned int retries = 1, unsigned int retryInterval = 0, Timestamp startTime = Timestamp(), Timestamp stopTime = Timestamp()); + String requestDiagnosticsUpload(const char *location, unsigned int retries = 1, unsigned int retryInterval = 0, Timestamp startTime = Timestamp(), Timestamp stopTime = Timestamp()); Ocpp16::DiagnosticsStatus getDiagnosticsStatus(); diff --git a/src/MicroOcpp/Model/FirmwareManagement/FirmwareService.cpp b/src/MicroOcpp/Model/FirmwareManagement/FirmwareService.cpp index 54cf72ca..7eb006e1 100644 --- a/src/MicroOcpp/Model/FirmwareManagement/FirmwareService.cpp +++ b/src/MicroOcpp/Model/FirmwareManagement/FirmwareService.cpp @@ -22,10 +22,11 @@ #define MO_IGNORE_FW_RETR_DATE 0 #endif -using namespace MicroOcpp; +using MicroOcpp::FirmwareService; using MicroOcpp::Ocpp16::FirmwareStatus; +using MicroOcpp::Request; -FirmwareService::FirmwareService(Context& context) : context(context) { +FirmwareService::FirmwareService(Context& context) : MemoryManaged("v16.Firmware.FirmwareService"), context(context), buildNumber(makeString(getMemoryTag())), location(makeString(getMemoryTag())) { context.getOperationRegistry().registerOperation("UpdateFirmware", [this] () { return new Ocpp16::UpdateFirmware(*this);}); diff --git a/src/MicroOcpp/Model/FirmwareManagement/FirmwareService.h b/src/MicroOcpp/Model/FirmwareManagement/FirmwareService.h index e481458b..5f4671f2 100644 --- a/src/MicroOcpp/Model/FirmwareManagement/FirmwareService.h +++ b/src/MicroOcpp/Model/FirmwareManagement/FirmwareService.h @@ -12,6 +12,7 @@ #include #include #include +#include namespace MicroOcpp { @@ -30,12 +31,12 @@ enum class InstallationStatus { class Context; class Request; -class FirmwareService { +class FirmwareService : public MemoryManaged { private: Context& context; std::shared_ptr previousBuildNumberString; - std::string buildNumber; + String buildNumber; std::function downloadStatusInput; bool downloadIssued = false; @@ -50,7 +51,7 @@ class FirmwareService { Ocpp16::FirmwareStatus lastReportedStatus = Ocpp16::FirmwareStatus::Idle; bool checkedSuccessfulFwUpdate = false; - std::string location; + String location; Timestamp retreiveDate; unsigned int retries = 0; unsigned int retryInterval = 0; diff --git a/src/MicroOcpp/Model/Heartbeat/HeartbeatService.cpp b/src/MicroOcpp/Model/Heartbeat/HeartbeatService.cpp index a77eed0e..ea79cb24 100644 --- a/src/MicroOcpp/Model/Heartbeat/HeartbeatService.cpp +++ b/src/MicroOcpp/Model/Heartbeat/HeartbeatService.cpp @@ -11,7 +11,7 @@ using namespace MicroOcpp; -HeartbeatService::HeartbeatService(Context& context) : context(context) { +HeartbeatService::HeartbeatService(Context& context) : MemoryManaged("v16.Heartbeat.HeartbeatService"), context(context) { heartbeatIntervalInt = declareConfiguration("HeartbeatInterval", 86400); lastHeartbeat = mocpp_tick_ms(); diff --git a/src/MicroOcpp/Model/Heartbeat/HeartbeatService.h b/src/MicroOcpp/Model/Heartbeat/HeartbeatService.h index 0decfa40..ea632cc8 100644 --- a/src/MicroOcpp/Model/Heartbeat/HeartbeatService.h +++ b/src/MicroOcpp/Model/Heartbeat/HeartbeatService.h @@ -5,14 +5,16 @@ #ifndef MO_HEARTBEATSERVICE_H #define MO_HEARTBEATSERVICE_H -#include #include +#include +#include + namespace MicroOcpp { class Context; -class HeartbeatService { +class HeartbeatService : public MemoryManaged { private: Context& context; diff --git a/src/MicroOcpp/Model/Metering/MeterStore.cpp b/src/MicroOcpp/Model/Metering/MeterStore.cpp index d5f7041a..68e84376 100644 --- a/src/MicroOcpp/Model/Metering/MeterStore.cpp +++ b/src/MicroOcpp/Model/Metering/MeterStore.cpp @@ -16,7 +16,7 @@ using namespace MicroOcpp; TransactionMeterData::TransactionMeterData(unsigned int connectorId, unsigned int txNr, std::shared_ptr filesystem) - : connectorId(connectorId), txNr(txNr), filesystem{filesystem} { + : MemoryManaged("v16.Metering.TransactionMeterData"), connectorId(connectorId), txNr(txNr), filesystem{filesystem}, txData{makeVector>(getMemoryTag())} { if (!filesystem) { MO_DBG_DEBUG("volatile mode"); @@ -83,10 +83,10 @@ bool TransactionMeterData::addTxData(std::unique_ptr mv) { return true; } -std::vector> TransactionMeterData::retrieveStopTxData() { +Vector> TransactionMeterData::retrieveStopTxData() { if (isFinalized()) { MO_DBG_ERR("Can only retrieve once"); - return decltype(txData) {}; + return makeVector>(getMemoryTag()); } finalize(); MO_DBG_DEBUG("creating sd"); @@ -112,7 +112,7 @@ bool TransactionMeterData::restore(MeterValueBuilder& mvBuilder) { return false; //all files have same length } - auto doc = FilesystemUtils::loadJson(filesystem, fn); + auto doc = FilesystemUtils::loadJson(filesystem, fn, getMemoryTag()); if (!doc) { misses++; @@ -146,7 +146,7 @@ bool TransactionMeterData::restore(MeterValueBuilder& mvBuilder) { return true; } -MeterStore::MeterStore(std::shared_ptr filesystem) : filesystem {filesystem} { +MeterStore::MeterStore(std::shared_ptr filesystem) : MemoryManaged("v16.Metering.MeterStore"), filesystem {filesystem}, txMeterData{makeVector>(getMemoryTag())} { if (!filesystem) { MO_DBG_DEBUG("volatile mode"); diff --git a/src/MicroOcpp/Model/Metering/MeterStore.h b/src/MicroOcpp/Model/Metering/MeterStore.h index 3f14e47c..bdb67441 100644 --- a/src/MicroOcpp/Model/Metering/MeterStore.h +++ b/src/MicroOcpp/Model/Metering/MeterStore.h @@ -8,13 +8,11 @@ #include #include #include - -#include -#include +#include namespace MicroOcpp { -class TransactionMeterData { +class TransactionMeterData : public MemoryManaged { private: const unsigned int connectorId; //assignment to Transaction object const unsigned int txNr; //assignment to Transaction object @@ -24,14 +22,14 @@ class TransactionMeterData { std::shared_ptr filesystem; - std::vector> txData; + Vector> txData; public: TransactionMeterData(unsigned int connectorId, unsigned int txNr, std::shared_ptr filesystem); bool addTxData(std::unique_ptr mv); - std::vector> retrieveStopTxData(); //will invalidate internal cache + Vector> retrieveStopTxData(); //will invalidate internal cache bool restore(MeterValueBuilder& mvBuilder); //load record from memory; true if record found, false if nothing loaded @@ -42,11 +40,11 @@ class TransactionMeterData { bool isFinalized() {return finalized;} }; -class MeterStore { +class MeterStore : public MemoryManaged { private: std::shared_ptr filesystem; - std::vector> txMeterData; + Vector> txMeterData; public: MeterStore() = delete; diff --git a/src/MicroOcpp/Model/Metering/MeterValue.cpp b/src/MicroOcpp/Model/Metering/MeterValue.cpp index 8162d3eb..c00c4f34 100644 --- a/src/MicroOcpp/Model/Metering/MeterValue.cpp +++ b/src/MicroOcpp/Model/Metering/MeterValue.cpp @@ -8,9 +8,20 @@ using namespace MicroOcpp; -std::unique_ptr MeterValue::toJson() { +MeterValue::MeterValue(const Timestamp& timestamp) : + MemoryManaged("v16.Metering.MeterValue"), + timestamp(timestamp), + sampledValue(makeVector>(getMemoryTag())) { + +} + +void MeterValue::addSampledValue(std::unique_ptr sample) { + sampledValue.push_back(std::move(sample)); +} + +std::unique_ptr MeterValue::toJson() { size_t capacity = 0; - std::vector> entries; + auto entries = makeVector>(getMemoryTag()); for (auto sample = sampledValue.begin(); sample != sampledValue.end(); sample++) { auto json = (*sample)->toJson(); if (!json) { @@ -24,7 +35,7 @@ std::unique_ptr MeterValue::toJson() { capacity += JSONDATE_LENGTH + 1; capacity += JSON_OBJECT_SIZE(2); - auto result = std::unique_ptr(new DynamicJsonDocument(capacity + 100)); //TODO remove safety space + auto result = makeJsonDoc(getMemoryTag(), capacity); auto jsonPayload = result->to(); char timestampStr [JSONDATE_LENGTH + 1] = {'\0'}; @@ -56,11 +67,13 @@ ReadingContext MeterValue::getReadingContext() { return ReadingContext::NOT_SET; } -MeterValueBuilder::MeterValueBuilder(const std::vector> &samplers, +MeterValueBuilder::MeterValueBuilder(const Vector> &samplers, std::shared_ptr samplersSelectStr) : + MemoryManaged("v16.Metering.MeterValueBuilder"), samplers(samplers), - selectString(samplersSelectStr) { - + selectString(samplersSelectStr), + select_mask(makeVector(getMemoryTag())) { + updateObservedSamplers(); select_observe = selectString->getValueRevision(); } @@ -89,7 +102,7 @@ void MeterValueBuilder::updateObservedSamplers() { if (sr != sl + 1) { for (size_t i = 0; i < samplers.size(); i++) { - if (!strncmp(samplers[i]->getProperties().getMeasurand().c_str(), sstring + sl, sr - sl)) { + if (!strncmp(samplers[i]->getProperties().getMeasurand(), sstring + sl, sr - sl)) { select_mask[i] = true; select_n++; } @@ -139,11 +152,11 @@ std::unique_ptr MeterValueBuilder::deserializeSample(const JsonObjec for (JsonObject svJson : sampledValue) { //for each sampled value, search sampler with matching measurand type for (auto& sampler : samplers) { auto& properties = sampler->getProperties(); - if (!properties.getMeasurand().compare(svJson["measurand"] | "") && - !properties.getFormat().compare(svJson["format"] | "") && - !properties.getPhase().compare(svJson["phase"] | "") && - !properties.getLocation().compare(svJson["location"] | "") && - !properties.getUnit().compare(svJson["unit"] | "")) { + if (!strcmp(properties.getMeasurand(), svJson["measurand"] | "") && + !strcmp(properties.getFormat(), svJson["format"] | "") && + !strcmp(properties.getPhase(), svJson["phase"] | "") && + !strcmp(properties.getLocation(), svJson["location"] | "") && + !strcmp(properties.getUnit(), svJson["unit"] | "")) { //found correct sampler auto dVal = sampler->deserializeValue(svJson); if (dVal) { diff --git a/src/MicroOcpp/Model/Metering/MeterValue.h b/src/MicroOcpp/Model/Metering/MeterValue.h index f8fd3549..74351943 100644 --- a/src/MicroOcpp/Model/Metering/MeterValue.h +++ b/src/MicroOcpp/Model/Metering/MeterValue.h @@ -8,23 +8,23 @@ #include #include #include +#include #include #include -#include namespace MicroOcpp { -class MeterValue { +class MeterValue : public MemoryManaged { private: Timestamp timestamp; - std::vector> sampledValue; + Vector> sampledValue; public: - MeterValue(Timestamp timestamp) : timestamp(timestamp) { } + MeterValue(const Timestamp& timestamp); MeterValue(const MeterValue& other) = delete; - void addSampledValue(std::unique_ptr sample) {sampledValue.push_back(std::move(sample));} + void addSampledValue(std::unique_ptr sample); - std::unique_ptr toJson(); + std::unique_ptr toJson(); const Timestamp& getTimestamp(); void setTimestamp(Timestamp timestamp); @@ -32,17 +32,17 @@ class MeterValue { ReadingContext getReadingContext(); }; -class MeterValueBuilder { +class MeterValueBuilder : public MemoryManaged { private: - const std::vector> &samplers; + const Vector> &samplers; std::shared_ptr selectString; - std::vector select_mask; + Vector select_mask; unsigned int select_n {0}; decltype(selectString->getValueRevision()) select_observe; void updateObservedSamplers(); public: - MeterValueBuilder(const std::vector> &samplers, + MeterValueBuilder(const Vector> &samplers, std::shared_ptr samplersSelectStr); std::unique_ptr takeSample(const Timestamp& timestamp, const ReadingContext& context); diff --git a/src/MicroOcpp/Model/Metering/MeteringConnector.cpp b/src/MicroOcpp/Model/Metering/MeteringConnector.cpp index aa1f4dcc..45373443 100644 --- a/src/MicroOcpp/Model/Metering/MeteringConnector.cpp +++ b/src/MicroOcpp/Model/Metering/MeteringConnector.cpp @@ -18,7 +18,7 @@ using namespace MicroOcpp; using namespace MicroOcpp::Ocpp16; MeteringConnector::MeteringConnector(Model& model, int connectorId, MeterStore& meterStore) - : model(model), connectorId{connectorId}, meterStore(meterStore) { + : MemoryManaged("v16.Metering.MeteringConnector"), model(model), connectorId{connectorId}, meterStore(meterStore), meterData(makeVector>(getMemoryTag())), samplers(makeVector>(getMemoryTag())) { auto meterValuesSampledDataString = declareConfiguration("MeterValuesSampledData", ""); declareConfiguration("MeterValuesSampledDataMaxLength", 8, CONFIGURATION_VOLATILE, true); @@ -58,7 +58,7 @@ std::unique_ptr MeteringConnector::loop() { if ((txBreak || meterData.size() >= (size_t) meterValueCacheSizeInt->getInt()) && !meterData.empty()) { auto meterValues = std::unique_ptr(new MeterValues(std::move(meterData), connectorId, transaction)); - meterData.clear(); + meterData = makeVector>(getMemoryTag()); return std::move(meterValues); //std::move is required for some compilers even if it's not mandated by standard C++ } @@ -172,7 +172,7 @@ std::unique_ptr MeteringConnector::takeTriggeredMeterValues() { } void MeteringConnector::addMeterValueSampler(std::unique_ptr meterValueSampler) { - if (!meterValueSampler->getProperties().getMeasurand().compare("Energy.Active.Import.Register")) { + if (!strcmp(meterValueSampler->getProperties().getMeasurand(), "Energy.Active.Import.Register")) { energySamplerIndex = samplers.size(); } samplers.push_back(std::move(meterValueSampler)); @@ -232,8 +232,8 @@ std::shared_ptr MeteringConnector::getStopTxMeterData(Tran bool MeteringConnector::existsSampler(const char *measurand, size_t len) { for (size_t i = 0; i < samplers.size(); i++) { - if (samplers[i]->getProperties().getMeasurand().length() == len && - !strncmp(measurand, samplers[i]->getProperties().getMeasurand().c_str(), len)) { + if (strlen(samplers[i]->getProperties().getMeasurand()) == len && + !strncmp(measurand, samplers[i]->getProperties().getMeasurand(), len)) { return true; } } diff --git a/src/MicroOcpp/Model/Metering/MeteringConnector.h b/src/MicroOcpp/Model/Metering/MeteringConnector.h index c40075f5..881c7aa1 100644 --- a/src/MicroOcpp/Model/Metering/MeteringConnector.h +++ b/src/MicroOcpp/Model/Metering/MeteringConnector.h @@ -7,12 +7,12 @@ #include #include -#include #include #include #include #include +#include namespace MicroOcpp { @@ -21,13 +21,13 @@ class Operation; class Transaction; class MeterStore; -class MeteringConnector { +class MeteringConnector : public MemoryManaged { private: Model& model; const int connectorId; MeterStore& meterStore; - std::vector> meterData; + Vector> meterData; std::shared_ptr stopTxnData; std::unique_ptr sampledDataBuilder; @@ -45,7 +45,7 @@ class MeteringConnector { std::shared_ptr transaction; bool trackTxRunning = false; - std::vector> samplers; + Vector> samplers; int energySamplerIndex {-1}; std::shared_ptr meterValueSampleIntervalInt; diff --git a/src/MicroOcpp/Model/Metering/MeteringService.cpp b/src/MicroOcpp/Model/Metering/MeteringService.cpp index 169c2e2a..9196865f 100644 --- a/src/MicroOcpp/Model/Metering/MeteringService.cpp +++ b/src/MicroOcpp/Model/Metering/MeteringService.cpp @@ -14,7 +14,7 @@ using namespace MicroOcpp; MeteringService::MeteringService(Context& context, int numConn, std::shared_ptr filesystem) - : context(context), meterStore(filesystem) { + : MemoryManaged("v16.Metering.MeteringService"), context(context), meterStore(filesystem), connectors(makeVector>(getMemoryTag())) { //set factory defaults for Metering-related config keys declareConfiguration("MeterValuesSampledData", "Energy.Active.Import.Register,Power.Active.Import"); @@ -115,18 +115,14 @@ std::unique_ptr MeteringService::takeTriggeredMeterValues(int connector MO_DBG_ERR("connectorId out of bounds. Ignore"); return nullptr; } - auto& connector = connectors.at(connectorId); - if (connector.get()) { - auto msg = connector->takeTriggeredMeterValues(); - if (msg) { - auto meterValues = makeRequest(std::move(msg)); - meterValues->setTimeout(120000); - return meterValues; - } - MO_DBG_DEBUG("Did not take any samples for connectorId %d", connectorId); - return nullptr; + + auto msg = connectors[connectorId]->takeTriggeredMeterValues(); + if (msg) { + auto meterValues = makeRequest(std::move(msg)); + meterValues->setTimeout(120000); + return meterValues; } - MO_DBG_ERR("Could not find connector"); + MO_DBG_DEBUG("Did not take any samples for connectorId %d", connectorId); return nullptr; } @@ -140,9 +136,7 @@ void MeteringService::beginTxMeterData(Transaction *transaction) { MO_DBG_ERR("connectorId is out of bounds"); return; } - auto& connector = connectors[connectorId]; - - connector->beginTxMeterData(transaction); + connectors[connectorId]->beginTxMeterData(transaction); } std::shared_ptr MeteringService::endTxMeterData(Transaction *transaction) { @@ -155,9 +149,7 @@ std::shared_ptr MeteringService::endTxMeterData(Transactio MO_DBG_ERR("connectorId is out of bounds"); return nullptr; } - auto& connector = connectors[connectorId]; - - return connector->endTxMeterData(transaction); + return connectors[connectorId]->endTxMeterData(transaction); } void MeteringService::abortTxMeterData(unsigned int connectorId) { @@ -165,9 +157,7 @@ void MeteringService::abortTxMeterData(unsigned int connectorId) { MO_DBG_ERR("connectorId is out of bounds"); return; } - auto& connector = connectors[connectorId]; - - connector->abortTxMeterData(); + connectors[connectorId]->abortTxMeterData(); } std::shared_ptr MeteringService::getStopTxMeterData(Transaction *transaction) { @@ -180,9 +170,7 @@ std::shared_ptr MeteringService::getStopTxMeterData(Transa MO_DBG_ERR("connectorId is out of bounds"); return nullptr; } - auto& connector = connectors[connectorId]; - - return connector->getStopTxMeterData(transaction); + return connectors[connectorId]->getStopTxMeterData(transaction); } bool MeteringService::removeTxMeterData(unsigned int connectorId, unsigned int txNr) { diff --git a/src/MicroOcpp/Model/Metering/MeteringService.h b/src/MicroOcpp/Model/Metering/MeteringService.h index 76f8038d..748a0b4a 100644 --- a/src/MicroOcpp/Model/Metering/MeteringService.h +++ b/src/MicroOcpp/Model/Metering/MeteringService.h @@ -6,12 +6,12 @@ #define MO_METERINGSERVICE_H #include -#include #include #include #include #include +#include namespace MicroOcpp { @@ -19,12 +19,12 @@ class Context; class Request; class FilesystemAdapter; -class MeteringService { +class MeteringService : public MemoryManaged { private: Context& context; MeterStore meterStore; - std::vector> connectors; + Vector> connectors; public: MeteringService(Context& context, int numConnectors, std::shared_ptr filesystem); diff --git a/src/MicroOcpp/Model/Metering/SampledValue.cpp b/src/MicroOcpp/Model/Metering/SampledValue.cpp index be7cfedf..64f96152 100644 --- a/src/MicroOcpp/Model/Metering/SampledValue.cpp +++ b/src/MicroOcpp/Model/Metering/SampledValue.cpp @@ -16,17 +16,17 @@ int32_t SampledValueDeSerializer::deserialize(const char *str) { return strtol(str, nullptr, 10); } -std::string SampledValueDeSerializer::serialize(int32_t& val) { +MicroOcpp::String SampledValueDeSerializer::serialize(int32_t& val) { char str [12] = {'\0'}; snprintf(str, 12, "%" PRId32, val); - return std::string(str); + return makeString("v16.Metering.SampledValueDeSerializer", str); } -std::string SampledValueDeSerializer::serialize(float& val) { +MicroOcpp::String SampledValueDeSerializer::serialize(float& val) { char str [20]; str[0] = '\0'; snprintf(str, 20, MO_SAMPLEDVALUE_FLOAT_FORMAT, val); - return std::string(str); + return makeString("v16.Metering.SampledValueDeSerializer", str); } //helper function @@ -89,34 +89,29 @@ ReadingContext deserializeReadingContext(const char *context) { } }} //end namespaces -std::unique_ptr SampledValue::toJson() { +std::unique_ptr SampledValue::toJson() { auto value = serializeValue(); if (value.empty()) { return nullptr; } size_t capacity = 0; capacity += JSON_OBJECT_SIZE(8); - capacity += value.length() + 1 - + properties.getFormat().length() + 1 - + properties.getMeasurand().length() + 1 - + properties.getPhase().length() + 1 - + properties.getLocation().length() + 1 - + properties.getUnit().length() + 1; - auto result = std::unique_ptr(new DynamicJsonDocument(capacity + 100)); //TODO remove safety space + capacity += value.length() + 1; + auto result = makeJsonDoc("v16.Metering.SampledValue", capacity); auto payload = result->to(); payload["value"] = value; auto context_cstr = Ocpp16::serializeReadingContext(context); if (context_cstr) payload["context"] = context_cstr; - if (!properties.getFormat().empty()) + if (*properties.getFormat()) payload["format"] = properties.getFormat(); - if (!properties.getMeasurand().empty()) + if (*properties.getMeasurand()) payload["measurand"] = properties.getMeasurand(); - if (!properties.getPhase().empty()) + if (*properties.getPhase()) payload["phase"] = properties.getPhase(); - if (!properties.getLocation().empty()) + if (*properties.getLocation()) payload["location"] = properties.getLocation(); - if (!properties.getUnit().empty()) + if (*properties.getUnit()) payload["unit"] = properties.getUnit(); return result; } diff --git a/src/MicroOcpp/Model/Metering/SampledValue.h b/src/MicroOcpp/Model/Metering/SampledValue.h index a75963a5..aabc674d 100644 --- a/src/MicroOcpp/Model/Metering/SampledValue.h +++ b/src/MicroOcpp/Model/Metering/SampledValue.h @@ -9,6 +9,7 @@ #include #include +#include #include namespace MicroOcpp { @@ -18,7 +19,7 @@ class SampledValueDeSerializer { public: static T deserialize(const char *str); static bool ready(T& val); - static std::string serialize(T& val); + static String serialize(T& val); static int32_t toInteger(T& val); }; @@ -27,7 +28,7 @@ class SampledValueDeSerializer { // example class public: static int32_t deserialize(const char *str); static bool ready(int32_t& val) {return true;} //int32_t is always valid - static std::string serialize(int32_t& val); + static String serialize(int32_t& val); static int32_t toInteger(int32_t& val) {return val;} //no conversion required }; @@ -36,20 +37,25 @@ class SampledValueDeSerializer { // Used in meterValues public: static float deserialize(const char *str) {return atof(str);} static bool ready(float& val) {return true;} //float is always valid - static std::string serialize(float& val); + static String serialize(float& val); static int32_t toInteger(float& val) {return (int32_t) val;} }; class SampledValueProperties { private: - std::string format; - std::string measurand; - std::string phase; - std::string location; - std::string unit; + String format; + String measurand; + String phase; + String location; + String unit; public: - SampledValueProperties() { } + SampledValueProperties() : + format(makeString("v16.Metering.SampledValueProperties")), + measurand(makeString("v16.Metering.SampledValueProperties")), + phase(makeString("v16.Metering.SampledValueProperties")), + location(makeString("v16.Metering.SampledValueProperties")), + unit(makeString("v16.Metering.SampledValueProperties")) { } SampledValueProperties(const SampledValueProperties& other) : format(other.format), measurand(other.measurand), @@ -59,15 +65,15 @@ class SampledValueProperties { ~SampledValueProperties() = default; void setFormat(const char *format) {this->format = format;} - const std::string& getFormat() const {return format;} + const char *getFormat() const {return format.c_str();} void setMeasurand(const char *measurand) {this->measurand = measurand;} - const std::string& getMeasurand() const {return measurand;} + const char *getMeasurand() const {return measurand.c_str();} void setPhase(const char *phase) {this->phase = phase;} - const std::string& getPhase() const {return phase;} + const char *getPhase() const {return phase.c_str();} void setLocation(const char *location) {this->location = location;} - const std::string& getLocation() const {return location;} + const char *getLocation() const {return location.c_str();} void setUnit(const char *unit) {this->unit = unit;} - const std::string& getUnit() const {return unit;} + const char *getUnit() const {return unit.c_str();} }; enum class ReadingContext { @@ -91,13 +97,13 @@ class SampledValue { protected: const SampledValueProperties& properties; const ReadingContext context; - virtual std::string serializeValue() = 0; + virtual String serializeValue() = 0; public: SampledValue(const SampledValueProperties& properties, ReadingContext context) : properties(properties), context(context) { } SampledValue(const SampledValue& other) : properties(other.properties), context(other.context) { } virtual ~SampledValue() = default; - std::unique_ptr toJson(); + std::unique_ptr toJson(); virtual operator bool() = 0; virtual int32_t toInteger() = 0; @@ -106,17 +112,17 @@ class SampledValue { }; template -class SampledValueConcrete : public SampledValue { +class SampledValueConcrete : public SampledValue, public MemoryManaged { private: T value; public: - SampledValueConcrete(const SampledValueProperties& properties, ReadingContext context, const T&& value) : SampledValue(properties, context), value(value) { } - SampledValueConcrete(const SampledValueConcrete& other) : SampledValue(other), value(other.value) { } + SampledValueConcrete(const SampledValueProperties& properties, ReadingContext context, const T&& value) : SampledValue(properties, context), MemoryManaged("v16.Metering.SampledValueConcrete"), value(value) { } + SampledValueConcrete(const SampledValueConcrete& other) : SampledValue(other), MemoryManaged(other), value(other.value) { } ~SampledValueConcrete() = default; operator bool() override {return DeSerializer::ready(value);} - std::string serializeValue() override {return DeSerializer::serialize(value);} + String serializeValue() override {return DeSerializer::serialize(value);} int32_t toInteger() override { return DeSerializer::toInteger(value);} }; @@ -133,11 +139,11 @@ class SampledValueSampler { }; template -class SampledValueSamplerConcrete : public SampledValueSampler { +class SampledValueSamplerConcrete : public SampledValueSampler, public MemoryManaged { private: std::function sampler; public: - SampledValueSamplerConcrete(SampledValueProperties properties, std::function sampler) : SampledValueSampler(properties), sampler(sampler) { } + SampledValueSamplerConcrete(SampledValueProperties properties, std::function sampler) : SampledValueSampler(properties), MemoryManaged("v16.Metering.SampledValueSamplerConcrete"), sampler(sampler) { } std::unique_ptr takeValue(ReadingContext context) override { return std::unique_ptr>(new SampledValueConcrete( properties, diff --git a/src/MicroOcpp/Model/Model.cpp b/src/MicroOcpp/Model/Model.cpp index a98ab72f..571f19cb 100644 --- a/src/MicroOcpp/Model/Model.cpp +++ b/src/MicroOcpp/Model/Model.cpp @@ -4,8 +4,6 @@ #include -#include - #include #include #include @@ -27,7 +25,7 @@ using namespace MicroOcpp; -Model::Model(ProtocolVersion version, uint16_t bootNr) : version(version), bootNr(bootNr) { +Model::Model(ProtocolVersion version, uint16_t bootNr) : MemoryManaged("Model"), connectors(makeVector>(getMemoryTag())), version(version), bootNr(bootNr) { } @@ -114,7 +112,7 @@ ConnectorsCommon *Model::getConnectorsCommon() { return chargeControlCommon.get(); } -void Model::setConnectors(std::vector>&& connectors) { +void Model::setConnectors(Vector>&& connectors) { this->connectors = std::move(connectors); capabilitiesUpdated = true; } @@ -266,7 +264,7 @@ void Model::updateSupportedStandardProfiles() { return; } - std::string buf = supportedFeatureProfilesString->getString(); + auto buf = makeString(getMemoryTag(), supportedFeatureProfilesString->getString()); if (chargeControlCommon && heartbeatService && diff --git a/src/MicroOcpp/Model/Model.h b/src/MicroOcpp/Model/Model.h index fd93faba..67639ee1 100644 --- a/src/MicroOcpp/Model/Model.h +++ b/src/MicroOcpp/Model/Model.h @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -44,9 +45,9 @@ class ResetService; } #endif //MO_ENABLE_V201 -class Model { +class Model : public MemoryManaged { private: - std::vector> connectors; + Vector> connectors; std::unique_ptr transactionStore; std::unique_ptr smartChargingService; std::unique_ptr chargeControlCommon; @@ -104,7 +105,7 @@ class Model { void setConnectorsCommon(std::unique_ptr ccs); ConnectorsCommon *getConnectorsCommon(); - void setConnectors(std::vector>&& connectors); + void setConnectors(Vector>&& connectors); unsigned int getNumConnectors() const; Connector *getConnector(unsigned int connectorId); diff --git a/src/MicroOcpp/Model/Reservation/Reservation.cpp b/src/MicroOcpp/Model/Reservation/Reservation.cpp index e16618ff..eb856b5d 100644 --- a/src/MicroOcpp/Model/Reservation/Reservation.cpp +++ b/src/MicroOcpp/Model/Reservation/Reservation.cpp @@ -12,7 +12,7 @@ using namespace MicroOcpp; -Reservation::Reservation(Model& model, unsigned int slot) : model(model), slot(slot) { +Reservation::Reservation(Model& model, unsigned int slot) : MemoryManaged("v16.Reservation.Reservation"), model(model), slot(slot) { snprintf(connectorIdKey, sizeof(connectorIdKey), MO_RESERVATION_CID_KEY "%u", slot); connectorIdInt = declareConfiguration(connectorIdKey, -1, RESERVATION_FN, false, false, false); diff --git a/src/MicroOcpp/Model/Reservation/Reservation.h b/src/MicroOcpp/Model/Reservation/Reservation.h index dba888e6..daae197a 100644 --- a/src/MicroOcpp/Model/Reservation/Reservation.h +++ b/src/MicroOcpp/Model/Reservation/Reservation.h @@ -11,6 +11,7 @@ #include #include +#include #ifndef RESERVATION_FN #define RESERVATION_FN (MO_FILENAME_PREFIX "reservations.jsn") @@ -26,7 +27,7 @@ namespace MicroOcpp { class Model; -class Reservation { +class Reservation : public MemoryManaged { private: Model& model; const unsigned int slot; diff --git a/src/MicroOcpp/Model/Reservation/ReservationService.cpp b/src/MicroOcpp/Model/Reservation/ReservationService.cpp index d1131c4c..dde39aea 100644 --- a/src/MicroOcpp/Model/Reservation/ReservationService.cpp +++ b/src/MicroOcpp/Model/Reservation/ReservationService.cpp @@ -18,7 +18,7 @@ using namespace MicroOcpp; -ReservationService::ReservationService(Context& context, unsigned int numConnectors) : context(context), maxReservations((int) numConnectors - 1) { +ReservationService::ReservationService(Context& context, unsigned int numConnectors) : MemoryManaged("v16.Reservation.ReservationService"), context(context), maxReservations((int) numConnectors - 1), reservations(makeVector>(getMemoryTag())) { if (maxReservations > 0) { reservations.reserve((size_t) maxReservations); for (int i = 0; i < maxReservations; i++) { diff --git a/src/MicroOcpp/Model/Reservation/ReservationService.h b/src/MicroOcpp/Model/Reservation/ReservationService.h index 2d052594..367f1f59 100644 --- a/src/MicroOcpp/Model/Reservation/ReservationService.h +++ b/src/MicroOcpp/Model/Reservation/ReservationService.h @@ -10,6 +10,7 @@ #if MO_ENABLE_RESERVATION #include +#include #include @@ -17,12 +18,12 @@ namespace MicroOcpp { class Context; -class ReservationService { +class ReservationService : public MemoryManaged { private: Context& context; const int maxReservations; // = number of physical connectors - std::vector> reservations; + Vector> reservations; std::shared_ptr reserveConnectorZeroSupportedBool; diff --git a/src/MicroOcpp/Model/Reset/ResetService.cpp b/src/MicroOcpp/Model/Reset/ResetService.cpp index d43436c4..ebe7ca07 100644 --- a/src/MicroOcpp/Model/Reset/ResetService.cpp +++ b/src/MicroOcpp/Model/Reset/ResetService.cpp @@ -26,7 +26,7 @@ using namespace MicroOcpp; ResetService::ResetService(Context& context) - : context(context) { + : MemoryManaged("v16.Reset.ResetService"), context(context) { resetRetriesInt = declareConfiguration("ResetRetries", 2); @@ -110,7 +110,7 @@ namespace MicroOcpp { namespace Ocpp201 { ResetService::ResetService(Context& context) - : context(context) { + : MemoryManaged("v201.Reset.ResetService"), context(context), evses(makeVector(getMemoryTag())) { auto varService = context.getModel().getVariableService(); resetRetriesInt = varService->declareVariable("OCPPCommCtrlr", "ResetRetries", 0); diff --git a/src/MicroOcpp/Model/Reset/ResetService.h b/src/MicroOcpp/Model/Reset/ResetService.h index 88481815..a84e82d6 100644 --- a/src/MicroOcpp/Model/Reset/ResetService.h +++ b/src/MicroOcpp/Model/Reset/ResetService.h @@ -6,17 +6,17 @@ #define MO_RESETSERVICE_H #include -#include #include #include +#include #include namespace MicroOcpp { class Context; -class ResetService { +class ResetService : public MemoryManaged { private: Context& context; @@ -64,7 +64,7 @@ class Variable; namespace Ocpp201 { -class ResetService { +class ResetService : public MemoryManaged { private: Context& context; @@ -86,7 +86,7 @@ class ResetService { void loop(); }; - std::vector evses; + Vector evses; Evse *getEvse(unsigned int connectorId); Evse *getOrCreateEvse(unsigned int connectorId); diff --git a/src/MicroOcpp/Model/SmartCharging/SmartChargingModel.cpp b/src/MicroOcpp/Model/SmartCharging/SmartChargingModel.cpp index 4bab8476..3c71d539 100644 --- a/src/MicroOcpp/Model/SmartCharging/SmartChargingModel.cpp +++ b/src/MicroOcpp/Model/SmartCharging/SmartChargingModel.cpp @@ -18,6 +18,10 @@ ChargeRate MicroOcpp::chargeRate_min(const ChargeRate& a, const ChargeRate& b) { return res; } +ChargingSchedule::ChargingSchedule() : MemoryManaged("v16.SmartCharging.SmartChargingModel"), chargingSchedulePeriod{makeVector(getMemoryTag())} { + +} + bool ChargingSchedule::calculateLimit(const Timestamp &t, const Timestamp &startOfCharging, ChargeRate& limit, Timestamp& nextChange) { Timestamp basis = Timestamp(); //point in time to which schedule-related times are relative switch (chargingProfileKind) { @@ -116,13 +120,13 @@ bool ChargingSchedule::calculateLimit(const Timestamp &t, const Timestamp &start } } -bool ChargingSchedule::toJson(DynamicJsonDocument& doc) { +bool ChargingSchedule::toJson(JsonDoc& doc) { size_t capacity = 0; capacity += JSON_OBJECT_SIZE(5); //no of fields of ChargingSchedule capacity += JSONDATE_LENGTH + 1; //startSchedule capacity += JSON_ARRAY_SIZE(chargingSchedulePeriod.size()) + chargingSchedulePeriod.size() * JSON_OBJECT_SIZE(3); - doc = DynamicJsonDocument(capacity); + doc = initJsonDoc("v16.SmartCharging.ChargingSchedule", capacity); if (duration >= 0) { doc["duration"] = duration; } @@ -173,6 +177,10 @@ void ChargingSchedule::printSchedule(){ } } +ChargingProfile::ChargingProfile() : MemoryManaged("v16.SmartCharging.ChargingProfile") { + +} + bool ChargingProfile::calculateLimit(const Timestamp &t, const Timestamp &startOfCharging, ChargeRate& limit, Timestamp& nextChange){ if (t > validTo && validTo > MIN_TIME) { return false; //no limit defined @@ -205,14 +213,14 @@ ChargingProfilePurposeType ChargingProfile::getChargingProfilePurpose(){ return chargingProfilePurpose; } -bool ChargingProfile::toJson(DynamicJsonDocument& doc) { +bool ChargingProfile::toJson(JsonDoc& doc) { - DynamicJsonDocument chargingScheduleDoc {0}; + auto chargingScheduleDoc = initJsonDoc("v16.SmartCharging.ChargingSchedule"); if (!chargingSchedule.toJson(chargingScheduleDoc)) { return false; } - doc = DynamicJsonDocument( + doc = initJsonDoc("v16.SmartCharging.ChargingProfile", JSON_OBJECT_SIZE(9) + //no. of fields in ChargingProfile 2 * (JSONDATE_LENGTH + 1) + //validFrom and validTo chargingScheduleDoc.memoryUsage()); //nested JSON object @@ -486,7 +494,7 @@ bool MicroOcpp::loadChargingSchedule(JsonObject& json, ChargingSchedule& out) { } for (JsonObject periodJson : periodJsonArray) { - out.chargingSchedulePeriod.push_back(ChargingSchedulePeriod()); + out.chargingSchedulePeriod.emplace_back(); if (!loadChargingSchedulePeriod(periodJson, out.chargingSchedulePeriod.back())) { return false; } diff --git a/src/MicroOcpp/Model/SmartCharging/SmartChargingModel.h b/src/MicroOcpp/Model/SmartCharging/SmartChargingModel.h index 74d571b6..825d6866 100644 --- a/src/MicroOcpp/Model/SmartCharging/SmartChargingModel.h +++ b/src/MicroOcpp/Model/SmartCharging/SmartChargingModel.h @@ -18,12 +18,12 @@ #endif #include -#include #include #include #include +#include namespace MicroOcpp { @@ -75,17 +75,19 @@ class ChargingSchedulePeriod { int numberPhases = 3; }; -class ChargingSchedule { +class ChargingSchedule : public MemoryManaged { public: int duration = -1; Timestamp startSchedule; ChargingRateUnitType chargingRateUnit; - std::vector chargingSchedulePeriod; + Vector chargingSchedulePeriod; float minChargingRate = -1.0f; ChargingProfileKindType chargingProfileKind; //copied from ChargingProfile to increase cohesion of limit algorithms RecurrencyKindType recurrencyKind = RecurrencyKindType::NOT_SET; //copied from ChargingProfile to increase cohesion of limit algorithms + ChargingSchedule(); + /** * limit: output parameter * nextChange: output parameter @@ -96,7 +98,7 @@ class ChargingSchedule { */ bool calculateLimit(const Timestamp &t, const Timestamp &startOfCharging, ChargeRate& limit, Timestamp& nextChange); - bool toJson(DynamicJsonDocument& out); + bool toJson(JsonDoc& out); /* * print on console @@ -104,7 +106,7 @@ class ChargingSchedule { void printSchedule(); }; -class ChargingProfile { +class ChargingProfile : public MemoryManaged { public: int chargingProfileId = -1; int transactionId = -1; @@ -116,6 +118,8 @@ class ChargingProfile { Timestamp validTo; ChargingSchedule chargingSchedule; + ChargingProfile(); + /** * limit: output parameter * nextChange: output parameter @@ -137,7 +141,7 @@ class ChargingProfile { ChargingProfilePurposeType getChargingProfilePurpose(); - bool toJson(DynamicJsonDocument& out); + bool toJson(JsonDoc& out); /* * print on console diff --git a/src/MicroOcpp/Model/SmartCharging/SmartChargingService.cpp b/src/MicroOcpp/Model/SmartCharging/SmartChargingService.cpp index 08445340..762bd6ac 100644 --- a/src/MicroOcpp/Model/SmartCharging/SmartChargingService.cpp +++ b/src/MicroOcpp/Model/SmartCharging/SmartChargingService.cpp @@ -16,7 +16,7 @@ using namespace::MicroOcpp; SmartChargingConnector::SmartChargingConnector(Model& model, std::shared_ptr filesystem, unsigned int connectorId, ProfileStack& ChargePointMaxProfile, ProfileStack& ChargePointTxDefaultProfile) : - model(model), filesystem{filesystem}, connectorId{connectorId}, ChargePointMaxProfile(ChargePointMaxProfile), ChargePointTxDefaultProfile(ChargePointTxDefaultProfile) { + MemoryManaged("v16.SmartCharging.SmartChargingConnector"), model(model), filesystem{filesystem}, connectorId{connectorId}, ChargePointMaxProfile(ChargePointMaxProfile), ChargePointTxDefaultProfile(ChargePointTxDefaultProfile) { } @@ -267,7 +267,7 @@ std::unique_ptr SmartChargingConnector::getCompositeSchedule(i } } - periods.push_back(ChargingSchedulePeriod()); + periods.emplace_back(); float limit_opt = unit == ChargingRateUnitType_Optional::Watt ? limit.power : limit.current; periods.back().limit = limit_opt != std::numeric_limits::max() ? limit_opt : -1.f, periods.back().numberPhases = limit.nphases != std::numeric_limits::max() ? limit.nphases : -1; @@ -311,10 +311,10 @@ SmartChargingConnector *SmartChargingService::getScConnectorById(unsigned int co } SmartChargingService::SmartChargingService(Context& context, std::shared_ptr filesystem, unsigned int numConnectors) - : context(context), filesystem{filesystem}, numConnectors(numConnectors) { + : MemoryManaged("v16.SmartCharging.SmartChargingService"), context(context), filesystem{filesystem}, connectors{makeVector(getMemoryTag())}, numConnectors(numConnectors) { for (unsigned int cId = 1; cId < numConnectors; cId++) { - connectors.push_back(std::move(SmartChargingConnector(context.getModel(), filesystem, cId, ChargePointMaxProfile, ChargePointTxDefaultProfile))); + connectors.emplace_back(context.getModel(), filesystem, cId, ChargePointMaxProfile, ChargePointTxDefaultProfile); } declareConfiguration("ChargeProfileMaxStackLevel", MO_ChargeProfileMaxStackLevel, CONFIGURATION_VOLATILE, true); @@ -444,7 +444,7 @@ bool SmartChargingService::loadProfiles() { continue; //There is not a profile on the stack iStack with stacklevel iLevel. Normal case, just continue. } - auto profileDoc = FilesystemUtils::loadJson(filesystem, fn); + auto profileDoc = FilesystemUtils::loadJson(filesystem, fn, getMemoryTag()); if (!profileDoc) { success = false; MO_DBG_ERR("profile corrupt: %s, remove", fn); @@ -738,7 +738,7 @@ bool SmartChargingServiceUtils::storeProfile(std::shared_ptr return true; //not an error } - DynamicJsonDocument chargingProfileJson {0}; + auto chargingProfileJson = initJsonDoc("v16.SmartCharging.ChargingProfile"); if (!chargingProfile->toJson(chargingProfileJson)) { return false; } diff --git a/src/MicroOcpp/Model/SmartCharging/SmartChargingService.h b/src/MicroOcpp/Model/SmartCharging/SmartChargingService.h index e3a41dab..57952a72 100644 --- a/src/MicroOcpp/Model/SmartCharging/SmartChargingService.h +++ b/src/MicroOcpp/Model/SmartCharging/SmartChargingService.h @@ -13,6 +13,7 @@ #include #include #include +#include namespace MicroOcpp { @@ -27,7 +28,7 @@ class Model; using ProfileStack = std::array, MO_ChargeProfileMaxStackLevel + 1>; -class SmartChargingConnector { +class SmartChargingConnector : public MemoryManaged { private: Model& model; std::shared_ptr filesystem; @@ -72,11 +73,11 @@ class SmartChargingConnector { size_t getChargingProfilesCount(); }; -class SmartChargingService { +class SmartChargingService : public MemoryManaged { private: Context& context; std::shared_ptr filesystem; - std::vector connectors; //connectorId 0 excluded + Vector connectors; //connectorId 0 excluded SmartChargingConnector *getScConnectorById(unsigned int connectorId); unsigned int numConnectors; //connectorId 0 included diff --git a/src/MicroOcpp/Model/Transactions/Transaction.h b/src/MicroOcpp/Model/Transactions/Transaction.h index 4413102a..0e7dfd90 100644 --- a/src/MicroOcpp/Model/Transactions/Transaction.h +++ b/src/MicroOcpp/Model/Transactions/Transaction.h @@ -8,6 +8,7 @@ #ifdef __cplusplus #include +#include #include namespace MicroOcpp { @@ -44,7 +45,7 @@ class SendStatus { void setAttemptTime(const Timestamp& timestamp) {attemptTime = timestamp;} }; -class Transaction { +class Transaction : public MemoryManaged { private: ConnectorTransactionStore& context; @@ -90,6 +91,7 @@ class Transaction { public: Transaction(ConnectorTransactionStore& context, unsigned int connectorId, unsigned int txNr, bool silent = false) : + MemoryManaged("v16.Transactions.Transaction"), context(context), connectorId(connectorId), txNr(txNr), @@ -221,7 +223,7 @@ enum class TransactionEventTriggerReason : uint8_t { ResetCommand }; -class Transaction { +class Transaction : public MemoryManaged { public: // ReasonEnumType (3.67) @@ -291,10 +293,12 @@ class Transaction { StopReason stopReason = StopReason::UNDEFINED; TransactionEventTriggerReason stopTrigger = TransactionEventTriggerReason::UNDEFINED; std::unique_ptr stopIdToken; // if null, then stopIdToken equals idToken + + Transaction() : MemoryManaged("v201.Transactions.Transaction") { } }; // TransactionEventRequest (1.60.1) -class TransactionEventData { +class TransactionEventData : public MemoryManaged { public: // TransactionEventEnumType (3.80) @@ -333,7 +337,7 @@ class TransactionEventData { EvseId evse = -1; //meterValue not supported - TransactionEventData(std::shared_ptr transaction, unsigned int seqNo) : transaction(transaction), seqNo(seqNo) { } + TransactionEventData(std::shared_ptr transaction, unsigned int seqNo) : MemoryManaged("v201.Transactions.TransactionEventData"), transaction(transaction), seqNo(seqNo) { } }; } // namespace Ocpp201 diff --git a/src/MicroOcpp/Model/Transactions/TransactionDeserialize.cpp b/src/MicroOcpp/Model/Transactions/TransactionDeserialize.cpp index eb3ff237..e3c412f0 100644 --- a/src/MicroOcpp/Model/Transactions/TransactionDeserialize.cpp +++ b/src/MicroOcpp/Model/Transactions/TransactionDeserialize.cpp @@ -51,8 +51,8 @@ bool deserializeSendStatus(SendStatus& status, JsonObject in) { return true; } -bool serializeTransaction(Transaction& tx, DynamicJsonDocument& out) { - out = DynamicJsonDocument(1024); +bool serializeTransaction(Transaction& tx, JsonDoc& out) { + out = initJsonDoc("v16.Transactions.TransactionDeserialize", 1024); JsonObject state = out.to(); JsonObject sessionState = state.createNestedObject("session"); diff --git a/src/MicroOcpp/Model/Transactions/TransactionDeserialize.h b/src/MicroOcpp/Model/Transactions/TransactionDeserialize.h index b3f0549e..c8cfc427 100644 --- a/src/MicroOcpp/Model/Transactions/TransactionDeserialize.h +++ b/src/MicroOcpp/Model/Transactions/TransactionDeserialize.h @@ -6,12 +6,13 @@ #define MO_TRANSACTIONDESERIALIZE_H #include +#include #include namespace MicroOcpp { -bool serializeTransaction(Transaction& tx, DynamicJsonDocument& out); +bool serializeTransaction(Transaction& tx, JsonDoc& out); bool deserializeTransaction(Transaction& tx, JsonObject in); } diff --git a/src/MicroOcpp/Model/Transactions/TransactionService.cpp b/src/MicroOcpp/Model/Transactions/TransactionService.cpp index a1ccd4aa..c36126ac 100644 --- a/src/MicroOcpp/Model/Transactions/TransactionService.cpp +++ b/src/MicroOcpp/Model/Transactions/TransactionService.cpp @@ -24,7 +24,7 @@ using namespace MicroOcpp; using namespace MicroOcpp::Ocpp201; TransactionService::Evse::Evse(Context& context, TransactionService& txService, unsigned int evseId) : - context(context), txService(txService), evseId(evseId) { + MemoryManaged("v201.Transactions.TransactionServiceEvse"), context(context), txService(txService), evseId(evseId) { } @@ -314,10 +314,10 @@ void TransactionService::Evse::loop() { // meterValue not supported if (transaction->notifyStopIdToken && transaction->stopIdToken) { - txEvent->idToken = std::unique_ptr(new IdToken(*transaction->stopIdToken.get())); + txEvent->idToken = std::unique_ptr(new IdToken(*transaction->stopIdToken.get(), getMemoryTag())); transaction->notifyStopIdToken = false; } else if (transaction->notifyIdToken) { - txEvent->idToken = std::unique_ptr(new IdToken(transaction->idToken)); + txEvent->idToken = std::unique_ptr(new IdToken(transaction->idToken, getMemoryTag())); transaction->notifyIdToken = false; } } @@ -414,7 +414,7 @@ bool TransactionService::Evse::endAuthorization(IdToken idToken, bool validateId transaction->isAuthorized = false; transaction->notifyIdToken = true; } else if (!validateIdToken) { - transaction->stopIdToken = std::unique_ptr(new IdToken(idToken)); + transaction->stopIdToken = std::unique_ptr(new IdToken(idToken, getMemoryTag())); transaction->isAuthorized = false; transaction->notifyStopIdToken = true; } else { @@ -429,7 +429,7 @@ bool TransactionService::Evse::endAuthorization(IdToken idToken, bool validateId return false; } - authorize->setOnReceiveConfListener([tx, idToken] (JsonObject response) { + authorize->setOnReceiveConfListener([tx, idToken, this] (JsonObject response) { if (strcmp(response["idTokenInfo"]["status"] | "_Undefined", "Accepted")) { MO_DBG_DEBUG("Authorize rejected (%s), don't stop tx", idToken.get()); return; @@ -437,7 +437,7 @@ bool TransactionService::Evse::endAuthorization(IdToken idToken, bool validateId MO_DBG_DEBUG("Authorized transaction stop (%s)", idToken.get()); - tx->stopIdToken = std::unique_ptr(new IdToken(idToken)); + tx->stopIdToken = std::unique_ptr(new IdToken(idToken, getMemoryTag())); if (!tx->stopIdToken) { // OOM if (tx->active) { @@ -501,7 +501,7 @@ bool TransactionService::isTxStopPoint(TxStartStopPoint check) { return false; } -bool TransactionService::parseTxStartStopPoint(const char *csl, std::vector& dst) { +bool TransactionService::parseTxStartStopPoint(const char *csl, Vector& dst) { dst.clear(); while (*csl == ',') { @@ -547,7 +547,7 @@ bool TransactionService::parseTxStartStopPoint(const char *csl, std::vector(getMemoryTag())), txStartPointParsed(makeVector(getMemoryTag())), txStopPointParsed(makeVector(getMemoryTag())) { auto variableService = context.getModel().getVariableService(); txStartPointString = variableService->declareVariable("TxCtrlr", "TxStartPoint", "PowerPathClosed"); @@ -559,12 +559,12 @@ TransactionService::TransactionService(Context& context) : context(context) { variableService->declareVariable("AuthCtrlr", "AuthorizeRemoteStart", false, MO_VARIABLE_VOLATILE, Variable::Mutability::ReadOnly); variableService->registerValidator("TxCtrlr", "TxStartPoint", [this] (const char *value) -> bool { - std::vector validated; + auto validated = makeVector(getMemoryTag()); return this->parseTxStartStopPoint(value, validated); }); variableService->registerValidator("TxCtrlr", "TxStopPoint", [this] (const char *value) -> bool { - std::vector validated; + auto validated = makeVector(getMemoryTag()); return this->parseTxStartStopPoint(value, validated); }); diff --git a/src/MicroOcpp/Model/Transactions/TransactionService.h b/src/MicroOcpp/Model/Transactions/TransactionService.h index 20edc212..4b985b24 100644 --- a/src/MicroOcpp/Model/Transactions/TransactionService.h +++ b/src/MicroOcpp/Model/Transactions/TransactionService.h @@ -15,20 +15,20 @@ #include #include +#include #include #include -#include namespace MicroOcpp { class Context; class Variable; -class TransactionService { +class TransactionService : public MemoryManaged { public: - class Evse { + class Evse : public MemoryManaged { private: Context& context; TransactionService& txService; @@ -79,7 +79,7 @@ class TransactionService { }; Context& context; - std::vector evses; + Vector evses; Variable *txStartPointString = nullptr; Variable *txStopPointString = nullptr; @@ -88,12 +88,12 @@ class TransactionService { Variable *evConnectionTimeOutInt = nullptr; uint16_t trackTxStartPoint = -1; uint16_t trackTxStopPoint = -1; - std::vector txStartPointParsed; - std::vector txStopPointParsed; + Vector txStartPointParsed; + Vector txStopPointParsed; bool isTxStartPoint(TxStartStopPoint check); bool isTxStopPoint(TxStartStopPoint check); - bool parseTxStartStopPoint(const char *src, std::vector& dst); + bool parseTxStartStopPoint(const char *src, Vector& dst); public: TransactionService(Context& context); diff --git a/src/MicroOcpp/Model/Transactions/TransactionStore.cpp b/src/MicroOcpp/Model/Transactions/TransactionStore.cpp index ccb48333..97c62d4b 100644 --- a/src/MicroOcpp/Model/Transactions/TransactionStore.cpp +++ b/src/MicroOcpp/Model/Transactions/TransactionStore.cpp @@ -10,9 +10,11 @@ using namespace MicroOcpp; ConnectorTransactionStore::ConnectorTransactionStore(TransactionStore& context, unsigned int connectorId, std::shared_ptr filesystem) : + MemoryManaged("v16.Transactions.TransactionStore"), context(context), connectorId(connectorId), - filesystem(filesystem) { + filesystem(filesystem), + transactions{makeVector>(getMemoryTag())} { } @@ -67,7 +69,7 @@ std::shared_ptr ConnectorTransactionStore::getTransaction(unsigned return nullptr; } - auto doc = FilesystemUtils::loadJson(filesystem, fn); + auto doc = FilesystemUtils::loadJson(filesystem, fn, getMemoryTag()); if (!doc) { MO_DBG_ERR("memory corruption"); @@ -134,7 +136,7 @@ bool ConnectorTransactionStore::commit(Transaction *transaction) { return false; } - DynamicJsonDocument txDoc {0}; + auto txDoc = initJsonDoc(getMemoryTag()); if (!serializeTransaction(*transaction, txDoc)) { MO_DBG_ERR("Serialization error"); return false; @@ -174,8 +176,9 @@ bool ConnectorTransactionStore::remove(unsigned int txNr) { return filesystem->remove(fn); } -TransactionStore::TransactionStore(unsigned int nConnectors, std::shared_ptr filesystem) { - +TransactionStore::TransactionStore(unsigned int nConnectors, std::shared_ptr filesystem) : + MemoryManaged{"v16.Transactions.TransactionStore"}, connectors{makeVector>(getMemoryTag())} { + for (unsigned int i = 0; i < nConnectors; i++) { connectors.push_back(std::unique_ptr( new ConnectorTransactionStore(*this, i, filesystem))); diff --git a/src/MicroOcpp/Model/Transactions/TransactionStore.h b/src/MicroOcpp/Model/Transactions/TransactionStore.h index 9f080dcd..7e4db699 100644 --- a/src/MicroOcpp/Model/Transactions/TransactionStore.h +++ b/src/MicroOcpp/Model/Transactions/TransactionStore.h @@ -5,24 +5,22 @@ #ifndef MO_TRANSACTIONSTORE_H #define MO_TRANSACTIONSTORE_H -#include -#include - #include #include +#include namespace MicroOcpp { class TransactionStore; -class ConnectorTransactionStore { +class ConnectorTransactionStore : public MemoryManaged { private: TransactionStore& context; const unsigned int connectorId; std::shared_ptr filesystem; - std::deque> transactions; + Vector> transactions; public: ConnectorTransactionStore(TransactionStore& context, unsigned int connectorId, std::shared_ptr filesystem); @@ -40,9 +38,9 @@ class ConnectorTransactionStore { bool remove(unsigned int txNr); }; -class TransactionStore { +class TransactionStore : public MemoryManaged { private: - std::vector> connectors; + Vector> connectors; public: TransactionStore(unsigned int nConnectors, std::shared_ptr filesystem); diff --git a/src/MicroOcpp/Model/Variables/Variable.cpp b/src/MicroOcpp/Model/Variables/Variable.cpp index ac9b10c2..4f676d0f 100644 --- a/src/MicroOcpp/Model/Variables/Variable.cpp +++ b/src/MicroOcpp/Model/Variables/Variable.cpp @@ -82,6 +82,7 @@ Variable::~Variable() { void Variable::setName(const char *name) { this->variableName = name; + updateMemoryTag("v201.Variables.Variable.", name); } const char *Variable::getName() const { return variableName; @@ -321,13 +322,13 @@ class VariableString : public Variable { } ~VariableString() { - delete[] value.get(AttributeType::Actual); + MO_FREE(value.get(AttributeType::Actual)); value.get(AttributeType::Actual) = nullptr; - delete[] value.get(AttributeType::Target); + MO_FREE(value.get(AttributeType::Target)); value.get(AttributeType::Target) = nullptr; - delete[] value.get(AttributeType::MinSet); + MO_FREE(value.get(AttributeType::MinSet)); value.get(AttributeType::MinSet) = nullptr; - delete[] value.get(AttributeType::MaxSet); + MO_FREE(value.get(AttributeType::MaxSet)); value.get(AttributeType::MaxSet) = nullptr; } @@ -342,14 +343,15 @@ class VariableString : public Variable { size_t len = strlen(val); char *valNew = nullptr; if (len != 0) { - valNew = new char[len + 1]; + size_t size = len + 1; + valNew = static_cast(MO_MALLOC(getMemoryTag(), size)); if (!valNew) { MO_DBG_ERR("OOM"); return false; } - memcpy(valNew, val, len + 1); + memcpy(valNew, val, size); } - delete[] value.get(attrType); + MO_FREE(value.get(attrType)); value.get(attrType) = valNew; writeCount++; return true; diff --git a/src/MicroOcpp/Model/Variables/Variable.h b/src/MicroOcpp/Model/Variables/Variable.h index 274416ec..c64ffa46 100644 --- a/src/MicroOcpp/Model/Variables/Variable.h +++ b/src/MicroOcpp/Model/Variables/Variable.h @@ -14,11 +14,11 @@ #if MO_ENABLE_V201 #include -#include #include #include #include +#include #ifndef MO_VARIABLE_TYPECHECK #define MO_VARIABLE_TYPECHECK 1 @@ -27,7 +27,7 @@ namespace MicroOcpp { // VariableCharacteristicsType (2.51) -struct VariableCharacteristics { +struct VariableCharacteristics : public MemoryManaged { // DataEnumType (3.26) enum class DataType : uint8_t { @@ -47,6 +47,8 @@ struct VariableCharacteristics { int maxLimit = std::numeric_limits::max(); const char *valuesList = nullptr; //no copy //bool supportsMonitoring; //stored in Variable + + VariableCharacteristics() : MemoryManaged("v201.Variables.VariableCharacteristics") { } }; // SetVariableStatusEnumType (3.79) @@ -125,7 +127,7 @@ struct ComponentId { * the value of the variable. To make it use the host system's key-value store, extend this class * with a custom implementation of the virtual methods and pass its instances to MO. */ -class Variable { +class Variable : public MemoryManaged { public: //AttributeEnumType (3.2) enum class AttributeType : uint8_t { diff --git a/src/MicroOcpp/Model/Variables/VariableContainer.cpp b/src/MicroOcpp/Model/Variables/VariableContainer.cpp index 6d229c9c..1b99396d 100644 --- a/src/MicroOcpp/Model/Variables/VariableContainer.cpp +++ b/src/MicroOcpp/Model/Variables/VariableContainer.cpp @@ -23,7 +23,7 @@ VariableContainer::~VariableContainer() { } VariableContainerVolatile::VariableContainerVolatile(const char *filename, bool accessible) : - VariableContainer(filename, accessible) { + VariableContainer(filename, accessible), MemoryManaged("v201.Variables.VariableContainerVolatile.", filename), variables(makeVector>(getMemoryTag())) { } diff --git a/src/MicroOcpp/Model/Variables/VariableContainer.h b/src/MicroOcpp/Model/Variables/VariableContainer.h index 90ee41c9..fe247abe 100644 --- a/src/MicroOcpp/Model/Variables/VariableContainer.h +++ b/src/MicroOcpp/Model/Variables/VariableContainer.h @@ -9,15 +9,15 @@ #ifndef MO_VARIABLECONTAINER_H #define MO_VARIABLECONTAINER_H -#include -#include - -#include - #include #if MO_ENABLE_V201 +#include + +#include +#include + namespace MicroOcpp { class VariableContainer { @@ -53,9 +53,9 @@ class VariableContainer { virtual Variable *getVariable(const ComponentId& component, const char *variableName) const = 0; }; -class VariableContainerVolatile : public VariableContainer { +class VariableContainerVolatile : public VariableContainer, public MemoryManaged { private: - std::vector> variables; + Vector> variables; public: VariableContainerVolatile(const char *filename, bool accessible); ~VariableContainerVolatile(); diff --git a/src/MicroOcpp/Model/Variables/VariableService.cpp b/src/MicroOcpp/Model/Variables/VariableService.cpp index 267a8971..c196f805 100644 --- a/src/MicroOcpp/Model/Variables/VariableService.cpp +++ b/src/MicroOcpp/Model/Variables/VariableService.cpp @@ -27,12 +27,12 @@ namespace MicroOcpp { template VariableValidator::VariableValidator(const ComponentId& component, const char *name, std::function validate) : - component(component), name(name), validate(validate) { + MemoryManaged("v201.Variables.VariableValidator.", name), component(component), name(name), validate(validate) { } template -VariableValidator *getVariableValidator(std::vector>& collection, const ComponentId& component, const char *name) { +VariableValidator *getVariableValidator(Vector>& collection, const ComponentId& component, const char *name) { for (auto& validator : collection) { if (!strcmp(name, validator.name) && component.equals(validator.component)) { return &validator; @@ -80,7 +80,7 @@ std::shared_ptr VariableService::getContainer(const char *fil } template -bool registerVariableValidator(std::vector>& collection, const ComponentId& component, const char *name, std::function validate) { +bool registerVariableValidator(Vector>& collection, const ComponentId& component, const char *name, std::function validate) { for (auto it = collection.begin(); it != collection.end(); it++) { if (!strcmp(name, it->name) && component.equals(it->component)) { collection.erase(it); @@ -148,7 +148,13 @@ Variable *VariableService::getVariable(Variable::InternalDataType type, const Co return nullptr; } -VariableService::VariableService(Context& context, std::shared_ptr filesystem) : context(context), filesystem(filesystem) { +VariableService::VariableService(Context& context, std::shared_ptr filesystem) : + MemoryManaged("v201.Variables.VariableService"), + context(context), filesystem(filesystem), + containers(makeVector>(getMemoryTag())), + validatorInt(makeVector>(getMemoryTag())), + validatorBool(makeVector>(getMemoryTag())), + validatorString(makeVector>(getMemoryTag())) { context.getOperationRegistry().registerOperation("SetVariables", [this] () { return new Ocpp201::SetVariables(*this);}); context.getOperationRegistry().registerOperation("GetVariables", [this] () { @@ -438,7 +444,7 @@ GenericDeviceModelStatus VariableService::getBaseReport(int requestId, ReportBas return GenericDeviceModelStatus_NotSupported; } - std::vector variables; + Vector variables = makeVector(getMemoryTag()); for (const auto& container : containers) { if (!container->isAccessible()) { diff --git a/src/MicroOcpp/Model/Variables/VariableService.h b/src/MicroOcpp/Model/Variables/VariableService.h index dfc4808c..0fff37d3 100644 --- a/src/MicroOcpp/Model/Variables/VariableService.h +++ b/src/MicroOcpp/Model/Variables/VariableService.h @@ -10,7 +10,6 @@ #define MO_VARIABLESERVICE_H #include -#include #include #include #include @@ -22,6 +21,7 @@ #include #include #include +#include #ifndef MO_VARIABLE_FN #define MO_VARIABLE_FN (MO_FILENAME_PREFIX "ocpp-vars.jsn") @@ -38,7 +38,7 @@ namespace MicroOcpp { template -struct VariableValidator { +struct VariableValidator : public MemoryManaged { ComponentId component; const char *name; std::function validate; @@ -47,15 +47,15 @@ struct VariableValidator { class Context; -class VariableService { +class VariableService : public MemoryManaged { private: Context& context; std::shared_ptr filesystem; - std::vector> containers; + Vector> containers; - std::vector> validatorInt; - std::vector> validatorBool; - std::vector> validatorString; + Vector> validatorInt; + Vector> validatorBool; + Vector> validatorString; VariableValidator *getValidatorInt(const ComponentId& component, const char *name); VariableValidator *getValidatorBool(const ComponentId& component, const char *name); diff --git a/src/MicroOcpp/Operations/Authorize.cpp b/src/MicroOcpp/Operations/Authorize.cpp index f3688913..e12050be 100644 --- a/src/MicroOcpp/Operations/Authorize.cpp +++ b/src/MicroOcpp/Operations/Authorize.cpp @@ -13,7 +13,7 @@ using namespace MicroOcpp; namespace MicroOcpp { namespace Ocpp16 { -Authorize::Authorize(Model& model, const char *idTagIn) : model(model) { +Authorize::Authorize(Model& model, const char *idTagIn) : MemoryManaged("v16.Operation.", "Authorize"), model(model) { if (idTagIn && strnlen(idTagIn, IDTAG_LEN_MAX + 2) <= IDTAG_LEN_MAX) { snprintf(idTag, IDTAG_LEN_MAX + 1, "%s", idTagIn); } else { @@ -25,8 +25,8 @@ const char* Authorize::getOperationType(){ return "Authorize"; } -std::unique_ptr Authorize::createReq() { - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1) + (IDTAG_LEN_MAX + 1))); +std::unique_ptr Authorize::createReq() { + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(1) + (IDTAG_LEN_MAX + 1)); JsonObject payload = doc->to(); payload["idTag"] = idTag; return doc; @@ -54,8 +54,8 @@ void Authorize::processReq(JsonObject payload){ */ } -std::unique_ptr Authorize::createConf(){ - auto doc = std::unique_ptr(new DynamicJsonDocument(2 * JSON_OBJECT_SIZE(1))); +std::unique_ptr Authorize::createConf(){ + auto doc = makeJsonDoc(getMemoryTag(), 2 * JSON_OBJECT_SIZE(1)); JsonObject payload = doc->to(); JsonObject idTagInfo = payload.createNestedObject("idTagInfo"); idTagInfo["status"] = "Accepted"; @@ -70,7 +70,7 @@ std::unique_ptr Authorize::createConf(){ namespace MicroOcpp { namespace Ocpp201 { -Authorize::Authorize(Model& model, const IdToken& idToken) : model(model) { +Authorize::Authorize(Model& model, const IdToken& idToken) : MemoryManaged("v201.Operation.Authorize"), model(model) { this->idToken = idToken; } @@ -78,10 +78,10 @@ const char* Authorize::getOperationType(){ return "Authorize"; } -std::unique_ptr Authorize::createReq() { - auto doc = std::unique_ptr(new DynamicJsonDocument( +std::unique_ptr Authorize::createReq() { + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(1) + - JSON_OBJECT_SIZE(2))); + JSON_OBJECT_SIZE(2)); JsonObject payload = doc->to(); payload["idToken"]["idToken"] = idToken.get(); payload["idToken"]["type"] = idToken.getTypeCstr(); @@ -108,8 +108,8 @@ void Authorize::processReq(JsonObject payload){ */ } -std::unique_ptr Authorize::createConf(){ - auto doc = std::unique_ptr(new DynamicJsonDocument(2 * JSON_OBJECT_SIZE(1))); +std::unique_ptr Authorize::createConf(){ + auto doc = makeJsonDoc(getMemoryTag(), 2 * JSON_OBJECT_SIZE(1)); JsonObject payload = doc->to(); JsonObject idTagInfo = payload.createNestedObject("idTokenInfo"); idTagInfo["status"] = "Accepted"; diff --git a/src/MicroOcpp/Operations/Authorize.h b/src/MicroOcpp/Operations/Authorize.h index 0bd9f2eb..b49226ef 100644 --- a/src/MicroOcpp/Operations/Authorize.h +++ b/src/MicroOcpp/Operations/Authorize.h @@ -15,7 +15,7 @@ class Model; namespace Ocpp16 { -class Authorize : public Operation { +class Authorize : public Operation, public MemoryManaged { private: Model& model; char idTag [IDTAG_LEN_MAX + 1] = {'\0'}; @@ -24,13 +24,13 @@ class Authorize : public Operation { const char* getOperationType() override; - std::unique_ptr createReq() override; + std::unique_ptr createReq() override; void processConf(JsonObject payload) override; void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; }; @@ -44,7 +44,7 @@ class Authorize : public Operation { namespace MicroOcpp { namespace Ocpp201 { -class Authorize : public Operation { +class Authorize : public Operation, public MemoryManaged { private: Model& model; IdToken idToken; @@ -53,13 +53,13 @@ class Authorize : public Operation { const char* getOperationType() override; - std::unique_ptr createReq() override; + std::unique_ptr createReq() override; void processConf(JsonObject payload) override; void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; }; diff --git a/src/MicroOcpp/Operations/BootNotification.cpp b/src/MicroOcpp/Operations/BootNotification.cpp index e0236b0a..1f4b7c77 100644 --- a/src/MicroOcpp/Operations/BootNotification.cpp +++ b/src/MicroOcpp/Operations/BootNotification.cpp @@ -12,8 +12,9 @@ #include using MicroOcpp::Ocpp16::BootNotification; +using MicroOcpp::JsonDoc; -BootNotification::BootNotification(Model& model, std::unique_ptr payload) : model(model), credentials(std::move(payload)) { +BootNotification::BootNotification(Model& model, std::unique_ptr payload) : MemoryManaged("v16.Operation.", "BootNotification"), model(model), credentials(std::move(payload)) { } @@ -21,18 +22,18 @@ const char* BootNotification::getOperationType(){ return "BootNotification"; } -std::unique_ptr BootNotification::createReq() { +std::unique_ptr BootNotification::createReq() { if (credentials) { #if MO_ENABLE_V201 if (model.getVersion().major == 2) { - std::unique_ptr doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(2) + credentials->memoryUsage())); + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(2) + credentials->memoryUsage()); JsonObject payload = doc->to(); payload["reason"] = "PowerUp"; payload["chargingStation"] = *credentials; return doc; } #endif - return std::unique_ptr(new DynamicJsonDocument(*credentials)); + return std::unique_ptr(new JsonDoc(*credentials)); } else { MO_DBG_ERR("payload undefined"); return createEmptyDocument(); @@ -99,8 +100,8 @@ void BootNotification::processReq(JsonObject payload){ */ } -std::unique_ptr BootNotification::createConf(){ - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(3) + (JSONDATE_LENGTH + 1))); +std::unique_ptr BootNotification::createConf(){ + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(3) + (JSONDATE_LENGTH + 1)); JsonObject payload = doc->to(); //safety mechanism; in some test setups the library has to answer BootNotifications without valid system time diff --git a/src/MicroOcpp/Operations/BootNotification.h b/src/MicroOcpp/Operations/BootNotification.h index cc783fd4..c560e03f 100644 --- a/src/MicroOcpp/Operations/BootNotification.h +++ b/src/MicroOcpp/Operations/BootNotification.h @@ -19,25 +19,25 @@ class Model; namespace Ocpp16 { -class BootNotification : public Operation { +class BootNotification : public Operation, public MemoryManaged { private: Model& model; - std::unique_ptr credentials; + std::unique_ptr credentials; const char *errorCode = nullptr; public: - BootNotification(Model& model, std::unique_ptr payload); + BootNotification(Model& model, std::unique_ptr payload); ~BootNotification() = default; const char* getOperationType() override; - std::unique_ptr createReq() override; + std::unique_ptr createReq() override; void processConf(JsonObject payload) override; void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; const char *getErrorCode() override {return errorCode;} }; diff --git a/src/MicroOcpp/Operations/CancelReservation.cpp b/src/MicroOcpp/Operations/CancelReservation.cpp index b0a6206a..7741d9b9 100644 --- a/src/MicroOcpp/Operations/CancelReservation.cpp +++ b/src/MicroOcpp/Operations/CancelReservation.cpp @@ -11,12 +11,13 @@ #include using MicroOcpp::Ocpp16::CancelReservation; +using MicroOcpp::JsonDoc; -CancelReservation::CancelReservation(ReservationService& reservationService) : reservationService(reservationService) { +CancelReservation::CancelReservation(ReservationService& reservationService) : MemoryManaged("v16.Operation.", "CancelReservation"), reservationService(reservationService) { } -const char* CancelReservation::getOperationType(){ +const char* CancelReservation::getOperationType() { return "CancelReservation"; } @@ -32,8 +33,8 @@ void CancelReservation::processReq(JsonObject payload) { } } -std::unique_ptr CancelReservation::createConf(){ - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); +std::unique_ptr CancelReservation::createConf(){ + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(1)); JsonObject payload = doc->to(); if (found) { payload["status"] = "Accepted"; diff --git a/src/MicroOcpp/Operations/CancelReservation.h b/src/MicroOcpp/Operations/CancelReservation.h index 4a8dec1f..0e39bb60 100644 --- a/src/MicroOcpp/Operations/CancelReservation.h +++ b/src/MicroOcpp/Operations/CancelReservation.h @@ -17,7 +17,7 @@ class ReservationService; namespace Ocpp16 { -class CancelReservation : public Operation { +class CancelReservation : public Operation, public MemoryManaged { private: ReservationService& reservationService; bool found = false; @@ -29,7 +29,7 @@ class CancelReservation : public Operation { void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; const char *getErrorCode() override {return errorCode;} }; diff --git a/src/MicroOcpp/Operations/ChangeAvailability.cpp b/src/MicroOcpp/Operations/ChangeAvailability.cpp index 517bdabb..b0bd2da3 100644 --- a/src/MicroOcpp/Operations/ChangeAvailability.cpp +++ b/src/MicroOcpp/Operations/ChangeAvailability.cpp @@ -10,8 +10,9 @@ #include using MicroOcpp::Ocpp16::ChangeAvailability; +using MicroOcpp::JsonDoc; -ChangeAvailability::ChangeAvailability(Model& model) : model(model) { +ChangeAvailability::ChangeAvailability(Model& model) : MemoryManaged("v16.Operation.", "ChangeAvailability"), model(model) { } @@ -84,8 +85,8 @@ void ChangeAvailability::processReq(JsonObject payload) { } } -std::unique_ptr ChangeAvailability::createConf(){ - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); +std::unique_ptr ChangeAvailability::createConf(){ + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(1)); JsonObject payload = doc->to(); if (!accepted) { payload["status"] = "Rejected"; diff --git a/src/MicroOcpp/Operations/ChangeAvailability.h b/src/MicroOcpp/Operations/ChangeAvailability.h index 4e7e58af..2830d791 100644 --- a/src/MicroOcpp/Operations/ChangeAvailability.h +++ b/src/MicroOcpp/Operations/ChangeAvailability.h @@ -13,7 +13,7 @@ class Model; namespace Ocpp16 { -class ChangeAvailability : public Operation { +class ChangeAvailability : public Operation, public MemoryManaged { private: Model& model; bool scheduled = false; @@ -27,7 +27,7 @@ class ChangeAvailability : public Operation { void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; const char *getErrorCode() override {return errorCode;} }; diff --git a/src/MicroOcpp/Operations/ChangeConfiguration.cpp b/src/MicroOcpp/Operations/ChangeConfiguration.cpp index 66e29fed..15227ca2 100644 --- a/src/MicroOcpp/Operations/ChangeConfiguration.cpp +++ b/src/MicroOcpp/Operations/ChangeConfiguration.cpp @@ -9,8 +9,9 @@ #include //for tolower using MicroOcpp::Ocpp16::ChangeConfiguration; +using MicroOcpp::JsonDoc; -ChangeConfiguration::ChangeConfiguration() { +ChangeConfiguration::ChangeConfiguration() : MemoryManaged("v16.Operation.", "ChangeConfiguration") { } @@ -141,8 +142,8 @@ void ChangeConfiguration::processReq(JsonObject payload) { } } -std::unique_ptr ChangeConfiguration::createConf(){ - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); +std::unique_ptr ChangeConfiguration::createConf(){ + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(1)); JsonObject payload = doc->to(); if (notSupported) { payload["status"] = "NotSupported"; diff --git a/src/MicroOcpp/Operations/ChangeConfiguration.h b/src/MicroOcpp/Operations/ChangeConfiguration.h index 1f98a65e..3699cf6d 100644 --- a/src/MicroOcpp/Operations/ChangeConfiguration.h +++ b/src/MicroOcpp/Operations/ChangeConfiguration.h @@ -10,7 +10,7 @@ namespace MicroOcpp { namespace Ocpp16 { -class ChangeConfiguration : public Operation { +class ChangeConfiguration : public Operation, public MemoryManaged { private: bool reject = false; bool rebootRequired = false; @@ -25,7 +25,7 @@ class ChangeConfiguration : public Operation { void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; const char *getErrorCode() override {return errorCode;} diff --git a/src/MicroOcpp/Operations/ClearCache.cpp b/src/MicroOcpp/Operations/ClearCache.cpp index c5e122aa..6666ae51 100644 --- a/src/MicroOcpp/Operations/ClearCache.cpp +++ b/src/MicroOcpp/Operations/ClearCache.cpp @@ -7,8 +7,9 @@ #include using MicroOcpp::Ocpp16::ClearCache; +using MicroOcpp::JsonDoc; -ClearCache::ClearCache(std::shared_ptr filesystem) : filesystem(filesystem) { +ClearCache::ClearCache(std::shared_ptr filesystem) : MemoryManaged("v16.Operation.", "ClearCache"), filesystem(filesystem) { } @@ -31,8 +32,8 @@ void ClearCache::processReq(JsonObject payload) { }); } -std::unique_ptr ClearCache::createConf(){ - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); +std::unique_ptr ClearCache::createConf(){ + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(1)); JsonObject payload = doc->to(); if (success) { payload["status"] = "Accepted"; //"Accepted", because the intended postcondition is true diff --git a/src/MicroOcpp/Operations/ClearCache.h b/src/MicroOcpp/Operations/ClearCache.h index 0dc06d58..110ab14a 100644 --- a/src/MicroOcpp/Operations/ClearCache.h +++ b/src/MicroOcpp/Operations/ClearCache.h @@ -11,7 +11,7 @@ namespace MicroOcpp { namespace Ocpp16 { -class ClearCache : public Operation { +class ClearCache : public Operation, public MemoryManaged { private: std::shared_ptr filesystem; bool success = true; @@ -22,7 +22,7 @@ class ClearCache : public Operation { void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; }; } //end namespace Ocpp16 diff --git a/src/MicroOcpp/Operations/ClearChargingProfile.cpp b/src/MicroOcpp/Operations/ClearChargingProfile.cpp index 24b92379..e99f9bd7 100644 --- a/src/MicroOcpp/Operations/ClearChargingProfile.cpp +++ b/src/MicroOcpp/Operations/ClearChargingProfile.cpp @@ -9,8 +9,9 @@ #include using MicroOcpp::Ocpp16::ClearChargingProfile; +using MicroOcpp::JsonDoc; -ClearChargingProfile::ClearChargingProfile(SmartChargingService& scService) : scService(scService) { +ClearChargingProfile::ClearChargingProfile(SmartChargingService& scService) : MemoryManaged("v16.Operation.", "ClearChargingProfile"), scService(scService) { } @@ -69,8 +70,8 @@ void ClearChargingProfile::processReq(JsonObject payload) { matchingProfilesFound = scService.clearChargingProfile(filter); } -std::unique_ptr ClearChargingProfile::createConf(){ - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); +std::unique_ptr ClearChargingProfile::createConf(){ + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(1)); JsonObject payload = doc->to(); if (matchingProfilesFound) payload["status"] = "Accepted"; diff --git a/src/MicroOcpp/Operations/ClearChargingProfile.h b/src/MicroOcpp/Operations/ClearChargingProfile.h index 535571f8..40b7d210 100644 --- a/src/MicroOcpp/Operations/ClearChargingProfile.h +++ b/src/MicroOcpp/Operations/ClearChargingProfile.h @@ -13,7 +13,7 @@ class SmartChargingService; namespace Ocpp16 { -class ClearChargingProfile : public Operation { +class ClearChargingProfile : public Operation, public MemoryManaged { private: SmartChargingService& scService; bool matchingProfilesFound = false; @@ -24,7 +24,7 @@ class ClearChargingProfile : public Operation { void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; }; diff --git a/src/MicroOcpp/Operations/CustomOperation.cpp b/src/MicroOcpp/Operations/CustomOperation.cpp index ddd5ab32..78643d43 100644 --- a/src/MicroOcpp/Operations/CustomOperation.cpp +++ b/src/MicroOcpp/Operations/CustomOperation.cpp @@ -5,12 +5,14 @@ #include using MicroOcpp::Ocpp16::CustomOperation; +using MicroOcpp::JsonDoc; CustomOperation::CustomOperation(const char *operationType, - std::function ()> fn_createReq, + std::function ()> fn_createReq, std::function fn_processConf, std::function fn_processErr) : - operationType{operationType}, + MemoryManaged("v16.Operation.", operationType), + operationType{makeString(getMemoryTag(), operationType)}, fn_createReq{fn_createReq}, fn_processConf{fn_processConf}, fn_processErr{fn_processErr} { @@ -19,11 +21,12 @@ CustomOperation::CustomOperation(const char *operationType, CustomOperation::CustomOperation(const char *operationType, std::function fn_processReq, - std::function ()> fn_createConf, + std::function ()> fn_createConf, std::function fn_getErrorCode, std::function fn_getErrorDescription, - std::function ()> fn_getErrorDetails) : - operationType{operationType}, + std::function ()> fn_getErrorDetails) : + MemoryManaged("v16.Operation.", operationType), + operationType{makeString(getMemoryTag(), operationType)}, fn_processReq{fn_processReq}, fn_createConf{fn_createConf}, fn_getErrorCode{fn_getErrorCode}, @@ -40,7 +43,7 @@ const char* CustomOperation::getOperationType() { return operationType.c_str(); } -std::unique_ptr CustomOperation::createReq() { +std::unique_ptr CustomOperation::createReq() { return fn_createReq(); } @@ -59,7 +62,7 @@ void CustomOperation::processReq(JsonObject payload) { return fn_processReq(payload); } -std::unique_ptr CustomOperation::createConf() { +std::unique_ptr CustomOperation::createConf() { return fn_createConf(); } @@ -79,7 +82,7 @@ const char *CustomOperation::getErrorDescription() { } } -std::unique_ptr CustomOperation::getErrorDetails() { +std::unique_ptr CustomOperation::getErrorDetails() { if (fn_getErrorDetails) { return fn_getErrorDetails(); } else { diff --git a/src/MicroOcpp/Operations/CustomOperation.h b/src/MicroOcpp/Operations/CustomOperation.h index 88193fc8..02f72e88 100644 --- a/src/MicroOcpp/Operations/CustomOperation.h +++ b/src/MicroOcpp/Operations/CustomOperation.h @@ -13,38 +13,38 @@ namespace MicroOcpp { namespace Ocpp16 { -class CustomOperation : public Operation { +class CustomOperation : public Operation, public MemoryManaged { private: - std::string operationType; - std::function ()> fn_createReq; + String operationType; + std::function ()> fn_createReq; std::function fn_processConf; std::function fn_processErr; //optional std::function fn_processReq; - std::function ()> fn_createConf; + std::function ()> fn_createConf; std::function fn_getErrorCode; //optional std::function fn_getErrorDescription; //optional - std::function ()> fn_getErrorDetails; //optional + std::function ()> fn_getErrorDetails; //optional public: //for operations initiated at this device CustomOperation(const char *operationType, - std::function ()> fn_createReq, + std::function ()> fn_createReq, std::function fn_processConf, std::function fn_processErr = nullptr); //for operations receied from remote CustomOperation(const char *operationType, std::function fn_processReq, - std::function ()> fn_createConf, + std::function ()> fn_createConf, std::function fn_getErrorCode = nullptr, std::function fn_getErrorDescription = nullptr, - std::function ()> fn_getErrorDetails = nullptr); + std::function ()> fn_getErrorDetails = nullptr); ~CustomOperation(); const char* getOperationType() override; - std::unique_ptr createReq() override; + std::unique_ptr createReq() override; void processConf(JsonObject payload) override; @@ -52,10 +52,10 @@ class CustomOperation : public Operation { void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; const char *getErrorCode() override; const char *getErrorDescription() override; - std::unique_ptr getErrorDetails() override; + std::unique_ptr getErrorDetails() override; }; } //end namespace Ocpp16 diff --git a/src/MicroOcpp/Operations/DataTransfer.cpp b/src/MicroOcpp/Operations/DataTransfer.cpp index 6535bfc5..5c605039 100644 --- a/src/MicroOcpp/Operations/DataTransfer.cpp +++ b/src/MicroOcpp/Operations/DataTransfer.cpp @@ -6,17 +6,22 @@ #include using MicroOcpp::Ocpp16::DataTransfer; +using MicroOcpp::JsonDoc; + +DataTransfer::DataTransfer() : MemoryManaged("v16.Operation.", "DataTransfer") { + +} + +DataTransfer::DataTransfer(const String &msg) : MemoryManaged("v16.Operation.", "DataTransfer"), msg{makeString(getMemoryTag(), msg.c_str())} { -DataTransfer::DataTransfer(const std::string &msg) { - this->msg = msg; } const char* DataTransfer::getOperationType(){ return "DataTransfer"; } -std::unique_ptr DataTransfer::createReq() { - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(2) + (msg.length() + 1))); +std::unique_ptr DataTransfer::createReq() { + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(2) + (msg.length() + 1)); JsonObject payload = doc->to(); payload["vendorId"] = "CustomVendor"; payload["data"] = msg; @@ -24,9 +29,9 @@ std::unique_ptr DataTransfer::createReq() { } void DataTransfer::processConf(JsonObject payload){ - std::string status = payload["status"] | "Invalid"; + const char *status = payload["status"] | "Invalid"; - if (status == "Accepted") { + if (!strcmp(status, "Accepted")) { MO_DBG_DEBUG("Request has been accepted"); } else { MO_DBG_INFO("Request has been denied"); @@ -37,8 +42,8 @@ void DataTransfer::processReq(JsonObject payload) { // Do nothing - we're just required to reject these DataTransfer requests } -std::unique_ptr DataTransfer::createConf(){ - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); +std::unique_ptr DataTransfer::createConf(){ + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(1)); JsonObject payload = doc->to(); payload["status"] = "Rejected"; return doc; diff --git a/src/MicroOcpp/Operations/DataTransfer.h b/src/MicroOcpp/Operations/DataTransfer.h index 76588d27..f7967202 100644 --- a/src/MicroOcpp/Operations/DataTransfer.h +++ b/src/MicroOcpp/Operations/DataTransfer.h @@ -10,22 +10,22 @@ namespace MicroOcpp { namespace Ocpp16 { -class DataTransfer : public Operation { +class DataTransfer : public Operation, public MemoryManaged { private: - std::string msg {}; + String msg; public: - DataTransfer() {}; - DataTransfer(const std::string &msg); + DataTransfer(); + DataTransfer(const String &msg); const char* getOperationType() override; - std::unique_ptr createReq() override; + std::unique_ptr createReq() override; void processConf(JsonObject payload) override; void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; }; diff --git a/src/MicroOcpp/Operations/DeleteCertificate.cpp b/src/MicroOcpp/Operations/DeleteCertificate.cpp index 9bf42d39..b7a7267a 100644 --- a/src/MicroOcpp/Operations/DeleteCertificate.cpp +++ b/src/MicroOcpp/Operations/DeleteCertificate.cpp @@ -11,8 +11,9 @@ #include using MicroOcpp::Ocpp201::DeleteCertificate; +using MicroOcpp::JsonDoc; -DeleteCertificate::DeleteCertificate(CertificateService& certService) : certService(certService) { +DeleteCertificate::DeleteCertificate(CertificateService& certService) : MemoryManaged("v201.Operation.", "DeleteCertificate"), certService(certService) { } @@ -85,8 +86,8 @@ void DeleteCertificate::processReq(JsonObject payload) { //operation executed successfully } -std::unique_ptr DeleteCertificate::createConf(){ - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); +std::unique_ptr DeleteCertificate::createConf(){ + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(1)); JsonObject payload = doc->to(); payload["status"] = status; return doc; diff --git a/src/MicroOcpp/Operations/DeleteCertificate.h b/src/MicroOcpp/Operations/DeleteCertificate.h index bf5bf616..4c07014b 100644 --- a/src/MicroOcpp/Operations/DeleteCertificate.h +++ b/src/MicroOcpp/Operations/DeleteCertificate.h @@ -17,7 +17,7 @@ class CertificateService; namespace Ocpp201 { -class DeleteCertificate : public Operation { +class DeleteCertificate : public Operation, public MemoryManaged { private: CertificateService& certService; const char *status = nullptr; @@ -29,7 +29,7 @@ class DeleteCertificate : public Operation { void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; const char *getErrorCode() override {return errorCode;} }; diff --git a/src/MicroOcpp/Operations/DiagnosticsStatusNotification.cpp b/src/MicroOcpp/Operations/DiagnosticsStatusNotification.cpp index 6eaa3d94..8fc99913 100644 --- a/src/MicroOcpp/Operations/DiagnosticsStatusNotification.cpp +++ b/src/MicroOcpp/Operations/DiagnosticsStatusNotification.cpp @@ -8,8 +8,9 @@ #include using MicroOcpp::Ocpp16::DiagnosticsStatusNotification; +using MicroOcpp::JsonDoc; -DiagnosticsStatusNotification::DiagnosticsStatusNotification(DiagnosticsStatus status) : status(status) { +DiagnosticsStatusNotification::DiagnosticsStatusNotification(DiagnosticsStatus status) : MemoryManaged("v16.Operation.", "DiagnosticsStatusNotification"), status(status) { } @@ -31,8 +32,8 @@ const char *DiagnosticsStatusNotification::cstrFromStatus(DiagnosticsStatus stat return nullptr; //cannot be reached } -std::unique_ptr DiagnosticsStatusNotification::createReq() { - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); +std::unique_ptr DiagnosticsStatusNotification::createReq() { + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(1)); JsonObject payload = doc->to(); payload["status"] = cstrFromStatus(status); return doc; diff --git a/src/MicroOcpp/Operations/DiagnosticsStatusNotification.h b/src/MicroOcpp/Operations/DiagnosticsStatusNotification.h index 18f346a5..e21c8c07 100644 --- a/src/MicroOcpp/Operations/DiagnosticsStatusNotification.h +++ b/src/MicroOcpp/Operations/DiagnosticsStatusNotification.h @@ -11,7 +11,7 @@ namespace MicroOcpp { namespace Ocpp16 { -class DiagnosticsStatusNotification : public Operation { +class DiagnosticsStatusNotification : public Operation, public MemoryManaged { private: DiagnosticsStatus status = DiagnosticsStatus::Idle; static const char *cstrFromStatus(DiagnosticsStatus status); @@ -20,7 +20,7 @@ class DiagnosticsStatusNotification : public Operation { const char* getOperationType() override {return "DiagnosticsStatusNotification"; } - std::unique_ptr createReq() override; + std::unique_ptr createReq() override; void processConf(JsonObject payload) override; diff --git a/src/MicroOcpp/Operations/FirmwareStatusNotification.cpp b/src/MicroOcpp/Operations/FirmwareStatusNotification.cpp index b3f0a5dd..0b52c56f 100644 --- a/src/MicroOcpp/Operations/FirmwareStatusNotification.cpp +++ b/src/MicroOcpp/Operations/FirmwareStatusNotification.cpp @@ -8,8 +8,9 @@ #include using MicroOcpp::Ocpp16::FirmwareStatusNotification; +using MicroOcpp::JsonDoc; -FirmwareStatusNotification::FirmwareStatusNotification(FirmwareStatus status) : status{status} { +FirmwareStatusNotification::FirmwareStatusNotification(FirmwareStatus status) : MemoryManaged("v16.Operation.", "FirmwareStatusNotification"), status{status} { } @@ -40,8 +41,8 @@ const char *FirmwareStatusNotification::cstrFromFwStatus(FirmwareStatus status) return NULL; //cannot be reached } -std::unique_ptr FirmwareStatusNotification::createReq() { - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); +std::unique_ptr FirmwareStatusNotification::createReq() { + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(1)); JsonObject payload = doc->to(); payload["status"] = cstrFromFwStatus(status); return doc; diff --git a/src/MicroOcpp/Operations/FirmwareStatusNotification.h b/src/MicroOcpp/Operations/FirmwareStatusNotification.h index 632d2bfa..026ea45b 100644 --- a/src/MicroOcpp/Operations/FirmwareStatusNotification.h +++ b/src/MicroOcpp/Operations/FirmwareStatusNotification.h @@ -12,7 +12,7 @@ namespace MicroOcpp { namespace Ocpp16 { -class FirmwareStatusNotification : public Operation { +class FirmwareStatusNotification : public Operation, public MemoryManaged { private: FirmwareStatus status = FirmwareStatus::Idle; static const char *cstrFromFwStatus(FirmwareStatus status); @@ -21,7 +21,7 @@ class FirmwareStatusNotification : public Operation { const char* getOperationType() override {return "FirmwareStatusNotification"; } - std::unique_ptr createReq() override; + std::unique_ptr createReq() override; void processConf(JsonObject payload) override; diff --git a/src/MicroOcpp/Operations/GetBaseReport.cpp b/src/MicroOcpp/Operations/GetBaseReport.cpp index 3f3ab807..95414481 100644 --- a/src/MicroOcpp/Operations/GetBaseReport.cpp +++ b/src/MicroOcpp/Operations/GetBaseReport.cpp @@ -11,8 +11,9 @@ #include using MicroOcpp::Ocpp201::GetBaseReport; +using MicroOcpp::JsonDoc; -GetBaseReport::GetBaseReport(VariableService& variableService) : variableService(variableService) { +GetBaseReport::GetBaseReport(VariableService& variableService) : MemoryManaged("v201.Operation.", "GetBaseReport"), variableService(variableService) { } @@ -47,9 +48,9 @@ void GetBaseReport::processReq(JsonObject payload) { status = variableService.getBaseReport(requestId, reportBase); } -std::unique_ptr GetBaseReport::createConf(){ +std::unique_ptr GetBaseReport::createConf(){ - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(1)); JsonObject payload = doc->to(); const char *statusCstr = ""; diff --git a/src/MicroOcpp/Operations/GetBaseReport.h b/src/MicroOcpp/Operations/GetBaseReport.h index 2eb85ab2..f23b7e81 100644 --- a/src/MicroOcpp/Operations/GetBaseReport.h +++ b/src/MicroOcpp/Operations/GetBaseReport.h @@ -9,9 +9,8 @@ #if MO_ENABLE_V201 -#include - #include +#include #include namespace MicroOcpp { @@ -20,7 +19,7 @@ class VariableService; namespace Ocpp201 { -class GetBaseReport : public Operation { +class GetBaseReport : public Operation, public MemoryManaged { private: VariableService& variableService; @@ -34,7 +33,7 @@ class GetBaseReport : public Operation { void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; const char *getErrorCode() override {return errorCode;} diff --git a/src/MicroOcpp/Operations/GetCompositeSchedule.cpp b/src/MicroOcpp/Operations/GetCompositeSchedule.cpp index 54958f36..760e0e2f 100644 --- a/src/MicroOcpp/Operations/GetCompositeSchedule.cpp +++ b/src/MicroOcpp/Operations/GetCompositeSchedule.cpp @@ -8,8 +8,9 @@ #include using MicroOcpp::Ocpp16::GetCompositeSchedule; +using MicroOcpp::JsonDoc; -GetCompositeSchedule::GetCompositeSchedule(Model& model, SmartChargingService& scService) : model(model), scService(scService) { +GetCompositeSchedule::GetCompositeSchedule(Model& model, SmartChargingService& scService) : MemoryManaged("v16.Operation.", "GetCompositeSchedule"), model(model), scService(scService) { } @@ -40,12 +41,12 @@ void GetCompositeSchedule::processReq(JsonObject payload) { } } -std::unique_ptr GetCompositeSchedule::createConf(){ +std::unique_ptr GetCompositeSchedule::createConf(){ bool success = false; auto chargingSchedule = scService.getCompositeSchedule((unsigned int) connectorId, duration, chargingRateUnit); - DynamicJsonDocument chargingScheduleDoc {0}; + JsonDoc chargingScheduleDoc {0}; if (chargingSchedule) { success = chargingSchedule->toJson(chargingScheduleDoc); @@ -58,9 +59,9 @@ std::unique_ptr GetCompositeSchedule::createConf(){ } if (success && chargingSchedule) { - auto doc = std::unique_ptr(new DynamicJsonDocument( + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(4) + - chargingScheduleDoc.memoryUsage())); + chargingScheduleDoc.memoryUsage()); JsonObject payload = doc->to(); payload["status"] = "Accepted"; payload["connectorId"] = connectorId; @@ -68,7 +69,7 @@ std::unique_ptr GetCompositeSchedule::createConf(){ payload["chargingSchedule"] = chargingScheduleDoc; return doc; } else { - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(1)); JsonObject payload = doc->to(); payload["status"] = "Rejected"; return doc; diff --git a/src/MicroOcpp/Operations/GetCompositeSchedule.h b/src/MicroOcpp/Operations/GetCompositeSchedule.h index 800c8f33..30e427c4 100644 --- a/src/MicroOcpp/Operations/GetCompositeSchedule.h +++ b/src/MicroOcpp/Operations/GetCompositeSchedule.h @@ -15,7 +15,7 @@ class Model; namespace Ocpp16 { -class GetCompositeSchedule : public Operation { +class GetCompositeSchedule : public Operation, public MemoryManaged { private: Model& model; SmartChargingService& scService; @@ -31,7 +31,7 @@ class GetCompositeSchedule : public Operation { void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; const char *getErrorCode() override {return errorCode;} }; diff --git a/src/MicroOcpp/Operations/GetConfiguration.cpp b/src/MicroOcpp/Operations/GetConfiguration.cpp index be08e9dd..1ba7ef0a 100644 --- a/src/MicroOcpp/Operations/GetConfiguration.cpp +++ b/src/MicroOcpp/Operations/GetConfiguration.cpp @@ -7,8 +7,9 @@ #include using MicroOcpp::Ocpp16::GetConfiguration; +using MicroOcpp::JsonDoc; -GetConfiguration::GetConfiguration() { +GetConfiguration::GetConfiguration() : MemoryManaged("v16.Operation.", "GetConfiguration"), keys{makeVector(getMemoryTag())} { } @@ -20,14 +21,14 @@ void GetConfiguration::processReq(JsonObject payload) { JsonArray requestedKeys = payload["key"]; for (size_t i = 0; i < requestedKeys.size(); i++) { - keys.push_back(requestedKeys[i].as()); + keys.push_back(makeString(getMemoryTag(), requestedKeys[i].as())); } } -std::unique_ptr GetConfiguration::createConf(){ +std::unique_ptr GetConfiguration::createConf(){ - std::vector configurations; - std::vector unknownKeys; + Vector configurations = makeVector(getMemoryTag()); + Vector unknownKeys = makeVector(getMemoryTag()); auto containers = getConfigurationContainersPublic(); @@ -82,10 +83,10 @@ std::unique_ptr GetConfiguration::createConf(){ MO_DBG_DEBUG("GetConfiguration capacity: %zu", jcapacity); - std::unique_ptr doc; + std::unique_ptr doc; if (jcapacity <= MO_MAX_JSON_CAPACITY) { - doc = std::unique_ptr(new DynamicJsonDocument(jcapacity)); + doc = makeJsonDoc(getMemoryTag(), jcapacity); } if (!doc || doc->capacity() < jcapacity) { diff --git a/src/MicroOcpp/Operations/GetConfiguration.h b/src/MicroOcpp/Operations/GetConfiguration.h index 94fb5d06..c6781119 100644 --- a/src/MicroOcpp/Operations/GetConfiguration.h +++ b/src/MicroOcpp/Operations/GetConfiguration.h @@ -6,15 +6,14 @@ #define MO_GETCONFIGURATION_H #include - -#include +#include namespace MicroOcpp { namespace Ocpp16 { -class GetConfiguration : public Operation { +class GetConfiguration : public Operation, public MemoryManaged { private: - std::vector keys; + Vector keys; const char *errorCode {nullptr}; const char *errorDescription = ""; @@ -25,7 +24,7 @@ class GetConfiguration : public Operation { void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; const char *getErrorCode() override {return errorCode;} const char *getErrorDescription() override {return errorDescription;} diff --git a/src/MicroOcpp/Operations/GetDiagnostics.cpp b/src/MicroOcpp/Operations/GetDiagnostics.cpp index 93aec8a7..e3bab7eb 100644 --- a/src/MicroOcpp/Operations/GetDiagnostics.cpp +++ b/src/MicroOcpp/Operations/GetDiagnostics.cpp @@ -8,8 +8,9 @@ #include using MicroOcpp::Ocpp16::GetDiagnostics; +using MicroOcpp::JsonDoc; -GetDiagnostics::GetDiagnostics(DiagnosticsService& diagService) : diagService(diagService) { +GetDiagnostics::GetDiagnostics(DiagnosticsService& diagService) : MemoryManaged("v16.Operation.", "GetDiagnostics"), diagService(diagService), fileName(makeString(getMemoryTag())) { } @@ -50,13 +51,13 @@ void GetDiagnostics::processReq(JsonObject payload) { fileName = diagService.requestDiagnosticsUpload(location, (unsigned int) retries, (unsigned int) retryInterval, startTime, stopTime); } -std::unique_ptr GetDiagnostics::createConf(){ +std::unique_ptr GetDiagnostics::createConf(){ if (fileName.empty()) { return createEmptyDocument(); } else { - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1) + fileName.length() + 1)); + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(1)); JsonObject payload = doc->to(); - payload["fileName"] = fileName; + payload["fileName"] = fileName.c_str(); return doc; } } diff --git a/src/MicroOcpp/Operations/GetDiagnostics.h b/src/MicroOcpp/Operations/GetDiagnostics.h index f9c11635..704f9199 100644 --- a/src/MicroOcpp/Operations/GetDiagnostics.h +++ b/src/MicroOcpp/Operations/GetDiagnostics.h @@ -14,10 +14,10 @@ class DiagnosticsService; namespace Ocpp16 { -class GetDiagnostics : public Operation { +class GetDiagnostics : public Operation, public MemoryManaged { private: DiagnosticsService& diagService; - std::string fileName; + String fileName; const char *errorCode = nullptr; public: @@ -27,7 +27,7 @@ class GetDiagnostics : public Operation { void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; const char *getErrorCode() override {return errorCode;} }; diff --git a/src/MicroOcpp/Operations/GetInstalledCertificateIds.cpp b/src/MicroOcpp/Operations/GetInstalledCertificateIds.cpp index c0ca9028..87d4c2dd 100644 --- a/src/MicroOcpp/Operations/GetInstalledCertificateIds.cpp +++ b/src/MicroOcpp/Operations/GetInstalledCertificateIds.cpp @@ -11,8 +11,9 @@ #include using MicroOcpp::Ocpp201::GetInstalledCertificateIds; +using MicroOcpp::JsonDoc; -GetInstalledCertificateIds::GetInstalledCertificateIds(CertificateService& certService) : certService(certService) { +GetInstalledCertificateIds::GetInstalledCertificateIds(CertificateService& certService) : MemoryManaged("v201.Operation.", "GetInstalledCertificateIds"), certService(certService), certificateHashDataChain(makeVector(getMemoryTag())) { } @@ -23,7 +24,7 @@ void GetInstalledCertificateIds::processReq(JsonObject payload) { return; } - std::vector certificateType; + auto certificateType = makeVector(getMemoryTag()); for (const char *certificateTypeCstr : payload["certificateType"].as()) { if (!strcmp(certificateTypeCstr, "V2GRootCertificate")) { certificateType.push_back(GetCertificateIdType_V2GRootCertificate); @@ -65,7 +66,7 @@ void GetInstalledCertificateIds::processReq(JsonObject payload) { //operation executed successfully } -std::unique_ptr GetInstalledCertificateIds::createConf() { +std::unique_ptr GetInstalledCertificateIds::createConf() { size_t capacity = JSON_OBJECT_SIZE(2) + //payload root @@ -79,7 +80,7 @@ std::unique_ptr GetInstalledCertificateIds::createConf() { * 2 + 3; //issuerNameHash, issuerKeyHash and serialNumber as hex-endoded cstring } - auto doc = std::unique_ptr(new DynamicJsonDocument(capacity)); + auto doc = makeJsonDoc(getMemoryTag(), capacity); JsonObject payload = doc->to(); payload["status"] = status; diff --git a/src/MicroOcpp/Operations/GetInstalledCertificateIds.h b/src/MicroOcpp/Operations/GetInstalledCertificateIds.h index 86c4cfad..28a31c92 100644 --- a/src/MicroOcpp/Operations/GetInstalledCertificateIds.h +++ b/src/MicroOcpp/Operations/GetInstalledCertificateIds.h @@ -18,10 +18,10 @@ class CertificateService; namespace Ocpp201 { -class GetInstalledCertificateIds : public Operation { +class GetInstalledCertificateIds : public Operation, public MemoryManaged { private: CertificateService& certService; - std::vector certificateHashDataChain; + Vector certificateHashDataChain; const char *status = nullptr; const char *errorCode = nullptr; public: @@ -31,7 +31,7 @@ class GetInstalledCertificateIds : public Operation { void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; const char *getErrorCode() override {return errorCode;} }; diff --git a/src/MicroOcpp/Operations/GetLocalListVersion.cpp b/src/MicroOcpp/Operations/GetLocalListVersion.cpp index b1428791..f2c8a058 100644 --- a/src/MicroOcpp/Operations/GetLocalListVersion.cpp +++ b/src/MicroOcpp/Operations/GetLocalListVersion.cpp @@ -12,8 +12,9 @@ #include using MicroOcpp::Ocpp16::GetLocalListVersion; +using MicroOcpp::JsonDoc; -GetLocalListVersion::GetLocalListVersion(Model& model) : model(model) { +GetLocalListVersion::GetLocalListVersion(Model& model) : MemoryManaged("v16.Operation.", "GetLocalListVersion"), model(model) { } @@ -25,8 +26,8 @@ void GetLocalListVersion::processReq(JsonObject payload) { //empty payload } -std::unique_ptr GetLocalListVersion::createConf(){ - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); +std::unique_ptr GetLocalListVersion::createConf(){ + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(1)); JsonObject payload = doc->to(); if (auto authService = model.getAuthorizationService()) { diff --git a/src/MicroOcpp/Operations/GetLocalListVersion.h b/src/MicroOcpp/Operations/GetLocalListVersion.h index 2d0581ac..554f7a6b 100644 --- a/src/MicroOcpp/Operations/GetLocalListVersion.h +++ b/src/MicroOcpp/Operations/GetLocalListVersion.h @@ -17,7 +17,7 @@ class Model; namespace Ocpp16 { -class GetLocalListVersion : public Operation { +class GetLocalListVersion : public Operation, public MemoryManaged { private: Model& model; public: @@ -27,7 +27,7 @@ class GetLocalListVersion : public Operation { void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; }; } //end namespace Ocpp16 diff --git a/src/MicroOcpp/Operations/GetVariables.cpp b/src/MicroOcpp/Operations/GetVariables.cpp index e9500f8b..af75f644 100644 --- a/src/MicroOcpp/Operations/GetVariables.cpp +++ b/src/MicroOcpp/Operations/GetVariables.cpp @@ -12,10 +12,16 @@ #include //for tolower +using MicroOcpp::Ocpp201::GetVariableData; using MicroOcpp::Ocpp201::GetVariables; +using MicroOcpp::JsonDoc; + +GetVariableData::GetVariableData(const char *memory_tag) : componentName{makeString(memory_tag)}, variableName{makeString(memory_tag)} { + +} + +GetVariables::GetVariables(VariableService& variableService) : MemoryManaged("v201.Operation.", "GetVariableData"), variableService(variableService), queries(makeVector(getMemoryTag())) { -GetVariables::GetVariables(VariableService& variableService) : variableService(variableService) { - } const char* GetVariables::getOperationType(){ @@ -25,7 +31,7 @@ const char* GetVariables::getOperationType(){ void GetVariables::processReq(JsonObject payload) { for (JsonObject getVariable : payload["getVariableData"].as()) { - queries.emplace_back(); + queries.emplace_back(getMemoryTag()); auto& data = queries.back(); if (getVariable.containsKey("attributeType")) { @@ -75,7 +81,7 @@ void GetVariables::processReq(JsonObject payload) { } } -std::unique_ptr GetVariables::createConf(){ +std::unique_ptr GetVariables::createConf(){ // process GetVariables queries for (auto& query : queries) { @@ -127,7 +133,7 @@ std::unique_ptr GetVariables::createConf(){ data.variableName.length() + 1; } - auto doc = std::unique_ptr(new DynamicJsonDocument(capacity)); + auto doc = makeJsonDoc(getMemoryTag(), capacity); JsonObject payload = doc->to(); JsonArray getVariableResult = payload.createNestedArray("getVariableResult"); diff --git a/src/MicroOcpp/Operations/GetVariables.h b/src/MicroOcpp/Operations/GetVariables.h index a28f744b..a0360e62 100644 --- a/src/MicroOcpp/Operations/GetVariables.h +++ b/src/MicroOcpp/Operations/GetVariables.h @@ -9,10 +9,8 @@ #if MO_ENABLE_V201 -#include -#include - #include +#include #include namespace MicroOcpp { @@ -26,20 +24,22 @@ namespace Ocpp201 { struct GetVariableData { // GetVariableDataType Variable::AttributeType attributeType = Variable::AttributeType::Actual; - std::string componentName; + String componentName; int componentEvseId = -1; int componentEvseConnectorId = -1; - std::string variableName; + String variableName; // GetVariableResultType GetVariableStatus attributeStatus; Variable *variable = nullptr; + + GetVariableData(const char *memory_tag = nullptr); }; -class GetVariables : public Operation { +class GetVariables : public Operation, public MemoryManaged { private: VariableService& variableService; - std::vector queries; + Vector queries; const char *errorCode = nullptr; public: @@ -49,7 +49,7 @@ class GetVariables : public Operation { void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; const char *getErrorCode() override {return errorCode;} diff --git a/src/MicroOcpp/Operations/Heartbeat.cpp b/src/MicroOcpp/Operations/Heartbeat.cpp index 040fba05..4dfd0439 100644 --- a/src/MicroOcpp/Operations/Heartbeat.cpp +++ b/src/MicroOcpp/Operations/Heartbeat.cpp @@ -8,8 +8,9 @@ #include using MicroOcpp::Ocpp16::Heartbeat; +using MicroOcpp::JsonDoc; -Heartbeat::Heartbeat(Model& model) : model(model) { +Heartbeat::Heartbeat(Model& model) : MemoryManaged("v16.Operation.", "Heartbeat"), model(model) { } @@ -17,7 +18,7 @@ const char* Heartbeat::getOperationType(){ return "Heartbeat"; } -std::unique_ptr Heartbeat::createReq() { +std::unique_ptr Heartbeat::createReq() { return createEmptyDocument(); } @@ -44,8 +45,8 @@ void Heartbeat::processReq(JsonObject payload) { } -std::unique_ptr Heartbeat::createConf(){ - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1) + (JSONDATE_LENGTH + 1))); +std::unique_ptr Heartbeat::createConf(){ + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(1) + (JSONDATE_LENGTH + 1)); JsonObject payload = doc->to(); //safety mechanism; in some test setups the library could have to answer Heartbeats without valid system time diff --git a/src/MicroOcpp/Operations/Heartbeat.h b/src/MicroOcpp/Operations/Heartbeat.h index 83d4c01d..b3ce6a0e 100644 --- a/src/MicroOcpp/Operations/Heartbeat.h +++ b/src/MicroOcpp/Operations/Heartbeat.h @@ -13,7 +13,7 @@ class Model; namespace Ocpp16 { -class Heartbeat : public Operation { +class Heartbeat : public Operation, public MemoryManaged { private: Model& model; public: @@ -21,13 +21,13 @@ class Heartbeat : public Operation { const char* getOperationType() override; - std::unique_ptr createReq() override; + std::unique_ptr createReq() override; void processConf(JsonObject payload) override; void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; }; } //end namespace Ocpp16 diff --git a/src/MicroOcpp/Operations/InstallCertificate.cpp b/src/MicroOcpp/Operations/InstallCertificate.cpp index dee8c57e..b9859501 100644 --- a/src/MicroOcpp/Operations/InstallCertificate.cpp +++ b/src/MicroOcpp/Operations/InstallCertificate.cpp @@ -10,8 +10,9 @@ #include using MicroOcpp::Ocpp201::InstallCertificate; +using MicroOcpp::JsonDoc; -InstallCertificate::InstallCertificate(CertificateService& certService) : certService(certService) { +InstallCertificate::InstallCertificate(CertificateService& certService) : MemoryManaged("v201.Operation.", "InstallCertificate"), certService(certService) { } @@ -74,8 +75,8 @@ void InstallCertificate::processReq(JsonObject payload) { //operation executed successfully } -std::unique_ptr InstallCertificate::createConf(){ - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); +std::unique_ptr InstallCertificate::createConf(){ + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(1)); JsonObject payload = doc->to(); payload["status"] = status; return doc; diff --git a/src/MicroOcpp/Operations/InstallCertificate.h b/src/MicroOcpp/Operations/InstallCertificate.h index b3ded1c1..e2c22b55 100644 --- a/src/MicroOcpp/Operations/InstallCertificate.h +++ b/src/MicroOcpp/Operations/InstallCertificate.h @@ -17,7 +17,7 @@ class CertificateService; namespace Ocpp201 { -class InstallCertificate : public Operation { +class InstallCertificate : public Operation, public MemoryManaged { private: CertificateService& certService; const char *status = nullptr; @@ -29,7 +29,7 @@ class InstallCertificate : public Operation { void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; const char *getErrorCode() override {return errorCode;} }; diff --git a/src/MicroOcpp/Operations/MeterValues.cpp b/src/MicroOcpp/Operations/MeterValues.cpp index b00be35f..905e63dc 100644 --- a/src/MicroOcpp/Operations/MeterValues.cpp +++ b/src/MicroOcpp/Operations/MeterValues.cpp @@ -9,16 +9,17 @@ #include using MicroOcpp::Ocpp16::MeterValues; +using MicroOcpp::JsonDoc; #define ENERGY_METER_TIMEOUT_MS 30 * 1000 //after waiting for 30s, send MeterValues without missing readings //can only be used for echo server debugging -MeterValues::MeterValues() { +MeterValues::MeterValues() : MemoryManaged("v16.Operation.", "MeterValues") { } -MeterValues::MeterValues(std::vector>&& meterValue, unsigned int connectorId, std::shared_ptr transaction) - : meterValue{std::move(meterValue)}, connectorId{connectorId}, transaction{transaction} { +MeterValues::MeterValues(Vector>&& meterValue, unsigned int connectorId, std::shared_ptr transaction) + : MemoryManaged("v16.Operation.", "MeterValues"), meterValue{std::move(meterValue)}, connectorId{connectorId}, transaction{transaction} { } @@ -30,11 +31,11 @@ const char* MeterValues::getOperationType(){ return "MeterValues"; } -std::unique_ptr MeterValues::createReq() { +std::unique_ptr MeterValues::createReq() { size_t capacity = 0; - std::vector> entries; + auto entries = makeVector>(getMemoryTag()); for (auto value = meterValue.begin(); value != meterValue.end(); value++) { auto entry = (*value)->toJson(); if (entry) { @@ -48,7 +49,7 @@ std::unique_ptr MeterValues::createReq() { capacity += JSON_OBJECT_SIZE(3); capacity += JSON_ARRAY_SIZE(entries.size()); - auto doc = std::unique_ptr(new DynamicJsonDocument(capacity + 100)); //TODO remove safety space + auto doc = makeJsonDoc(getMemoryTag(), capacity); auto payload = doc->to(); payload["connectorId"] = connectorId; @@ -77,6 +78,6 @@ void MeterValues::processReq(JsonObject payload) { } -std::unique_ptr MeterValues::createConf(){ +std::unique_ptr MeterValues::createConf(){ return createEmptyDocument(); } diff --git a/src/MicroOcpp/Operations/MeterValues.h b/src/MicroOcpp/Operations/MeterValues.h index 3760e2aa..012151d5 100644 --- a/src/MicroOcpp/Operations/MeterValues.h +++ b/src/MicroOcpp/Operations/MeterValues.h @@ -6,10 +6,9 @@ #define MO_METERVALUES_H #include +#include #include -#include - namespace MicroOcpp { class MeterValue; @@ -17,16 +16,16 @@ class Transaction; namespace Ocpp16 { -class MeterValues : public Operation { +class MeterValues : public Operation, public MemoryManaged { private: - std::vector> meterValue; + Vector> meterValue; unsigned int connectorId = 0; std::shared_ptr transaction; public: - MeterValues(std::vector>&& meterValue, unsigned int connectorId, std::shared_ptr transaction = nullptr); + MeterValues(Vector>&& meterValue, unsigned int connectorId, std::shared_ptr transaction = nullptr); MeterValues(); //for debugging only. Make this for the server pendant @@ -34,13 +33,13 @@ class MeterValues : public Operation { const char* getOperationType() override; - std::unique_ptr createReq() override; + std::unique_ptr createReq() override; void processConf(JsonObject payload) override; void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; }; } //end namespace Ocpp16 diff --git a/src/MicroOcpp/Operations/NotifyReport.cpp b/src/MicroOcpp/Operations/NotifyReport.cpp index 9cbff693..0528e452 100644 --- a/src/MicroOcpp/Operations/NotifyReport.cpp +++ b/src/MicroOcpp/Operations/NotifyReport.cpp @@ -11,11 +11,11 @@ #include #include -using MicroOcpp::Ocpp201::NotifyReport; using namespace MicroOcpp::Ocpp201; +using MicroOcpp::JsonDoc; -NotifyReport::NotifyReport(Model& model, int requestId, const Timestamp& generatedAt, bool tbc, int seqNo, const std::vector& reportData) - : model(model), requestId(requestId), generatedAt(generatedAt), tbc(tbc), seqNo(seqNo), reportData(reportData) { +NotifyReport::NotifyReport(Model& model, int requestId, const Timestamp& generatedAt, bool tbc, int seqNo, const Vector& reportData) + : MemoryManaged("v201.Operation.", "NotifyReport"), model(model), requestId(requestId), generatedAt(generatedAt), tbc(tbc), seqNo(seqNo), reportData(reportData) { } @@ -23,7 +23,7 @@ const char* NotifyReport::getOperationType() { return "NotifyReport"; } -std::unique_ptr NotifyReport::createReq() { +std::unique_ptr NotifyReport::createReq() { #define VALUE_BUFSIZE 30 // for primitives (int) @@ -81,7 +81,7 @@ std::unique_ptr NotifyReport::createReq() { capacity += JSON_OBJECT_SIZE(2); //variableCharacteristics composite: only send two data fields } - auto doc = std::unique_ptr(new DynamicJsonDocument(capacity)); + auto doc = makeJsonDoc(getMemoryTag(), capacity); JsonObject payload = doc->to(); payload["requestId"] = requestId; diff --git a/src/MicroOcpp/Operations/NotifyReport.h b/src/MicroOcpp/Operations/NotifyReport.h index 285808e2..1a092678 100644 --- a/src/MicroOcpp/Operations/NotifyReport.h +++ b/src/MicroOcpp/Operations/NotifyReport.h @@ -11,8 +11,7 @@ #include #include - -#include +#include namespace MicroOcpp { @@ -21,7 +20,7 @@ class Variable; namespace Ocpp201 { -class NotifyReport : public Operation { +class NotifyReport : public Operation, public MemoryManaged { private: Model& model; @@ -29,14 +28,14 @@ class NotifyReport : public Operation { Timestamp generatedAt; bool tbc; int seqNo; - std::vector reportData; + Vector reportData; public: - NotifyReport(Model& model, int requestId, const Timestamp& generatedAt, bool tbc, int seqNo, const std::vector& reportData); + NotifyReport(Model& model, int requestId, const Timestamp& generatedAt, bool tbc, int seqNo, const Vector& reportData); const char* getOperationType() override; - std::unique_ptr createReq() override; + std::unique_ptr createReq() override; void processConf(JsonObject payload) override; }; diff --git a/src/MicroOcpp/Operations/RemoteStartTransaction.cpp b/src/MicroOcpp/Operations/RemoteStartTransaction.cpp index 668b6738..4e0d7163 100644 --- a/src/MicroOcpp/Operations/RemoteStartTransaction.cpp +++ b/src/MicroOcpp/Operations/RemoteStartTransaction.cpp @@ -11,8 +11,9 @@ #include using MicroOcpp::Ocpp16::RemoteStartTransaction; +using MicroOcpp::JsonDoc; -RemoteStartTransaction::RemoteStartTransaction(Model& model) : model(model) { +RemoteStartTransaction::RemoteStartTransaction(Model& model) : MemoryManaged("v16.Operation.", "RemoteStartTransaction"), model(model) { } @@ -115,8 +116,8 @@ void RemoteStartTransaction::processReq(JsonObject payload) { } } -std::unique_ptr RemoteStartTransaction::createConf(){ - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); +std::unique_ptr RemoteStartTransaction::createConf(){ + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(1)); JsonObject payload = doc->to(); if (accepted) { payload["status"] = "Accepted"; @@ -126,8 +127,8 @@ std::unique_ptr RemoteStartTransaction::createConf(){ return doc; } -std::unique_ptr RemoteStartTransaction::createReq() { - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); +std::unique_ptr RemoteStartTransaction::createReq() { + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(1)); JsonObject payload = doc->to(); payload["idTag"] = "A0000000"; diff --git a/src/MicroOcpp/Operations/RemoteStartTransaction.h b/src/MicroOcpp/Operations/RemoteStartTransaction.h index c286e1fd..411578bd 100644 --- a/src/MicroOcpp/Operations/RemoteStartTransaction.h +++ b/src/MicroOcpp/Operations/RemoteStartTransaction.h @@ -15,7 +15,7 @@ class ChargingProfile; namespace Ocpp16 { -class RemoteStartTransaction : public Operation { +class RemoteStartTransaction : public Operation, public MemoryManaged { private: Model& model; @@ -28,13 +28,13 @@ class RemoteStartTransaction : public Operation { const char* getOperationType() override; - std::unique_ptr createReq() override; + std::unique_ptr createReq() override; void processConf(JsonObject payload) override; void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; const char *getErrorCode() override {return errorCode;} const char *getErrorDescription() override {return errorDescription;} diff --git a/src/MicroOcpp/Operations/RemoteStopTransaction.cpp b/src/MicroOcpp/Operations/RemoteStopTransaction.cpp index 7e1cdd54..8a36699a 100644 --- a/src/MicroOcpp/Operations/RemoteStopTransaction.cpp +++ b/src/MicroOcpp/Operations/RemoteStopTransaction.cpp @@ -8,8 +8,9 @@ #include using MicroOcpp::Ocpp16::RemoteStopTransaction; +using MicroOcpp::JsonDoc; -RemoteStopTransaction::RemoteStopTransaction(Model& model) : model(model) { +RemoteStopTransaction::RemoteStopTransaction(Model& model) : MemoryManaged("v16.Operation.", "RemoteStopTransaction"), model(model) { } @@ -34,8 +35,8 @@ void RemoteStopTransaction::processReq(JsonObject payload) { } } -std::unique_ptr RemoteStopTransaction::createConf(){ - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); +std::unique_ptr RemoteStopTransaction::createConf(){ + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(1)); JsonObject payload = doc->to(); if (accepted){ payload["status"] = "Accepted"; diff --git a/src/MicroOcpp/Operations/RemoteStopTransaction.h b/src/MicroOcpp/Operations/RemoteStopTransaction.h index a3d6ac21..2a42d695 100644 --- a/src/MicroOcpp/Operations/RemoteStopTransaction.h +++ b/src/MicroOcpp/Operations/RemoteStopTransaction.h @@ -13,7 +13,7 @@ class Model; namespace Ocpp16 { -class RemoteStopTransaction : public Operation { +class RemoteStopTransaction : public Operation, public MemoryManaged { private: Model& model; bool accepted = false; @@ -26,7 +26,7 @@ class RemoteStopTransaction : public Operation { void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; const char *getErrorCode() override {return errorCode;} }; diff --git a/src/MicroOcpp/Operations/RequestStartTransaction.cpp b/src/MicroOcpp/Operations/RequestStartTransaction.cpp index 29ac3627..9b35783b 100644 --- a/src/MicroOcpp/Operations/RequestStartTransaction.cpp +++ b/src/MicroOcpp/Operations/RequestStartTransaction.cpp @@ -11,8 +11,9 @@ #include using MicroOcpp::Ocpp201::RequestStartTransaction; +using MicroOcpp::JsonDoc; -RequestStartTransaction::RequestStartTransaction(TransactionService& txService) : txService(txService) { +RequestStartTransaction::RequestStartTransaction(TransactionService& txService) : MemoryManaged("v201.Operation.", "RequestStartTransaction"), txService(txService) { } @@ -45,9 +46,9 @@ void RequestStartTransaction::processReq(JsonObject payload) { status = txService.requestStartTransaction(evseId, remoteStartId, idToken, transactionId); } -std::unique_ptr RequestStartTransaction::createConf(){ +std::unique_ptr RequestStartTransaction::createConf(){ - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(2))); + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(2)); JsonObject payload = doc->to(); const char *statusCstr = ""; diff --git a/src/MicroOcpp/Operations/RequestStartTransaction.h b/src/MicroOcpp/Operations/RequestStartTransaction.h index 9a4b6ab4..d28ade11 100644 --- a/src/MicroOcpp/Operations/RequestStartTransaction.h +++ b/src/MicroOcpp/Operations/RequestStartTransaction.h @@ -9,8 +9,8 @@ #if MO_ENABLE_V201 -#include #include +#include #include namespace MicroOcpp { @@ -19,7 +19,7 @@ class TransactionService; namespace Ocpp201 { -class RequestStartTransaction : public Operation { +class RequestStartTransaction : public Operation, public MemoryManaged { private: TransactionService& txService; @@ -34,7 +34,7 @@ class RequestStartTransaction : public Operation { void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; const char *getErrorCode() override {return errorCode;} diff --git a/src/MicroOcpp/Operations/RequestStopTransaction.cpp b/src/MicroOcpp/Operations/RequestStopTransaction.cpp index 6baf7bcb..9752895a 100644 --- a/src/MicroOcpp/Operations/RequestStopTransaction.cpp +++ b/src/MicroOcpp/Operations/RequestStopTransaction.cpp @@ -11,8 +11,9 @@ #include using MicroOcpp::Ocpp201::RequestStopTransaction; +using MicroOcpp::JsonDoc; -RequestStopTransaction::RequestStopTransaction(TransactionService& txService) : txService(txService) { +RequestStopTransaction::RequestStopTransaction(TransactionService& txService) : MemoryManaged("v201.Operation.", "RequestStopTransaction"), txService(txService) { } @@ -32,9 +33,9 @@ void RequestStopTransaction::processReq(JsonObject payload) { status = txService.requestStopTransaction(payload["transactionId"].as()); } -std::unique_ptr RequestStopTransaction::createConf(){ +std::unique_ptr RequestStopTransaction::createConf(){ - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(1)); JsonObject payload = doc->to(); const char *statusCstr = ""; diff --git a/src/MicroOcpp/Operations/RequestStopTransaction.h b/src/MicroOcpp/Operations/RequestStopTransaction.h index 40222c7a..ba8f545c 100644 --- a/src/MicroOcpp/Operations/RequestStopTransaction.h +++ b/src/MicroOcpp/Operations/RequestStopTransaction.h @@ -9,8 +9,8 @@ #if MO_ENABLE_V201 -#include #include +#include #include namespace MicroOcpp { @@ -19,7 +19,7 @@ class TransactionService; namespace Ocpp201 { -class RequestStopTransaction : public Operation { +class RequestStopTransaction : public Operation, public MemoryManaged { private: TransactionService& txService; @@ -33,7 +33,7 @@ class RequestStopTransaction : public Operation { void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; const char *getErrorCode() override {return errorCode;} diff --git a/src/MicroOcpp/Operations/ReserveNow.cpp b/src/MicroOcpp/Operations/ReserveNow.cpp index fe7eb473..26857fdb 100644 --- a/src/MicroOcpp/Operations/ReserveNow.cpp +++ b/src/MicroOcpp/Operations/ReserveNow.cpp @@ -14,8 +14,9 @@ #include using MicroOcpp::Ocpp16::ReserveNow; +using MicroOcpp::JsonDoc; -ReserveNow::ReserveNow(Model& model) : model(model) { +ReserveNow::ReserveNow(Model& model) : MemoryManaged("v16.Operation.", "ReserveNow"), model(model) { } @@ -114,8 +115,8 @@ void ReserveNow::processReq(JsonObject payload) { } } -std::unique_ptr ReserveNow::createConf(){ - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); +std::unique_ptr ReserveNow::createConf(){ + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(1)); JsonObject payload = doc->to(); if (reservationStatus) { diff --git a/src/MicroOcpp/Operations/ReserveNow.h b/src/MicroOcpp/Operations/ReserveNow.h index e907a716..cf162ad6 100644 --- a/src/MicroOcpp/Operations/ReserveNow.h +++ b/src/MicroOcpp/Operations/ReserveNow.h @@ -17,7 +17,7 @@ class Model; namespace Ocpp16 { -class ReserveNow : public Operation { +class ReserveNow : public Operation, public MemoryManaged { private: Model& model; const char *errorCode = nullptr; @@ -31,7 +31,7 @@ class ReserveNow : public Operation { void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; const char *getErrorCode() override {return errorCode;} }; diff --git a/src/MicroOcpp/Operations/Reset.cpp b/src/MicroOcpp/Operations/Reset.cpp index 87c8f855..bf2b7592 100644 --- a/src/MicroOcpp/Operations/Reset.cpp +++ b/src/MicroOcpp/Operations/Reset.cpp @@ -8,8 +8,9 @@ #include using MicroOcpp::Ocpp16::Reset; +using MicroOcpp::JsonDoc; -Reset::Reset(Model& model) : model(model) { +Reset::Reset(Model& model) : MemoryManaged("v16.Operation.", "Reset"), model(model) { } @@ -42,8 +43,8 @@ void Reset::processReq(JsonObject payload) { } } -std::unique_ptr Reset::createConf() { - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); +std::unique_ptr Reset::createConf() { + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(1)); JsonObject payload = doc->to(); payload["status"] = resetAccepted ? "Accepted" : "Rejected"; return doc; @@ -56,7 +57,7 @@ std::unique_ptr Reset::createConf() { namespace MicroOcpp { namespace Ocpp201 { -Reset::Reset(ResetService& resetService) : resetService(resetService) { +Reset::Reset(ResetService& resetService) : MemoryManaged("v201.Operation.", "Reset"), resetService(resetService) { } @@ -90,8 +91,8 @@ void Reset::processReq(JsonObject payload) { status = resetService.initiateReset(type, evseId); } -std::unique_ptr Reset::createConf() { - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); +std::unique_ptr Reset::createConf() { + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(1)); JsonObject payload = doc->to(); const char *statusCstr = ""; diff --git a/src/MicroOcpp/Operations/Reset.h b/src/MicroOcpp/Operations/Reset.h index 212a17c2..53aca0d0 100644 --- a/src/MicroOcpp/Operations/Reset.h +++ b/src/MicroOcpp/Operations/Reset.h @@ -15,7 +15,7 @@ class Model; namespace Ocpp16 { -class Reset : public Operation { +class Reset : public Operation, public MemoryManaged { private: Model& model; bool resetAccepted {false}; @@ -26,7 +26,7 @@ class Reset : public Operation { void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; }; } //end namespace Ocpp16 @@ -39,7 +39,7 @@ namespace Ocpp201 { class ResetService; -class Reset : public Operation { +class Reset : public Operation, public MemoryManaged { private: ResetService& resetService; ResetStatus status; @@ -51,7 +51,7 @@ class Reset : public Operation { void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; const char *getErrorCode() override {return errorCode;} }; diff --git a/src/MicroOcpp/Operations/SendLocalList.cpp b/src/MicroOcpp/Operations/SendLocalList.cpp index 128f5d8a..45f0dfbe 100644 --- a/src/MicroOcpp/Operations/SendLocalList.cpp +++ b/src/MicroOcpp/Operations/SendLocalList.cpp @@ -11,8 +11,9 @@ #include using MicroOcpp::Ocpp16::SendLocalList; +using MicroOcpp::JsonDoc; -SendLocalList::SendLocalList(AuthorizationService& authService) : authService(authService) { +SendLocalList::SendLocalList(AuthorizationService& authService) : MemoryManaged("v16.Operation.", "SendLocalList"), authService(authService) { } @@ -55,8 +56,8 @@ void SendLocalList::processReq(JsonObject payload) { updateFailure = !authService.updateLocalList(localAuthorizationList, listVersion, differential); } -std::unique_ptr SendLocalList::createConf(){ - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); +std::unique_ptr SendLocalList::createConf(){ + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(1)); JsonObject payload = doc->to(); if (versionMismatch) { diff --git a/src/MicroOcpp/Operations/SendLocalList.h b/src/MicroOcpp/Operations/SendLocalList.h index bbd1fa2d..d58265bd 100644 --- a/src/MicroOcpp/Operations/SendLocalList.h +++ b/src/MicroOcpp/Operations/SendLocalList.h @@ -17,7 +17,7 @@ class AuthorizationService; namespace Ocpp16 { -class SendLocalList : public Operation { +class SendLocalList : public Operation, public MemoryManaged { private: AuthorizationService& authService; const char *errorCode = nullptr; @@ -32,7 +32,7 @@ class SendLocalList : public Operation { void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; const char *getErrorCode() override {return errorCode;} }; diff --git a/src/MicroOcpp/Operations/SetChargingProfile.cpp b/src/MicroOcpp/Operations/SetChargingProfile.cpp index 20cf5ca8..355d70d3 100644 --- a/src/MicroOcpp/Operations/SetChargingProfile.cpp +++ b/src/MicroOcpp/Operations/SetChargingProfile.cpp @@ -9,8 +9,9 @@ #include using MicroOcpp::Ocpp16::SetChargingProfile; +using MicroOcpp::JsonDoc; -SetChargingProfile::SetChargingProfile(Model& model, SmartChargingService& scService) : model(model), scService(scService) { +SetChargingProfile::SetChargingProfile(Model& model, SmartChargingService& scService) : MemoryManaged("v16.Operation.", "SetChargingProfile"), model(model), scService(scService) { } @@ -84,8 +85,8 @@ void SetChargingProfile::processReq(JsonObject payload) { accepted = scService.setChargingProfile(connectorId, std::move(chargingProfile)); } -std::unique_ptr SetChargingProfile::createConf(){ - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); +std::unique_ptr SetChargingProfile::createConf(){ + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(1)); JsonObject payload = doc->to(); if (accepted) { payload["status"] = "Accepted"; diff --git a/src/MicroOcpp/Operations/SetChargingProfile.h b/src/MicroOcpp/Operations/SetChargingProfile.h index b68e96dc..1ce35f1e 100644 --- a/src/MicroOcpp/Operations/SetChargingProfile.h +++ b/src/MicroOcpp/Operations/SetChargingProfile.h @@ -14,7 +14,7 @@ class SmartChargingService; namespace Ocpp16 { -class SetChargingProfile : public Operation { +class SetChargingProfile : public Operation, public MemoryManaged { private: Model& model; SmartChargingService& scService; @@ -31,7 +31,7 @@ class SetChargingProfile : public Operation { void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; const char *getErrorCode() override {return errorCode;} const char *getErrorDescription() override {return errorDescription;} diff --git a/src/MicroOcpp/Operations/SetVariables.cpp b/src/MicroOcpp/Operations/SetVariables.cpp index 6333353e..23bd043d 100644 --- a/src/MicroOcpp/Operations/SetVariables.cpp +++ b/src/MicroOcpp/Operations/SetVariables.cpp @@ -10,9 +10,15 @@ #include #include +using MicroOcpp::Ocpp201::SetVariableData; using MicroOcpp::Ocpp201::SetVariables; +using MicroOcpp::JsonDoc; -SetVariables::SetVariables(VariableService& variableService) : variableService(variableService) { +SetVariableData::SetVariableData(const char *memory_tag) : componentName{makeString(memory_tag)}, variableName{makeString(memory_tag)} { + +} + +SetVariables::SetVariables(VariableService& variableService) : MemoryManaged("v201.Operation.", "SetVariables"), variableService(variableService), queries(makeVector(getMemoryTag())) { } @@ -23,7 +29,7 @@ const char* SetVariables::getOperationType(){ void SetVariables::processReq(JsonObject payload) { for (JsonObject setVariable : payload["setVariableData"].as()) { - queries.emplace_back(); + queries.emplace_back(getMemoryTag()); auto& data = queries.back(); if (setVariable.containsKey("attributeType")) { @@ -93,7 +99,7 @@ void SetVariables::processReq(JsonObject payload) { } } -std::unique_ptr SetVariables::createConf(){ +std::unique_ptr SetVariables::createConf(){ size_t capacity = JSON_ARRAY_SIZE(queries.size()); for (const auto& data : queries) { capacity += @@ -104,7 +110,7 @@ std::unique_ptr SetVariables::createConf(){ JSON_OBJECT_SIZE(2) + // variable data.variableName.length() + 1; } - auto doc = std::unique_ptr(new DynamicJsonDocument(capacity)); + auto doc = makeJsonDoc(getMemoryTag(), capacity); JsonObject payload = doc->to(); JsonArray setVariableResult = payload.createNestedArray("setVariableResult"); diff --git a/src/MicroOcpp/Operations/SetVariables.h b/src/MicroOcpp/Operations/SetVariables.h index 83527a4e..fb0ca889 100644 --- a/src/MicroOcpp/Operations/SetVariables.h +++ b/src/MicroOcpp/Operations/SetVariables.h @@ -9,10 +9,8 @@ #if MO_ENABLE_V201 -#include -#include - #include +#include #include namespace MicroOcpp { @@ -27,19 +25,21 @@ struct SetVariableData { // SetVariableDataType Variable::AttributeType attributeType = Variable::AttributeType::Actual; const char *attributeValue; // will become invalid after processReq - std::string componentName; + String componentName; int componentEvseId = -1; int componentEvseConnectorId = -1; - std::string variableName; + String variableName; // SetVariableResultType SetVariableStatus attributeStatus; + + SetVariableData(const char *memory_tag = nullptr); }; -class SetVariables : public Operation { +class SetVariables : public Operation, public MemoryManaged { private: VariableService& variableService; - std::vector queries; + Vector queries; const char *errorCode = nullptr; public: @@ -49,7 +49,7 @@ class SetVariables : public Operation { void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; const char *getErrorCode() override {return errorCode;} diff --git a/src/MicroOcpp/Operations/StartTransaction.cpp b/src/MicroOcpp/Operations/StartTransaction.cpp index ccd5d89e..907baaf3 100644 --- a/src/MicroOcpp/Operations/StartTransaction.cpp +++ b/src/MicroOcpp/Operations/StartTransaction.cpp @@ -12,9 +12,10 @@ #include using MicroOcpp::Ocpp16::StartTransaction; +using MicroOcpp::JsonDoc; -StartTransaction::StartTransaction(Model& model, std::shared_ptr transaction) : model(model), transaction(transaction) { +StartTransaction::StartTransaction(Model& model, std::shared_ptr transaction) : MemoryManaged("v16.Operation.", "StartTransaction"), model(model), transaction(transaction) { } @@ -26,12 +27,12 @@ const char* StartTransaction::getOperationType() { return "StartTransaction"; } -std::unique_ptr StartTransaction::createReq() { +std::unique_ptr StartTransaction::createReq() { - auto doc = std::unique_ptr(new DynamicJsonDocument( + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(6) + (IDTAG_LEN_MAX + 1) + - (JSONDATE_LENGTH + 1))); + (JSONDATE_LENGTH + 1)); JsonObject payload = doc->to(); @@ -93,8 +94,8 @@ void StartTransaction::processReq(JsonObject payload) { } -std::unique_ptr StartTransaction::createConf() { - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(2))); +std::unique_ptr StartTransaction::createConf() { + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(2)); JsonObject payload = doc->to(); JsonObject idTagInfo = payload.createNestedObject("idTagInfo"); diff --git a/src/MicroOcpp/Operations/StartTransaction.h b/src/MicroOcpp/Operations/StartTransaction.h index e01d0461..a73b5368 100644 --- a/src/MicroOcpp/Operations/StartTransaction.h +++ b/src/MicroOcpp/Operations/StartTransaction.h @@ -17,7 +17,7 @@ class Transaction; namespace Ocpp16 { -class StartTransaction : public Operation { +class StartTransaction : public Operation, public MemoryManaged { private: Model& model; std::shared_ptr transaction; @@ -29,13 +29,13 @@ class StartTransaction : public Operation { const char* getOperationType() override; - std::unique_ptr createReq() override; + std::unique_ptr createReq() override; void processConf(JsonObject payload) override; void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; }; } //end namespace Ocpp16 diff --git a/src/MicroOcpp/Operations/StatusNotification.cpp b/src/MicroOcpp/Operations/StatusNotification.cpp index 75e5cf1f..c5fb1a60 100644 --- a/src/MicroOcpp/Operations/StatusNotification.cpp +++ b/src/MicroOcpp/Operations/StatusNotification.cpp @@ -46,7 +46,7 @@ const char *cstrFromOcppEveState(ChargePointStatus state) { namespace Ocpp16 { StatusNotification::StatusNotification(int connectorId, ChargePointStatus currentStatus, const Timestamp ×tamp, ErrorData errorData) - : connectorId(connectorId), currentStatus(currentStatus), timestamp(timestamp), errorData(errorData) { + : MemoryManaged("v16.Operation.", "StatusNotification"), connectorId(connectorId), currentStatus(currentStatus), timestamp(timestamp), errorData(errorData) { if (currentStatus != ChargePointStatus_UNDEFINED) { MO_DBG_INFO("New status: %s (connectorId %d)", cstrFromOcppEveState(currentStatus), connectorId); @@ -57,8 +57,8 @@ const char* StatusNotification::getOperationType(){ return "StatusNotification"; } -std::unique_ptr StatusNotification::createReq() { - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(7) + (JSONDATE_LENGTH + 1))); +std::unique_ptr StatusNotification::createReq() { + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(7) + (JSONDATE_LENGTH + 1)); JsonObject payload = doc->to(); payload["connectorId"] = connectorId; @@ -107,7 +107,7 @@ void StatusNotification::processReq(JsonObject payload) { /* * For debugging only */ -std::unique_ptr StatusNotification::createConf(){ +std::unique_ptr StatusNotification::createConf(){ return createEmptyDocument(); } @@ -120,7 +120,7 @@ namespace MicroOcpp { namespace Ocpp201 { StatusNotification::StatusNotification(EvseId evseId, ChargePointStatus currentStatus, const Timestamp ×tamp) - : evseId(evseId), timestamp(timestamp), currentStatus(currentStatus) { + : MemoryManaged("v201.Operation.", "StatusNotification"), evseId(evseId), timestamp(timestamp), currentStatus(currentStatus) { } @@ -128,8 +128,8 @@ const char* StatusNotification::getOperationType(){ return "StatusNotification"; } -std::unique_ptr StatusNotification::createReq() { - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(4) + (JSONDATE_LENGTH + 1))); +std::unique_ptr StatusNotification::createReq() { + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(4) + (JSONDATE_LENGTH + 1)); JsonObject payload = doc->to(); char timestamp_cstr[JSONDATE_LENGTH + 1] = {'\0'}; diff --git a/src/MicroOcpp/Operations/StatusNotification.h b/src/MicroOcpp/Operations/StatusNotification.h index b218ed7e..2e65dcec 100644 --- a/src/MicroOcpp/Operations/StatusNotification.h +++ b/src/MicroOcpp/Operations/StatusNotification.h @@ -17,7 +17,7 @@ const char *cstrFromOcppEveState(ChargePointStatus state); namespace Ocpp16 { -class StatusNotification : public Operation { +class StatusNotification : public Operation, public MemoryManaged { private: int connectorId = 1; ChargePointStatus currentStatus = ChargePointStatus_UNDEFINED; @@ -28,13 +28,13 @@ class StatusNotification : public Operation { const char* getOperationType() override; - std::unique_ptr createReq() override; + std::unique_ptr createReq() override; void processConf(JsonObject payload) override; void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; int getConnectorId() { return connectorId; @@ -51,7 +51,7 @@ class StatusNotification : public Operation { namespace MicroOcpp { namespace Ocpp201 { -class StatusNotification : public Operation { +class StatusNotification : public Operation, public MemoryManaged { private: EvseId evseId; Timestamp timestamp; @@ -61,7 +61,7 @@ class StatusNotification : public Operation { const char* getOperationType() override; - std::unique_ptr createReq() override; + std::unique_ptr createReq() override; void processConf(JsonObject payload) override; }; diff --git a/src/MicroOcpp/Operations/StopTransaction.cpp b/src/MicroOcpp/Operations/StopTransaction.cpp index 49b9b029..ecc495cc 100644 --- a/src/MicroOcpp/Operations/StopTransaction.cpp +++ b/src/MicroOcpp/Operations/StopTransaction.cpp @@ -13,14 +13,15 @@ #include using MicroOcpp::Ocpp16::StopTransaction; +using MicroOcpp::JsonDoc; StopTransaction::StopTransaction(Model& model, std::shared_ptr transaction) - : model(model), transaction(transaction) { + : MemoryManaged("v16.Operation.", "StopTransaction"), model(model), transaction(transaction) { } -StopTransaction::StopTransaction(Model& model, std::shared_ptr transaction, std::vector> transactionData) - : model(model), transaction(transaction), transactionData(std::move(transactionData)) { +StopTransaction::StopTransaction(Model& model, std::shared_ptr transaction, Vector> transactionData) + : MemoryManaged("v16.Operation.", "StopTransaction"), model(model), transaction(transaction), transactionData(std::move(transactionData)) { } @@ -28,7 +29,7 @@ const char* StopTransaction::getOperationType() { return "StopTransaction"; } -std::unique_ptr StopTransaction::createReq() { +std::unique_ptr StopTransaction::createReq() { /* * Adjust timestamps in case they were taken before initial Clock setting @@ -67,7 +68,7 @@ std::unique_ptr StopTransaction::createReq() { } } - std::vector> txDataJson; + auto txDataJson = makeVector>(getMemoryTag()); size_t txDataJson_size = 0; for (auto mv = transactionData.begin(); mv != transactionData.end(); mv++) { auto mvJson = (*mv)->toJson(); @@ -78,17 +79,17 @@ std::unique_ptr StopTransaction::createReq() { txDataJson.emplace_back(std::move(mvJson)); } - DynamicJsonDocument txDataDoc = DynamicJsonDocument(JSON_ARRAY_SIZE(txDataJson.size()) + txDataJson_size); + auto txDataDoc = initJsonDoc(getMemoryTag(), JSON_ARRAY_SIZE(txDataJson.size()) + txDataJson_size); for (auto mvJson = txDataJson.begin(); mvJson != txDataJson.end(); mvJson++) { txDataDoc.add(**mvJson); } - auto doc = std::unique_ptr(new DynamicJsonDocument( + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(6) + //total of 6 fields (IDTAG_LEN_MAX + 1) + //stop idTag (JSONDATE_LENGTH + 1) + //timestamp string (REASON_LEN_MAX + 1) + //reason string - txDataDoc.capacity())); + txDataDoc.capacity()); JsonObject payload = doc->to(); if (transaction->getStopIdTag() && *transaction->getStopIdTag()) { @@ -148,8 +149,8 @@ void StopTransaction::processReq(JsonObject payload) { */ } -std::unique_ptr StopTransaction::createConf(){ - auto doc = std::unique_ptr(new DynamicJsonDocument(2 * JSON_OBJECT_SIZE(1))); +std::unique_ptr StopTransaction::createConf(){ + auto doc = makeJsonDoc(getMemoryTag(), 2 * JSON_OBJECT_SIZE(1)); JsonObject payload = doc->to(); JsonObject idTagInfo = payload.createNestedObject("idTagInfo"); diff --git a/src/MicroOcpp/Operations/StopTransaction.h b/src/MicroOcpp/Operations/StopTransaction.h index 9f617e9d..c573135c 100644 --- a/src/MicroOcpp/Operations/StopTransaction.h +++ b/src/MicroOcpp/Operations/StopTransaction.h @@ -6,9 +6,9 @@ #define MO_STOPTRANSACTION_H #include +#include #include #include -#include namespace MicroOcpp { @@ -21,20 +21,20 @@ class Transaction; namespace Ocpp16 { -class StopTransaction : public Operation { +class StopTransaction : public Operation, public MemoryManaged { private: Model& model; std::shared_ptr transaction; - std::vector> transactionData; + Vector> transactionData; public: StopTransaction(Model& model, std::shared_ptr transaction); - StopTransaction(Model& model, std::shared_ptr transaction, std::vector> transactionData); + StopTransaction(Model& model, std::shared_ptr transaction, Vector> transactionData); const char* getOperationType() override; - std::unique_ptr createReq() override; + std::unique_ptr createReq() override; void processConf(JsonObject payload) override; @@ -42,7 +42,7 @@ class StopTransaction : public Operation { void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; }; } //end namespace Ocpp16 diff --git a/src/MicroOcpp/Operations/TransactionEvent.cpp b/src/MicroOcpp/Operations/TransactionEvent.cpp index 92a7e686..a9e74a2f 100644 --- a/src/MicroOcpp/Operations/TransactionEvent.cpp +++ b/src/MicroOcpp/Operations/TransactionEvent.cpp @@ -11,11 +11,11 @@ #include #include -using MicroOcpp::Ocpp201::TransactionEvent; using namespace MicroOcpp::Ocpp201; +using MicroOcpp::JsonDoc; TransactionEvent::TransactionEvent(Model& model, std::shared_ptr txEvent) - : model(model), txEvent(txEvent) { + : MemoryManaged("v201.Operation.", "TransactionEvent"), model(model), txEvent(txEvent) { } @@ -23,13 +23,13 @@ const char* TransactionEvent::getOperationType() { return "TransactionEvent"; } -std::unique_ptr TransactionEvent::createReq() { - auto doc = std::unique_ptr(new DynamicJsonDocument( +std::unique_ptr TransactionEvent::createReq() { + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(12) + //total of 12 fields JSONDATE_LENGTH + 1 + //timestamp string JSON_OBJECT_SIZE(5) + //transactionInfo MO_TXID_LEN_MAX + 1 + //transactionId - MO_IDTOKEN_LEN_MAX + 1)); //idToken + MO_IDTOKEN_LEN_MAX + 1); //idToken //meterValue not supported JsonObject payload = doc->to(); @@ -277,7 +277,7 @@ void TransactionEvent::processReq(JsonObject payload) { */ } -std::unique_ptr TransactionEvent::createConf() { +std::unique_ptr TransactionEvent::createConf() { return createEmptyDocument(); } diff --git a/src/MicroOcpp/Operations/TransactionEvent.h b/src/MicroOcpp/Operations/TransactionEvent.h index dcedb63e..0df02ba0 100644 --- a/src/MicroOcpp/Operations/TransactionEvent.h +++ b/src/MicroOcpp/Operations/TransactionEvent.h @@ -19,7 +19,7 @@ namespace Ocpp201 { class TransactionEventData; -class TransactionEvent : public Operation { +class TransactionEvent : public Operation, public MemoryManaged { private: Model& model; std::shared_ptr txEvent; @@ -31,7 +31,7 @@ class TransactionEvent : public Operation { const char* getOperationType() override; - std::unique_ptr createReq() override; + std::unique_ptr createReq() override; void processConf(JsonObject payload) override; @@ -39,7 +39,7 @@ class TransactionEvent : public Operation { void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; }; } //end namespace Ocpp201 diff --git a/src/MicroOcpp/Operations/TriggerMessage.cpp b/src/MicroOcpp/Operations/TriggerMessage.cpp index 431f2a57..518353a0 100644 --- a/src/MicroOcpp/Operations/TriggerMessage.cpp +++ b/src/MicroOcpp/Operations/TriggerMessage.cpp @@ -12,8 +12,9 @@ #include using MicroOcpp::Ocpp16::TriggerMessage; +using MicroOcpp::JsonDoc; -TriggerMessage::TriggerMessage(Context& context) : context(context) { +TriggerMessage::TriggerMessage(Context& context) : MemoryManaged("v16.Operation.", "TriggerMessage"), context(context) { } @@ -80,8 +81,8 @@ void TriggerMessage::processReq(JsonObject payload) { } } -std::unique_ptr TriggerMessage::createConf(){ - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); +std::unique_ptr TriggerMessage::createConf(){ + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(1)); JsonObject payload = doc->to(); payload["status"] = statusMessage; return doc; diff --git a/src/MicroOcpp/Operations/TriggerMessage.h b/src/MicroOcpp/Operations/TriggerMessage.h index 4b8af068..7869e5a5 100644 --- a/src/MicroOcpp/Operations/TriggerMessage.h +++ b/src/MicroOcpp/Operations/TriggerMessage.h @@ -6,8 +6,7 @@ #define MO_TRIGGERMESSAGE_H #include - -#include +#include namespace MicroOcpp { @@ -15,7 +14,7 @@ class Context; namespace Ocpp16 { -class TriggerMessage : public Operation { +class TriggerMessage : public Operation, public MemoryManaged { private: Context& context; const char *statusMessage = nullptr; @@ -28,7 +27,7 @@ class TriggerMessage : public Operation { void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; const char *getErrorCode() override {return errorCode;} }; diff --git a/src/MicroOcpp/Operations/UnlockConnector.cpp b/src/MicroOcpp/Operations/UnlockConnector.cpp index 537ee3b4..87cc03f6 100644 --- a/src/MicroOcpp/Operations/UnlockConnector.cpp +++ b/src/MicroOcpp/Operations/UnlockConnector.cpp @@ -7,8 +7,9 @@ #include using MicroOcpp::Ocpp16::UnlockConnector; +using MicroOcpp::JsonDoc; -UnlockConnector::UnlockConnector(Model& model) : model(model) { +UnlockConnector::UnlockConnector(Model& model) : MemoryManaged("v16.Operation.", "UnlockConnector"), model(model) { } @@ -46,7 +47,7 @@ void UnlockConnector::processReq(JsonObject payload) { #endif //MO_ENABLE_CONNECTOR_LOCK } -std::unique_ptr UnlockConnector::createConf() { +std::unique_ptr UnlockConnector::createConf() { const char *status = "NotSupported"; @@ -72,7 +73,7 @@ std::unique_ptr UnlockConnector::createConf() { } #endif //MO_ENABLE_CONNECTOR_LOCK - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); + auto doc = makeJsonDoc(getMemoryTag(), JSON_OBJECT_SIZE(1)); JsonObject payload = doc->to(); payload["status"] = status; return doc; diff --git a/src/MicroOcpp/Operations/UnlockConnector.h b/src/MicroOcpp/Operations/UnlockConnector.h index bf49d195..44b41bb9 100644 --- a/src/MicroOcpp/Operations/UnlockConnector.h +++ b/src/MicroOcpp/Operations/UnlockConnector.h @@ -15,7 +15,7 @@ class Model; namespace Ocpp16 { -class UnlockConnector : public Operation { +class UnlockConnector : public Operation, public MemoryManaged { private: Model& model; @@ -33,7 +33,7 @@ class UnlockConnector : public Operation { void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; const char *getErrorCode() override {return errorCode;} }; diff --git a/src/MicroOcpp/Operations/UpdateFirmware.cpp b/src/MicroOcpp/Operations/UpdateFirmware.cpp index 52cb9683..d9be551f 100644 --- a/src/MicroOcpp/Operations/UpdateFirmware.cpp +++ b/src/MicroOcpp/Operations/UpdateFirmware.cpp @@ -8,8 +8,9 @@ #include using MicroOcpp::Ocpp16::UpdateFirmware; +using MicroOcpp::JsonDoc; -UpdateFirmware::UpdateFirmware(FirmwareService& fwService) : fwService(fwService) { +UpdateFirmware::UpdateFirmware(FirmwareService& fwService) : MemoryManaged("v16.Operation.", "UpdateFirmware"), fwService(fwService) { } @@ -45,6 +46,6 @@ void UpdateFirmware::processReq(JsonObject payload) { fwService.scheduleFirmwareUpdate(location, retrieveDate, (unsigned int) retries, (unsigned int) retryInterval); } -std::unique_ptr UpdateFirmware::createConf(){ +std::unique_ptr UpdateFirmware::createConf(){ return createEmptyDocument(); } diff --git a/src/MicroOcpp/Operations/UpdateFirmware.h b/src/MicroOcpp/Operations/UpdateFirmware.h index 0b4721f7..da962141 100644 --- a/src/MicroOcpp/Operations/UpdateFirmware.h +++ b/src/MicroOcpp/Operations/UpdateFirmware.h @@ -14,7 +14,7 @@ class FirmwareService; namespace Ocpp16 { -class UpdateFirmware : public Operation { +class UpdateFirmware : public Operation, public MemoryManaged { private: FirmwareService& fwService; @@ -26,7 +26,7 @@ class UpdateFirmware : public Operation { void processReq(JsonObject payload) override; - std::unique_ptr createConf() override; + std::unique_ptr createConf() override; const char *getErrorCode() override {return errorCode;} }; diff --git a/src/MicroOcpp_c.cpp b/src/MicroOcpp_c.cpp index 04aa5091..4c5b6317 100644 --- a/src/MicroOcpp_c.cpp +++ b/src/MicroOcpp_c.cpp @@ -6,6 +6,7 @@ #include "MicroOcpp.h" #include +#include #include #include @@ -363,7 +364,7 @@ void ocpp_set_console_out_c(void (*console_out)(const char *msg)) { void ocpp_authorize(const char *idTag, AuthorizeConfCallback onConfirmation, AuthorizeAbortCallback onAbort, AuthorizeTimeoutCallback onTimeout, AuthorizeErrorCallback onError, void *user_data) { - std::string idTag_capture = idTag; + auto idTag_capture = MicroOcpp::makeString("MicroOcpp_c.cpp", idTag); authorize(idTag, onConfirmation ? [onConfirmation, idTag_capture, user_data] (JsonObject payload) { diff --git a/tests/Api.cpp b/tests/Api.cpp index 2de67703..ab0888c2 100644 --- a/tests/Api.cpp +++ b/tests/Api.cpp @@ -10,7 +10,7 @@ #include #include #include -#include "./catch2/catch.hpp" +#include #include "./helpers/testHelper.h" #define BASE_TIME "2023-01-01T00:00:00.000Z" @@ -78,13 +78,13 @@ TEST_CASE( "C++ API test" ) { setOnSendConf("StatusNotification", [c = &checkpoints[ncheck++]] (JsonObject) {*c = true;}); sendRequest("DataTransfer", [c = &checkpoints[ncheck++]] () { *c = true; - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); + auto doc = MicroOcpp::makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(1)); doc->to(); return doc; }, [c = &checkpoints[ncheck++]] (JsonObject) {*c = true;}); setRequestHandler("DataTransfer", [c = &checkpoints[ncheck++]] (JsonObject) {*c = true;}, [c = &checkpoints[ncheck++]] () { *c = true; - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); + auto doc = MicroOcpp::makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(1)); doc->to(); return doc; }); @@ -145,13 +145,13 @@ TEST_CASE( "C++ API test" ) { REQUIRE(isOperative()); sendRequest("UnlockConnector", [] () { - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); + auto doc = MicroOcpp::makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(1)); (*doc)["connectorId"] = 1; return doc; }, [] (JsonObject) {}); sendRequest("Reset", [] () { - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); + auto doc = MicroOcpp::makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(1)); (*doc)["type"] = "Hard"; return doc; }, [] (JsonObject) {}); @@ -333,18 +333,18 @@ TEST_CASE( "C API test" ) { REQUIRE(ocpp_isOperative_m(2)); sendRequest("UnlockConnector", [] () { - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); + auto doc = MicroOcpp::makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(1)); (*doc)["connectorId"] = 1; return doc; }, [] (JsonObject) {}); sendRequest("UnlockConnector", [] () { - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); + auto doc = MicroOcpp::makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(1)); (*doc)["connectorId"] = 2; return doc; }, [] (JsonObject) {}); sendRequest("Reset", [] () { - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); + auto doc = MicroOcpp::makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(1)); (*doc)["type"] = "Hard"; return doc; }, [] (JsonObject) {}); diff --git a/tests/Certificates.cpp b/tests/Certificates.cpp index 9267705a..79d0b967 100644 --- a/tests/Certificates.cpp +++ b/tests/Certificates.cpp @@ -8,7 +8,7 @@ #include #include -#include "./catch2/catch.hpp" +#include #include "./helpers/testHelper.h" #include @@ -109,7 +109,7 @@ TEST_CASE( "M - Certificates" ) { auto ret1 = certs->installCertificate(InstallCertificateType_CSMSRootCertificate, root_cert); REQUIRE(ret1 == InstallCertificateStatus_Accepted); - std::vector chain; + auto chain = makeVector("UnitTests"); auto ret2 = certs->getCertificateIds({GetCertificateIdType_CSMSRootCertificate}, chain); REQUIRE(ret2 == GetInstalledCertificateStatus_Accepted); @@ -140,7 +140,7 @@ TEST_CASE( "M - Certificates" ) { auto ret1 = certs->installCertificate(InstallCertificateType_CSMSRootCertificate, root_cert); REQUIRE(ret1 == InstallCertificateStatus_Accepted); - std::vector chain; + auto chain = makeVector("UnitTests"); auto ret2 = certs->getCertificateIds({GetCertificateIdType_CSMSRootCertificate}, chain); REQUIRE(ret2 == GetInstalledCertificateStatus_Accepted); @@ -167,8 +167,8 @@ TEST_CASE( "M - Certificates" ) { "InstallCertificate", [] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument( - JSON_OBJECT_SIZE(2))); + auto doc = makeJsonDoc("UnitTests", + JSON_OBJECT_SIZE(2)); auto payload = doc->to(); payload["certificateType"] = "CSMSRootCertificate"; //of InstallCertificateTypeEnumType payload["certificate"] = root_cert; @@ -199,8 +199,8 @@ TEST_CASE( "M - Certificates" ) { "DeleteCertificate", [] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument( - JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(4))); + auto doc = makeJsonDoc("UnitTests", + JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(4)); auto payload = doc->to(); payload["certificateHashData"]["hashAlgorithm"] = root_cert_hash_algorithm; //of HashAlgorithmType payload["certificateHashData"]["issuerNameHash"] = root_cert_hash_issuer_name; @@ -227,8 +227,8 @@ TEST_CASE( "M - Certificates" ) { "GetInstalledCertificateIds", [] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument( - JSON_OBJECT_SIZE(1) + JSON_ARRAY_SIZE(1))); + auto doc = makeJsonDoc("UnitTests", + JSON_OBJECT_SIZE(1) + JSON_ARRAY_SIZE(1)); auto payload = doc->to(); payload["certificateType"][0] = "CSMSRootCertificate"; //of GetCertificateIdTypeEnumType return doc;}, diff --git a/tests/ChargePointError.cpp b/tests/ChargePointError.cpp index 3fe9a472..5f498de6 100644 --- a/tests/ChargePointError.cpp +++ b/tests/ChargePointError.cpp @@ -4,7 +4,7 @@ #include #include -#include "./catch2/catch.hpp" +#include #include "./helpers/testHelper.h" #include diff --git a/tests/ChargingSessions.cpp b/tests/ChargingSessions.cpp index 5c35362b..9401a4f1 100644 --- a/tests/ChargingSessions.cpp +++ b/tests/ChargingSessions.cpp @@ -13,7 +13,7 @@ #include #include #include -#include "./catch2/catch.hpp" +#include #include "./helpers/testHelper.h" #define BASE_TIME "2023-01-01T00:00:00.000Z" @@ -52,7 +52,7 @@ TEST_CASE( "Charging sessions" ) { SECTION("Check idle state"){ bool checkedBN = false; - checkMsg.registerOperation("BootNotification", [engine] () -> Operation* {return new Ocpp16::BootNotification(engine->getModel(), std::unique_ptr(new DynamicJsonDocument(0)));}); + checkMsg.registerOperation("BootNotification", [engine] () -> Operation* {return new Ocpp16::BootNotification(engine->getModel(), makeJsonDoc("UnitTests"));}); checkMsg.setOnRequest("BootNotification", [&checkedBN] (JsonObject request) { checkedBN = !strcmp(request["chargePointModel"] | "Invalid", "test-runner1234"); @@ -392,7 +392,7 @@ TEST_CASE( "Charging sessions" ) { [] (JsonObject payload) {}, //ignore req [&txId_generate] () { //create conf - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(2))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(2)); JsonObject payload = doc->to(); JsonObject idTagInfo = payload.createNestedObject("idTagInfo"); @@ -472,7 +472,7 @@ TEST_CASE( "Charging sessions" ) { [] (JsonObject payload) {}, //ignore req [&txId_generate] () { //create conf - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(2))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(2)); JsonObject payload = doc->to(); JsonObject idTagInfo = payload.createNestedObject("idTagInfo"); @@ -588,7 +588,7 @@ TEST_CASE( "Charging sessions" ) { }, [] () { //create conf - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(2))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(2)); JsonObject payload = doc->to(); JsonObject idTagInfo = payload.createNestedObject("idTagInfo"); @@ -634,7 +634,7 @@ TEST_CASE( "Charging sessions" ) { "ChangeAvailability", [] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(2))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(2)); auto payload = doc->to(); payload["connectorId"] = 1; payload["type"] = "Inoperative"; @@ -689,7 +689,7 @@ TEST_CASE( "Charging sessions" ) { new MicroOcpp::Ocpp16::CustomOperation("UnlockConnector", [] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(1)); auto payload = doc->to(); payload["connectorId"] = 1; return doc; @@ -716,7 +716,7 @@ TEST_CASE( "Charging sessions" ) { new MicroOcpp::Ocpp16::CustomOperation("UnlockConnector", [] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(1)); auto payload = doc->to(); payload["connectorId"] = 1; return doc; @@ -741,7 +741,7 @@ TEST_CASE( "Charging sessions" ) { new MicroOcpp::Ocpp16::CustomOperation("UnlockConnector", [] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(1)); auto payload = doc->to(); payload["connectorId"] = 1; return doc; @@ -833,7 +833,7 @@ TEST_CASE( "Charging sessions" ) { }, [&txId] () { //create conf - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(2))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(2)); JsonObject payload = doc->to(); JsonObject idTagInfo = payload.createNestedObject("idTagInfo"); @@ -962,7 +962,7 @@ TEST_CASE( "Charging sessions" ) { }, [&txId] () { //create conf - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(2))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(2)); JsonObject payload = doc->to(); JsonObject idTagInfo = payload.createNestedObject("idTagInfo"); @@ -1030,7 +1030,7 @@ TEST_CASE( "Charging sessions" ) { }, [&txId] () { //create conf - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(2))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(2)); JsonObject payload = doc->to(); JsonObject idTagInfo = payload.createNestedObject("idTagInfo"); diff --git a/tests/Configuration.cpp b/tests/Configuration.cpp index 57aa8107..91fa1e28 100644 --- a/tests/Configuration.cpp +++ b/tests/Configuration.cpp @@ -6,7 +6,7 @@ #include #include -#include "./catch2/catch.hpp" +#include #include "./helpers/testHelper.h" #include @@ -288,7 +288,7 @@ TEST_CASE( "Configuration" ) { "GetConfiguration", [] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(1)); doc->to(); return doc;}, [&checkProcessed] (JsonObject payload) { @@ -325,7 +325,7 @@ TEST_CASE( "Configuration" ) { "GetConfiguration", [] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1) + JSON_ARRAY_SIZE(2))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(1) + JSON_ARRAY_SIZE(2)); auto payload = doc->to(); auto key = payload.createNestedArray("key"); key.add(KNOWN_KEY); @@ -379,7 +379,7 @@ TEST_CASE( "Configuration" ) { "ChangeConfiguration", [] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(2))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(2)); auto payload = doc->to(); payload["key"] = KNOWN_KEY; payload["value"] = "1234"; @@ -401,7 +401,7 @@ TEST_CASE( "Configuration" ) { "ChangeConfiguration", [] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(2))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(2)); auto payload = doc->to(); payload["key"] = UNKOWN_KEY; payload["value"] = "no effect"; @@ -422,7 +422,7 @@ TEST_CASE( "Configuration" ) { "ChangeConfiguration", [] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(2))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(2)); auto payload = doc->to(); payload["key"] = KNOWN_KEY; payload["value"] = "not convertible to int"; @@ -449,7 +449,7 @@ TEST_CASE( "Configuration" ) { "ChangeConfiguration", [] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(2))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(2)); auto payload = doc->to(); payload["key"] = KNOWN_KEY; payload["value"] = "100234"; @@ -471,7 +471,7 @@ TEST_CASE( "Configuration" ) { "ChangeConfiguration", [] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(2))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(2)); auto payload = doc->to(); payload["key"] = KNOWN_KEY; payload["value"] = "4321"; diff --git a/tests/ConfigurationBehavior.cpp b/tests/ConfigurationBehavior.cpp index 1d345c3d..4b14f733 100644 --- a/tests/ConfigurationBehavior.cpp +++ b/tests/ConfigurationBehavior.cpp @@ -11,7 +11,7 @@ #include #include #include -#include "./catch2/catch.hpp" +#include #include "./helpers/testHelper.h" using namespace MicroOcpp; @@ -25,8 +25,8 @@ class CustomAuthorize : public Operation { void processReq(JsonObject payload) override { //ignore payload - result is determined at construction time } - std::unique_ptr createConf() override { - auto res = std::unique_ptr(new DynamicJsonDocument(2 * JSON_OBJECT_SIZE(1))); + std::unique_ptr createConf() override { + auto res = makeJsonDoc("UnitTests", 2 * JSON_OBJECT_SIZE(1)); auto payload = res->to(); payload["idTagInfo"]["status"] = status; return res; @@ -42,8 +42,8 @@ class CustomStartTransaction : public Operation { void processReq(JsonObject payload) override { //ignore payload - result is determined at construction time } - std::unique_ptr createConf() override { - auto res = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(1))); + std::unique_ptr createConf() override { + auto res = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(1)); auto payload = res->to(); payload["idTagInfo"]["status"] = status; payload["transactionId"] = 1000; diff --git a/tests/FirmwareManagement.cpp b/tests/FirmwareManagement.cpp index 20801dd8..5f11b8c4 100644 --- a/tests/FirmwareManagement.cpp +++ b/tests/FirmwareManagement.cpp @@ -4,7 +4,7 @@ #include #include -#include "./catch2/catch.hpp" +#include #include "./helpers/testHelper.h" #include @@ -71,7 +71,7 @@ TEST_CASE( "FirmwareManagement" ) { "UpdateFirmware", [] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(4))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(4)); auto payload = doc->to(); payload["location"] = FTP_URL; payload["retries"] = 1; @@ -125,7 +125,7 @@ TEST_CASE( "FirmwareManagement" ) { if (checkProcessed == 0) { if (checkProcessedOnDownloadStatus == 0) checkProcessedOnDownloadStatus = 1; return DownloadStatus::NotDownloaded; - } else if (checkProcessed >= 1) { + } else { if (checkProcessedOnDownloadStatus == 1) checkProcessedOnDownloadStatus = 2; return DownloadStatus::Downloaded; } @@ -135,7 +135,7 @@ TEST_CASE( "FirmwareManagement" ) { "UpdateFirmware", [] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(4))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(4)); auto payload = doc->to(); payload["location"] = FTP_URL; payload["retries"] = 1; @@ -192,7 +192,7 @@ TEST_CASE( "FirmwareManagement" ) { if (checkProcessed == 0) { if (checkProcessedOnInstallStatus == 0) checkProcessedOnInstallStatus = 1; return InstallationStatus::NotInstalled; - } else if (checkProcessed >= 1) { + } else { if (checkProcessedOnInstallStatus == 1) checkProcessedOnInstallStatus = 2; return InstallationStatus::Installed; } @@ -202,7 +202,7 @@ TEST_CASE( "FirmwareManagement" ) { "UpdateFirmware", [] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(4))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(4)); auto payload = doc->to(); payload["location"] = FTP_URL; payload["retries"] = 1; @@ -262,7 +262,7 @@ TEST_CASE( "FirmwareManagement" ) { if (checkProcessed == 0) { if (checkProcessedOnDownloadStatus == 0) checkProcessedOnDownloadStatus = 1; return DownloadStatus::NotDownloaded; - } else if (checkProcessed >= 1) { + } else { if (checkProcessedOnDownloadStatus == 1) checkProcessedOnDownloadStatus = 2; return DownloadStatus::Downloaded; } @@ -279,7 +279,7 @@ TEST_CASE( "FirmwareManagement" ) { if (checkProcessed <= 2) { if (checkProcessedOnInstallStatus == 0) checkProcessedOnInstallStatus = 1; return InstallationStatus::NotInstalled; - } else if (checkProcessed >= 3) { + } else { if (checkProcessedOnInstallStatus == 1) checkProcessedOnInstallStatus = 2; return InstallationStatus::Installed; } @@ -289,7 +289,7 @@ TEST_CASE( "FirmwareManagement" ) { "UpdateFirmware", [] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(4))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(4)); auto payload = doc->to(); payload["location"] = FTP_URL; payload["retries"] = 1; @@ -357,7 +357,7 @@ TEST_CASE( "FirmwareManagement" ) { } else if (checkProcessed == 2) { if (checkProcessedOnDownloadStatus == 2) checkProcessedOnDownloadStatus = 3; return DownloadStatus::NotDownloaded; - } else if (checkProcessed >= 3) { + } else { if (checkProcessedOnDownloadStatus == 3) checkProcessedOnDownloadStatus = 4; return DownloadStatus::DownloadFailed; } @@ -373,7 +373,7 @@ TEST_CASE( "FirmwareManagement" ) { "UpdateFirmware", [] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(4))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(4)); auto payload = doc->to(); payload["location"] = FTP_URL; payload["retries"] = 2; @@ -442,7 +442,7 @@ TEST_CASE( "FirmwareManagement" ) { } else if (checkProcessed == 2) { if (checkProcessedOnInstallStatus == 2) checkProcessedOnInstallStatus = 3; return InstallationStatus::NotInstalled; - } else if (checkProcessed >= 3) { + } else { if (checkProcessedOnInstallStatus == 3) checkProcessedOnInstallStatus = 4; return InstallationStatus::InstallationFailed; } @@ -452,7 +452,7 @@ TEST_CASE( "FirmwareManagement" ) { "UpdateFirmware", [] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(4))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(4)); auto payload = doc->to(); payload["location"] = FTP_URL; payload["retries"] = 2; @@ -514,7 +514,7 @@ TEST_CASE( "FirmwareManagement" ) { if (checkProcessed == 0) { if (checkProcessedOnDownloadStatus == 0) checkProcessedOnDownloadStatus = 1; return DownloadStatus::NotDownloaded; - } else if (checkProcessed >= 1) { + } else { if (checkProcessedOnDownloadStatus == 1) checkProcessedOnDownloadStatus = 2; return DownloadStatus::Downloaded; } @@ -531,7 +531,7 @@ TEST_CASE( "FirmwareManagement" ) { if (checkProcessed <= 2) { if (checkProcessedOnInstallStatus == 0) checkProcessedOnInstallStatus = 1; return InstallationStatus::NotInstalled; - } else if (checkProcessed >= 3) { + } else { if (checkProcessedOnInstallStatus == 1) checkProcessedOnInstallStatus = 2; return InstallationStatus::Installed; } @@ -541,7 +541,7 @@ TEST_CASE( "FirmwareManagement" ) { "UpdateFirmware", [] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(4))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(4)); auto payload = doc->to(); payload["location"] = FTP_URL; payload["retries"] = 1; diff --git a/tests/LocalAuthList.cpp b/tests/LocalAuthList.cpp index 866567e3..86ac08a6 100644 --- a/tests/LocalAuthList.cpp +++ b/tests/LocalAuthList.cpp @@ -8,7 +8,7 @@ #include #include -#include "./catch2/catch.hpp" +#include #include "./helpers/testHelper.h" #include @@ -409,7 +409,7 @@ TEST_CASE( "LocalAuth" ) { [] (JsonObject) {}, //ignore req [] () { //create conf - auto doc = std::unique_ptr(new DynamicJsonDocument(2 * JSON_OBJECT_SIZE(1))); + auto doc = makeJsonDoc("UnitTests", 2 * JSON_OBJECT_SIZE(1)); auto payload = doc->to(); payload["idTagInfo"]["status"] = "Blocked"; return doc; @@ -454,7 +454,7 @@ TEST_CASE( "LocalAuth" ) { }, [] () { //create conf - auto doc = std::unique_ptr(new DynamicJsonDocument(2 * JSON_OBJECT_SIZE(1))); + auto doc = makeJsonDoc("UnitTests", 2 * JSON_OBJECT_SIZE(1)); auto payload = doc->to(); payload["idTagInfo"]["status"] = "Blocked"; return doc; @@ -469,8 +469,8 @@ TEST_CASE( "LocalAuth" ) { }, [] () { //create conf - auto doc = std::unique_ptr(new DynamicJsonDocument( - JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(1))); + auto doc = makeJsonDoc("UnitTests", + JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(1)); auto payload = doc->to(); payload["idTagInfo"]["status"] = "Blocked"; payload["transactionId"] = 1000; @@ -642,7 +642,7 @@ TEST_CASE( "LocalAuth" ) { int listVersion = 42; size_t listSize = 2; - std::string populatedEntryIdTag; //local auth list entry to be fully populated + auto populatedEntryIdTag = makeString("UnitTests"); //local auth list entry to be fully populated //Full update - happy path bool checkAccepted = false; @@ -650,8 +650,8 @@ TEST_CASE( "LocalAuth" ) { new Ocpp16::CustomOperation("SendLocalList", [&listVersion, &listSize, &populatedEntryIdTag] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument( - 4096)); + auto doc = makeJsonDoc("UnitTests", + 4096); auto payload = doc->to(); payload["listVersion"] = listVersion; generateAuthList(payload["localAuthorizationList"].to(), listSize, false); @@ -693,8 +693,8 @@ TEST_CASE( "LocalAuth" ) { new Ocpp16::CustomOperation("SendLocalList", [&listVersion, &listSize] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument( - 1024)); + auto doc = makeJsonDoc("UnitTests", + 1024); auto payload = doc->to(); payload["listVersion"] = listVersion; generateAuthList(payload["localAuthorizationList"].to(), listSize, false); @@ -719,8 +719,8 @@ TEST_CASE( "LocalAuth" ) { new Ocpp16::CustomOperation("SendLocalList", [&listVersion, &listSizeInvalid] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument( - 1024)); + auto doc = makeJsonDoc("UnitTests", + 1024); auto payload = doc->to(); payload["listVersion"] = listVersion; generateAuthList(payload["localAuthorizationList"].to(), listSizeInvalid, false); @@ -746,8 +746,8 @@ TEST_CASE( "LocalAuth" ) { new Ocpp16::CustomOperation("SendLocalList", [&listVersion, &listSize] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument( - 4096)); + auto doc = makeJsonDoc("UnitTests", + 4096); auto payload = doc->to(); payload["listVersion"] = listVersion; generateAuthList(payload["localAuthorizationList"].to(), listSize, false); @@ -772,8 +772,8 @@ TEST_CASE( "LocalAuth" ) { new Ocpp16::CustomOperation("SendLocalList", [&listVersion, &listSize] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument( - 4096)); + auto doc = makeJsonDoc("UnitTests", + 4096); auto payload = doc->to(); payload["listVersion"] = listVersion; generateAuthList(payload["localAuthorizationList"].to(), listSize, false); @@ -799,8 +799,8 @@ TEST_CASE( "LocalAuth" ) { new Ocpp16::CustomOperation("SendLocalList", [&listVersionInvalid, &listSizeInvalid] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument( - 4096)); + auto doc = makeJsonDoc("UnitTests", + 4096); auto payload = doc->to(); payload["listVersion"] = listVersionInvalid; generateAuthList(payload["localAuthorizationList"].to(), listSizeInvalid, false); @@ -835,8 +835,8 @@ TEST_CASE( "LocalAuth" ) { new Ocpp16::CustomOperation("SendLocalList", [&i] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument( - 1024)); + auto doc = makeJsonDoc("UnitTests", + 1024); auto payload = doc->to(); payload["listVersion"] = (int) i; @@ -873,8 +873,8 @@ TEST_CASE( "LocalAuth" ) { new Ocpp16::CustomOperation("SendLocalList", [&listVersionInvalid] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument( - 1024)); + auto doc = makeJsonDoc("UnitTests", + 1024); auto payload = doc->to(); payload["listVersion"] = listVersionInvalid; diff --git a/tests/Metering.cpp b/tests/Metering.cpp index 3a542d5c..144d4a37 100644 --- a/tests/Metering.cpp +++ b/tests/Metering.cpp @@ -7,7 +7,7 @@ #include #include #include -#include "./catch2/catch.hpp" +#include #include "./helpers/testHelper.h" #define BASE_TIME "2023-01-01T00:00:00.000Z" @@ -49,7 +49,7 @@ TEST_CASE("Metering") { sendRequest("ChangeConfiguration", [] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(2))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(2)); auto payload = doc->to(); payload["key"] = "MeterValuesSampledData"; payload["value"] = "Energy.Active.Import.Register,INVALID,Voltage"; //invalid request @@ -69,7 +69,7 @@ TEST_CASE("Metering") { sendRequest("ChangeConfiguration", [] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(2))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(2)); auto payload = doc->to(); payload["key"] = "MeterValuesSampledData"; payload["value"] = "Voltage,Energy.Active.Import.Register"; //valid request diff --git a/tests/Reservation.cpp b/tests/Reservation.cpp index 1b36f077..b25db0e2 100644 --- a/tests/Reservation.cpp +++ b/tests/Reservation.cpp @@ -8,7 +8,7 @@ #include #include -#include "./catch2/catch.hpp" +#include #include "./helpers/testHelper.h" #include @@ -92,7 +92,7 @@ TEST_CASE( "Reservation" ) { "RemoteStartTransaction", [] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(1)); auto payload = doc->to(); payload["idTag"] = "wrong idTag"; return doc;}, @@ -115,7 +115,7 @@ TEST_CASE( "Reservation" ) { "RemoteStartTransaction", [idTag] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(1)); auto payload = doc->to(); payload["idTag"] = idTag; return doc;}, @@ -177,9 +177,9 @@ TEST_CASE( "Reservation" ) { [parentIdTag, &checkProcessed] () { //create conf checkProcessed = true; - auto doc = std::unique_ptr(new DynamicJsonDocument( + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(1) + //payload root - JSON_OBJECT_SIZE(3))); //idTagInfo + JSON_OBJECT_SIZE(3)); //idTagInfo auto payload = doc->to(); payload["idTagInfo"]["parentIdTag"] = parentIdTag; payload["idTagInfo"]["status"] = "Accepted"; @@ -319,9 +319,9 @@ TEST_CASE( "Reservation" ) { "ReserveNow", [reservationId, connectorId, expiryDate, idTag, parentIdTag] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument( + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(5) + - JSONDATE_LENGTH + 1)); + JSONDATE_LENGTH + 1); auto payload = doc->to(); payload["connectorId"] = connectorId; char expiryDate_cstr [JSONDATE_LENGTH + 1]; @@ -355,9 +355,9 @@ TEST_CASE( "Reservation" ) { "ReserveNow", [reservationId, connectorId, expiryDate, idTag, parentIdTag] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument( + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(5) + - JSONDATE_LENGTH + 1)); + JSONDATE_LENGTH + 1); auto payload = doc->to(); payload["connectorId"] = connectorId; char expiryDate_cstr [JSONDATE_LENGTH + 1]; @@ -390,9 +390,9 @@ TEST_CASE( "Reservation" ) { "ReserveNow", [reservationId, connectorId, expiryDate, idTag, parentIdTag] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument( + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(5) + - JSONDATE_LENGTH + 1)); + JSONDATE_LENGTH + 1); auto payload = doc->to(); payload["connectorId"] = connectorId; char expiryDate_cstr [JSONDATE_LENGTH + 1]; @@ -427,9 +427,9 @@ TEST_CASE( "Reservation" ) { "ReserveNow", [reservationId, connectorId, expiryDate, idTag, parentIdTag] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument( + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(5) + - JSONDATE_LENGTH + 1)); + JSONDATE_LENGTH + 1); auto payload = doc->to(); payload["connectorId"] = connectorId; char expiryDate_cstr [JSONDATE_LENGTH + 1]; @@ -473,7 +473,7 @@ TEST_CASE( "Reservation" ) { "CancelReservation", [reservationId, connectorId, expiryDate, idTag, parentIdTag] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(1)); auto payload = doc->to(); payload["reservationId"] = reservationId; return doc;}, @@ -494,7 +494,7 @@ TEST_CASE( "Reservation" ) { "CancelReservation", [reservationId, connectorId, expiryDate, idTag, parentIdTag] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(1)); auto payload = doc->to(); payload["reservationId"] = reservationId; return doc;}, diff --git a/tests/Reset.cpp b/tests/Reset.cpp index d1607eb8..8036393f 100644 --- a/tests/Reset.cpp +++ b/tests/Reset.cpp @@ -15,7 +15,7 @@ #include #include #include -#include "./catch2/catch.hpp" +#include #include "./helpers/testHelper.h" #define BASE_TIME "2023-01-01T00:00:00.000Z" @@ -94,7 +94,7 @@ TEST_CASE( "Reset" ) { "Reset", [] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(1)); auto payload = doc->to(); payload["type"] = "OnIdle"; return doc;}, @@ -193,7 +193,7 @@ TEST_CASE( "Reset" ) { "Reset", [] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(1)); auto payload = doc->to(); payload["type"] = "Immediate"; return doc;}, @@ -245,7 +245,7 @@ TEST_CASE( "Reset" ) { "Reset", [] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(1)); auto payload = doc->to(); payload["type"] = "Immediate"; return doc;}, @@ -277,7 +277,7 @@ TEST_CASE( "Reset" ) { "Reset", [] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(2))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(2)); auto payload = doc->to(); payload["type"] = "OnIdle"; payload["evseId"] = 1; diff --git a/tests/SmartCharging.cpp b/tests/SmartCharging.cpp index c92c5dcf..7cf53b32 100644 --- a/tests/SmartCharging.cpp +++ b/tests/SmartCharging.cpp @@ -10,7 +10,7 @@ #include #include #include -#include "./catch2/catch.hpp" +#include #include "./helpers/testHelper.h" #define BASE_TIME "2023-01-01T00:00:00.000Z" @@ -476,7 +476,7 @@ TEST_CASE( "SmartCharging" ) { "GetCompositeSchedule", [] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(3))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(3)); auto payload = doc->to(); payload["connectorId"] = 1; payload["duration"] = 86400; @@ -554,7 +554,7 @@ TEST_CASE( "SmartCharging" ) { //create req StaticJsonDocument<2048> raw; deserializeJson(raw, SCPROFILE_2_RELATIVE_TXDEF_24A); - auto doc = std::unique_ptr(new DynamicJsonDocument(2048)); + auto doc = makeJsonDoc("UnitTests", 2048); *doc = raw[3]; return doc;}, [&checkProcessed] (JsonObject response) { @@ -572,7 +572,7 @@ TEST_CASE( "SmartCharging" ) { //create req StaticJsonDocument<2048> raw; deserializeJson(raw, SCPROFILE_0_ALT_SAME_ID); - auto doc = std::unique_ptr(new DynamicJsonDocument(2048)); + auto doc = makeJsonDoc("UnitTests", 2048); *doc = raw[3]; (*doc)["connectorId"] = 2; return doc;}, @@ -591,7 +591,7 @@ TEST_CASE( "SmartCharging" ) { //create req StaticJsonDocument<2048> raw; deserializeJson(raw, SCPROFILE_1_ABSOLUTE_LIMIT_16A); - auto doc = std::unique_ptr(new DynamicJsonDocument(2048)); + auto doc = makeJsonDoc("UnitTests", 2048); *doc = raw[3]; return doc;}, [&checkProcessed] (JsonObject response) { @@ -614,7 +614,7 @@ TEST_CASE( "SmartCharging" ) { //create req StaticJsonDocument<2048> raw; deserializeJson(raw, SCPROFILE_1_ABSOLUTE_LIMIT_16A); - auto doc = std::unique_ptr(new DynamicJsonDocument(2048)); + auto doc = makeJsonDoc("UnitTests", 2048); *doc = raw[3]; return doc;}, [&checkProcessed] (JsonObject response) { @@ -636,7 +636,7 @@ TEST_CASE( "SmartCharging" ) { //create req StaticJsonDocument<2048> raw; deserializeJson(raw, SCPROFILE_5_VALID_UNTIL_2022_16A); - auto doc = std::unique_ptr(new DynamicJsonDocument(2048)); + auto doc = makeJsonDoc("UnitTests", 2048); *doc = raw[3]; return doc;}, [&checkProcessed] (JsonObject response) { @@ -660,7 +660,7 @@ TEST_CASE( "SmartCharging" ) { //create req StaticJsonDocument<2048> raw; deserializeJson(raw, SCPROFILE_2_RELATIVE_TXDEF_24A); - auto doc = std::unique_ptr(new DynamicJsonDocument(2048)); + auto doc = makeJsonDoc("UnitTests", 2048); *doc = raw[3]; (*doc)["csChargingProfiles"]["stackLevel"] = MO_ChargeProfileMaxStackLevel; return doc;}, @@ -679,7 +679,7 @@ TEST_CASE( "SmartCharging" ) { //create req StaticJsonDocument<2048> raw; deserializeJson(raw, SCPROFILE_2_RELATIVE_TXDEF_24A); - auto doc = std::unique_ptr(new DynamicJsonDocument(2048)); + auto doc = makeJsonDoc("UnitTests", 2048); *doc = raw[3]; (*doc)["csChargingProfiles"]["stackLevel"] = MO_ChargeProfileMaxStackLevel + 1; return doc;}, @@ -705,7 +705,7 @@ TEST_CASE( "SmartCharging" ) { //create req StaticJsonDocument<2048> raw; deserializeJson(raw, SCPROFILE_2_RELATIVE_TXDEF_24A); - auto doc = std::unique_ptr(new DynamicJsonDocument(2048)); + auto doc = makeJsonDoc("UnitTests", 2048); *doc = raw[3]; JsonArray chargingSchedulePeriod = (*doc)["csChargingProfiles"]["chargingSchedule"]["chargingSchedulePeriod"]; chargingSchedulePeriod.clear(); @@ -730,7 +730,7 @@ TEST_CASE( "SmartCharging" ) { //create req StaticJsonDocument<2048> raw; deserializeJson(raw, SCPROFILE_2_RELATIVE_TXDEF_24A); - auto doc = std::unique_ptr(new DynamicJsonDocument(2048)); + auto doc = makeJsonDoc("UnitTests", 2048); *doc = raw[3]; JsonArray chargingSchedulePeriod = (*doc)["csChargingProfiles"]["chargingSchedule"]["chargingSchedulePeriod"]; chargingSchedulePeriod.clear(); @@ -766,7 +766,7 @@ TEST_CASE( "SmartCharging" ) { //create req StaticJsonDocument<2048> raw; deserializeJson(raw, SCPROFILE_0); - auto doc = std::unique_ptr(new DynamicJsonDocument(2048)); + auto doc = makeJsonDoc("UnitTests", 2048); *doc = raw[3]; return doc;}, [&checkProcessed] (JsonObject response) { @@ -784,7 +784,7 @@ TEST_CASE( "SmartCharging" ) { //create req StaticJsonDocument<2048> raw; deserializeJson(raw, SCPROFILE_1_ABSOLUTE_LIMIT_16A); - auto doc = std::unique_ptr(new DynamicJsonDocument(2048)); + auto doc = makeJsonDoc("UnitTests", 2048); *doc = raw[3]; return doc;}, [&checkProcessed] (JsonObject response) { @@ -806,7 +806,7 @@ TEST_CASE( "SmartCharging" ) { //create req StaticJsonDocument<2048> raw; deserializeJson(raw, SCPROFILE_0); - auto doc = std::unique_ptr(new DynamicJsonDocument(2048)); + auto doc = makeJsonDoc("UnitTests", 2048); *doc = raw[3]; return doc;}, [&checkProcessed] (JsonObject response) { @@ -824,7 +824,7 @@ TEST_CASE( "SmartCharging" ) { //create req StaticJsonDocument<2048> raw; deserializeJson(raw, SCPROFILE_1_ABSOLUTE_LIMIT_16A); - auto doc = std::unique_ptr(new DynamicJsonDocument(2048)); + auto doc = makeJsonDoc("UnitTests", 2048); *doc = raw[3]; return doc;}, [&checkProcessed] (JsonObject response) { diff --git a/tests/TransactionSafety.cpp b/tests/TransactionSafety.cpp index 03eeb9f6..f3593e01 100644 --- a/tests/TransactionSafety.cpp +++ b/tests/TransactionSafety.cpp @@ -10,7 +10,7 @@ #include #include #include -#include "./catch2/catch.hpp" +#include #include "./helpers/testHelper.h" using namespace MicroOcpp; diff --git a/tests/Transactions.cpp b/tests/Transactions.cpp index e32994be..aa4a3be9 100644 --- a/tests/Transactions.cpp +++ b/tests/Transactions.cpp @@ -13,7 +13,7 @@ #include #include #include -#include "./catch2/catch.hpp" +#include #include "./helpers/testHelper.h" #define BASE_TIME "2023-01-01T00:00:00.000Z" @@ -42,7 +42,7 @@ TEST_CASE( "Transactions" ) { [] (JsonObject) {}, //ignore req [] () { //create conf - auto doc = std::unique_ptr(new DynamicJsonDocument(2 * JSON_OBJECT_SIZE(1))); + auto doc = makeJsonDoc("UnitTests", 2 * JSON_OBJECT_SIZE(1)); auto payload = doc->to(); payload["idTokenInfo"]["status"] = "Accepted"; return doc; diff --git a/tests/Variables.cpp b/tests/Variables.cpp index aed483b3..6813dd11 100644 --- a/tests/Variables.cpp +++ b/tests/Variables.cpp @@ -8,7 +8,7 @@ #include #include -#include "./catch2/catch.hpp" +#include #include "./helpers/testHelper.h" #include @@ -277,7 +277,7 @@ TEST_CASE( "Variable" ) { "GetVariables", [] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(1)); auto payload = doc->to(); return doc;}, [&checkProcessed] (JsonObject payload) { @@ -314,7 +314,7 @@ TEST_CASE( "Variable" ) { "GetVariable", [] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(1) + JSON_ARRAY_SIZE(2))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(1) + JSON_ARRAY_SIZE(2)); auto payload = doc->to(); auto key = payload.createNestedArray("key"); key.add(KNOWN_KEY); @@ -368,7 +368,7 @@ TEST_CASE( "Variable" ) { "ChangeVariable", [] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(2))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(2)); auto payload = doc->to(); payload["key"] = KNOWN_KEY; payload["value"] = "1234"; @@ -390,7 +390,7 @@ TEST_CASE( "Variable" ) { "ChangeVariable", [] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(2))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(2)); auto payload = doc->to(); payload["key"] = UNKOWN_KEY; payload["value"] = "no effect"; @@ -411,7 +411,7 @@ TEST_CASE( "Variable" ) { "ChangeVariable", [] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(2))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(2)); auto payload = doc->to(); payload["key"] = KNOWN_KEY; payload["value"] = "not convertible to int"; @@ -438,7 +438,7 @@ TEST_CASE( "Variable" ) { "ChangeVariable", [] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(2))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(2)); auto payload = doc->to(); payload["key"] = KNOWN_KEY; payload["value"] = "100234"; @@ -460,7 +460,7 @@ TEST_CASE( "Variable" ) { "ChangeVariable", [] () { //create req - auto doc = std::unique_ptr(new DynamicJsonDocument(JSON_OBJECT_SIZE(2))); + auto doc = makeJsonDoc("UnitTests", JSON_OBJECT_SIZE(2)); auto payload = doc->to(); payload["key"] = KNOWN_KEY; payload["value"] = "4321"; diff --git a/tests/helpers/testHelper.cpp b/tests/helpers/testHelper.cpp index fc56e20b..ffc6fac5 100644 --- a/tests/helpers/testHelper.cpp +++ b/tests/helpers/testHelper.cpp @@ -2,7 +2,11 @@ // Copyright Matthias Akstaller 2019 - 2024 // MIT License +#include +#include + #include +#include using namespace MicroOcpp; @@ -17,3 +21,15 @@ void loop() { mocpp_loop(); } } + +class TestRunListener : public Catch::TestEventListenerBase { +public: + using Catch::TestEventListenerBase::TestEventListenerBase; + + void testRunEnded( Catch::TestRunStats const& testRunStats ) override { + MO_MEM_PRINT_STATS(); + MO_MEM_DEINIT(); + } +}; + +CATCH_REGISTER_LISTENER(TestRunListener) diff --git a/tests/ocppEngineLifecycle.cpp b/tests/ocppEngineLifecycle.cpp index a6a84818..b3de2a18 100644 --- a/tests/ocppEngineLifecycle.cpp +++ b/tests/ocppEngineLifecycle.cpp @@ -4,7 +4,7 @@ #include #include -#include "./catch2/catch.hpp" +#include #include "./helpers/testHelper.h" TEST_CASE( "Context lifecycle" ) {