diff --git a/CMakeLists.txt b/CMakeLists.txt index a05245f..afd3d39 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,6 +35,7 @@ add_compile_definitions( MO_FILENAME_PREFIX="./mo_store/" MO_ENABLE_V201=1 MO_ENABLE_MBEDTLS=1 + MO_ENABLE_TIMESTAMP_MILLISECONDS=1 ) add_executable(mo_simulator ${MO_SIM_SRC} ${MO_SIM_MG_SRC}) diff --git a/lib/MicroOcpp b/lib/MicroOcpp index e879c0e..4ea7db2 160000 --- a/lib/MicroOcpp +++ b/lib/MicroOcpp @@ -1 +1 @@ -Subproject commit e879c0e6988d7946959ce8cf18e05c4b623d21ba +Subproject commit 4ea7db2daeefb94bef42d4fa2d4ae4db9fab5646 diff --git a/lib/MicroOcppMongoose b/lib/MicroOcppMongoose index 95f4748..dbd8786 160000 --- a/lib/MicroOcppMongoose +++ b/lib/MicroOcppMongoose @@ -1 +1 @@ -Subproject commit 95f4748f0863ab276f2b5481d29a3281a38a0a36 +Subproject commit dbd878688534086e74810d9aafa37886b84c3c06 diff --git a/src/evse.cpp b/src/evse.cpp index ff85000..b8b7d4a 100644 --- a/src/evse.cpp +++ b/src/evse.cpp @@ -19,14 +19,6 @@ Evse::Evse(unsigned int connectorId) : connectorId{connectorId} { } -MicroOcpp::Connector *getConnector(unsigned int connectorId) { - if (!getOcppContext()) { - MO_DBG_ERR("unitialized"); - return nullptr; - } - return getOcppContext()->getModel().getConnector(connectorId); -} - void Evse::setup() { #if MO_ENABLE_V201 @@ -43,12 +35,6 @@ void Evse::setup() { } #endif - auto connector = getConnector(connectorId); - if (!connector) { - MO_DBG_ERR("invalid state"); - return; - } - char key [30] = {'\0'}; snprintf(key, 30, "evPlugged_cId_%u", connectorId); @@ -134,12 +120,11 @@ void Evse::setup() { } void Evse::loop() { - if (auto connector = getConnector(connectorId)) { - auto curStatus = connector->getStatus(); - if (status.compare(MicroOcpp::cstrFromOcppEveState(curStatus))) { - status = MicroOcpp::cstrFromOcppEveState(curStatus); - } + auto curStatus = getChargePointStatus(connectorId); + + if (status.compare(MicroOcpp::cstrFromOcppEveState(curStatus))) { + status = MicroOcpp::cstrFromOcppEveState(curStatus); } bool simulate_isCharging = ocppPermitsCharge(connectorId) && trackEvPluggedBool->getBool() && trackEvsePluggedBool->getBool() && trackEvReadyBool->getBool() && trackEvseReadyBool->getBool(); @@ -167,21 +152,16 @@ void Evse::presentNfcTag(const char *uid_cstr) { return; } std::string uid = uid_cstr; - auto connector = getConnector(connectorId); - if (!connector) { - MO_DBG_ERR("invalid state"); - return; - } #if MO_ENABLE_V201 if (auto context = getOcppContext()) { if (context->getVersion().major == 2) { if (auto txService = context->getModel().getTransactionService()) { if (auto evse = txService->getEvse(connectorId)) { - if (evse->getTransaction() && evse->getTransaction()->isAuthorized) { - evse->endAuthorization(uid_cstr); + if (evse->getTransaction() && evse->getTransaction()->isAuthorizationActive) { + evse->endAuthorization(MicroOcpp::IdToken(uid_cstr, MicroOcpp::IdToken::Type::KeyCode)); } else { - evse->beginAuthorization(uid_cstr); + evse->beginAuthorization(MicroOcpp::IdToken(uid_cstr, MicroOcpp::IdToken::Type::KeyCode)); } return; } @@ -190,14 +170,14 @@ void Evse::presentNfcTag(const char *uid_cstr) { } #endif - if (connector->getTransaction() && connector->getTransaction()->isActive()) { - if (!uid.compare(connector->getTransaction()->getIdTag())) { - connector->endTransaction(uid.c_str()); + if (isTransactionActive(connectorId)) { + if (!uid.compare(getTransactionIdTag(connectorId))) { + endTransaction(uid.c_str(), "Local", connectorId); } else { MO_DBG_INFO("RFID card denied"); } } else { - connector->beginTransaction(uid.c_str()); + beginTransaction(uid.c_str(), connectorId); } } @@ -246,30 +226,15 @@ bool Evse::getEvseReady() { } const char *Evse::getSessionIdTag() { - auto connector = getConnector(connectorId); - if (!connector) { - MO_DBG_ERR("invalid state"); - return nullptr; - } - return connector->getTransaction() ? connector->getTransaction()->getIdTag() : nullptr; + return getTransactionIdTag(connectorId) ? getTransactionIdTag(connectorId) : ""; } int Evse::getTransactionId() { - auto connector = getConnector(connectorId); - if (!connector) { - MO_DBG_ERR("invalid state"); - return -1; - } - return connector->getTransaction() ? connector->getTransaction()->getTransactionId() : -1; + return getTransaction(connectorId) ? getTransaction(connectorId)->getTransactionId() : -1; } bool Evse::chargingPermitted() { - auto connector = getConnector(connectorId); - if (!connector) { - MO_DBG_ERR("invalid state"); - return false; - } - return connector->ocppPermitsCharge(); + return ocppPermitsCharge(connectorId); } int Evse::getPower() { diff --git a/src/main.cpp b/src/main.cpp index 8d8ee8d..ac7d6b4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,11 +3,17 @@ // GPL-3.0 License #include +#include + +#include #include +#include #include "evse.h" #include "api.h" +#include + #if MO_NUMCONNECTORS == 3 std::array connectors {{1,2}}; #else @@ -15,6 +21,10 @@ std::array connectors {{1}}; #endif bool g_isOcpp201 = false; +bool g_runSimulator = true; + +bool g_isUpAndRunning = false; //if the initial BootNotification and StatusNotifications got through + 1s delay +unsigned int g_bootNotificationTime = 0; #define MO_NETLIB_MONGOOSE 1 #define MO_NETLIB_WASM 2 @@ -42,6 +52,31 @@ MicroOcpp::Connection *conn = nullptr; #error Please ensure that build flag MO_NETLIB is set as MO_NETLIB_MONGOOSE or MO_NETLIB_WASM #endif +#if MBEDTLS_PLATFORM_MEMORY //configure MbedTLS with allocation hook functions + +void *mo_mem_mbedtls_calloc( size_t n, size_t count ) { + size_t size = n * count; + auto ptr = MO_MALLOC("MbedTLS", size); + if (ptr) { + memset(ptr, 0, size); + } + return ptr; +} +void mo_mem_mbedtls_free( void *ptr ) { + MO_FREE(ptr); +} + +#endif //MBEDTLS_PLATFORM_MEMORY + +void mo_sim_sig_handler(int s){ + + if (!g_runSimulator) { //already tried to shut down, now force stop + exit(EXIT_FAILURE); + } + + g_runSimulator = false; //shut down simulator gracefully +} + /* * Setup MicroOcpp and API */ @@ -94,6 +129,17 @@ void app_loop() { #if MO_NETLIB == MO_NETLIB_MONGOOSE int main() { + +#if MBEDTLS_PLATFORM_MEMORY + mbedtls_platform_set_calloc_free(mo_mem_mbedtls_calloc, mo_mem_mbedtls_free); +#endif //MBEDTLS_PLATFORM_MEMORY + + struct sigaction sigIntHandler; + sigIntHandler.sa_handler = mo_sim_sig_handler; + sigemptyset(&sigIntHandler.sa_mask); + sigIntHandler.sa_flags = 0; + sigaction(SIGINT, &sigIntHandler, NULL); + mg_log_set(MG_LL_INFO); mg_mgr_init(&mgr); @@ -117,11 +163,32 @@ int main() { server_initialize(osock); app_setup(*osock, filesystem); - for (;;) { // Block forever + setOnResetExecute([] (bool isHard) { + g_runSimulator = false; + }); + + while (g_runSimulator) { //Run Simulator until OCPP Reset is executed or user presses Ctrl+C mg_mgr_poll(&mgr, 100); app_loop(); + + if (!g_bootNotificationTime && getOcppContext()->getModel().getClock().now() >= MicroOcpp::MIN_TIME) { + //time has been set, BootNotification succeeded + g_bootNotificationTime = mocpp_tick_ms(); + } + + if (!g_isUpAndRunning && g_bootNotificationTime && mocpp_tick_ms() - g_bootNotificationTime >= 1000) { + printf("[Sim] Resetting maximum heap usage after boot success\n"); + g_isUpAndRunning = true; + MO_MEM_RESET(); + } } + printf("[Sim] Shutting down Simulator\n"); + + MO_MEM_PRINT_STATS(); + + mocpp_deinitialize(); + delete osock; mg_mgr_free(&mgr); return 0;