From 20996481953628f87a37c28bc5ff9034de604a84 Mon Sep 17 00:00:00 2001 From: c-jimenez <18682655+c-jimenez@users.noreply.github.com> Date: Sat, 11 Nov 2023 10:52:09 +0100 Subject: [PATCH] [examples] Fix segfault on disconnect in central system examples --- .../DefaultCentralSystemEventsHandler.cpp | 38 ++++++++++++++++--- .../DefaultCentralSystemEventsHandler.h | 34 +++++++++++++---- examples/iso15118_centralsystem/main.cpp | 10 ++--- examples/quick_start_centralsystem/main.cpp | 3 +- 4 files changed, 65 insertions(+), 20 deletions(-) diff --git a/examples/common/DefaultCentralSystemEventsHandler.cpp b/examples/common/DefaultCentralSystemEventsHandler.cpp index 4b5d2210..ef2bd71e 100644 --- a/examples/common/DefaultCentralSystemEventsHandler.cpp +++ b/examples/common/DefaultCentralSystemEventsHandler.cpp @@ -45,7 +45,8 @@ using namespace ocpp::x509; DefaultCentralSystemEventsHandler::DefaultCentralSystemEventsHandler(std::filesystem::path iso_v2g_root_ca, std::filesystem::path iso_mo_root_ca, bool set_pending_status) - : m_iso_v2g_root_ca(iso_v2g_root_ca), + : m_chargepoints_mutex(), + m_iso_v2g_root_ca(iso_v2g_root_ca), m_iso_mo_root_ca(iso_mo_root_ca), m_set_pending_status(set_pending_status), m_chargepoints(), @@ -83,6 +84,9 @@ bool DefaultCentralSystemEventsHandler::checkCredentials(const std::string& char void DefaultCentralSystemEventsHandler::chargePointConnected(std::shared_ptr chargepoint) { cout << "Charge point [" << chargepoint->identifier() << "] connected" << endl; + + std::lock_guard lock(m_chargepoints_mutex); + auto iter_chargepoint = m_chargepoints.find(chargepoint->identifier()); if (iter_chargepoint == m_chargepoints.end()) { @@ -103,6 +107,8 @@ void DefaultCentralSystemEventsHandler::removeChargePoint(const std::string& ide [this, identifier = identifier] { std::this_thread::sleep_for(std::chrono::milliseconds(50)); + + std::lock_guard lock(m_chargepoints_mutex); m_chargepoints.erase(identifier); m_pending_chargepoints.erase(identifier); m_accepted_chargepoints.erase(identifier); @@ -110,6 +116,29 @@ void DefaultCentralSystemEventsHandler::removeChargePoint(const std::string& ide t.detach(); } +/** @brief Indicate if a charge point must be accepted */ +bool DefaultCentralSystemEventsHandler::isAcceptedChargePoint(const std::string& identifier) +{ + std::lock_guard lock(m_chargepoints_mutex); + return (m_accepted_chargepoints.find(identifier) != m_accepted_chargepoints.end()); +} + +/** @brief Add a charge point to the pending list */ +void DefaultCentralSystemEventsHandler::addPendingChargePoint( + std::shared_ptr chargepoint) +{ + std::lock_guard lock(m_chargepoints_mutex); + m_pending_chargepoints[chargepoint->identifier()] = chargepoint; +} + +/** @brief Add a charge point to the accepted list */ +void DefaultCentralSystemEventsHandler::addAcceptedChargePoint( + std::shared_ptr chargepoint) +{ + std::lock_guard lock(m_chargepoints_mutex); + m_accepted_chargepoints[chargepoint->identifier()] = chargepoint; +} + /** @brief Constructor */ DefaultCentralSystemEventsHandler::ChargePointRequestHandler::ChargePointRequestHandler( DefaultCentralSystemEventsHandler& event_handler, std::shared_ptr& chargepoint) @@ -170,12 +199,9 @@ ocpp::types::RegistrationStatus DefaultCentralSystemEventsHandler::ChargePointRe ocpp::types::RegistrationStatus ret = RegistrationStatus::Accepted; if (m_event_handler.setPendingEnabled()) { - auto accepted_chargepoint = m_event_handler.acceptedChargePoints(); - auto iter_accepted = accepted_chargepoint.find(m_chargepoint->identifier()); - if (iter_accepted == accepted_chargepoint.end()) + if (!m_event_handler.isAcceptedChargePoint(m_chargepoint->identifier())) { - m_event_handler.pendingChargePoints()[m_chargepoint->identifier()] = m_chargepoint; - + m_event_handler.addPendingChargePoint(m_chargepoint); ret = RegistrationStatus::Pending; } } diff --git a/examples/common/DefaultCentralSystemEventsHandler.h b/examples/common/DefaultCentralSystemEventsHandler.h index 7e86c02b..e0eccea7 100644 --- a/examples/common/DefaultCentralSystemEventsHandler.h +++ b/examples/common/DefaultCentralSystemEventsHandler.h @@ -30,6 +30,7 @@ SOFTWARE. #include #include +#include /** @brief Default central system event handlers implementation for the examples */ class DefaultCentralSystemEventsHandler : public ocpp::centralsystem::ICentralSystemEventsHandler @@ -237,19 +238,25 @@ class DefaultCentralSystemEventsHandler : public ocpp::centralsystem::ICentralSy std::string m_generated_certificate; }; - /** @brief Get the list of the connected charge points */ - std::map>& chargePoints() { return m_chargepoints; } + /** @brief Get the number connected charge points */ + size_t chargePointsCount() + { + std::lock_guard lock(m_chargepoints_mutex); + return m_chargepoints.size(); + } - /** @brief Get the list of the pending charge points */ - std::map>& pendingChargePoints() + /** @brief Get the list of the connected charge points */ + std::map> chargePoints() { - return m_pending_chargepoints; + std::lock_guard lock(m_chargepoints_mutex); + return m_chargepoints; } - /** @brief Get the list of the accepted charge points */ - std::map>& acceptedChargePoints() + /** @brief Get the list of the pending charge points */ + std::map> pendingChargePoints() { - return m_accepted_chargepoints; + std::lock_guard lock(m_chargepoints_mutex); + return m_pending_chargepoints; } /** @brief Path to the V2G root CA */ @@ -263,7 +270,18 @@ class DefaultCentralSystemEventsHandler : public ocpp::centralsystem::ICentralSy /** @brief Remove a charge point from the connected charge points */ void removeChargePoint(const std::string& identifier); + /** @brief Indicate if a charge point must be accepted */ + bool isAcceptedChargePoint(const std::string& identifier); + + /** @brief Add a charge point to the pending list */ + void addPendingChargePoint(std::shared_ptr chargepoint); + + /** @brief Add a charge point to the accepted list */ + void addAcceptedChargePoint(std::shared_ptr chargepoint); + protected: + /** @brief Mutex for charge point list */ + std::mutex m_chargepoints_mutex; /** @brief Path to the V2G root CA */ std::filesystem::path m_iso_v2g_root_ca; /** @brief Path to the MO root CA */ diff --git a/examples/iso15118_centralsystem/main.cpp b/examples/iso15118_centralsystem/main.cpp index c0ea294e..e22761e1 100644 --- a/examples/iso15118_centralsystem/main.cpp +++ b/examples/iso15118_centralsystem/main.cpp @@ -148,11 +148,11 @@ int main(int argc, char* argv[]) while (true) { // For each pending charge point - for (auto& iter_chargepoint : event_handler.pendingChargePoints()) + auto pending_chargepoints = event_handler.pendingChargePoints(); + for (auto& iter_chargepoint : pending_chargepoints) { - auto chargepoint = iter_chargepoint.second; - auto iter_accepted = event_handler.acceptedChargePoints().find(chargepoint->identifier()); - if (iter_accepted == event_handler.acceptedChargePoints().end()) + auto chargepoint = iter_chargepoint.second; + if (!event_handler.isAcceptedChargePoint(chargepoint->identifier())) { std::cout << "---------------------------------------------" << std::endl; std::cout << "Pending Charge point : " << chargepoint->identifier() << std::endl; @@ -239,7 +239,7 @@ int main(int argc, char* argv[]) } // Accept charge point - event_handler.acceptedChargePoints()[chargepoint->identifier()] = chargepoint; + event_handler.addAcceptedChargePoint(chargepoint); // Trigger a boot notification to force it to update its registration status chargepoint->triggerMessage(MessageTrigger::BootNotification, Optional()); diff --git a/examples/quick_start_centralsystem/main.cpp b/examples/quick_start_centralsystem/main.cpp index b1cdcbb0..1ffd1525 100644 --- a/examples/quick_start_centralsystem/main.cpp +++ b/examples/quick_start_centralsystem/main.cpp @@ -118,7 +118,8 @@ int main(int argc, char* argv[]) std::this_thread::sleep_for(std::chrono::seconds(1)); // For each connected charge point - for (auto& iter_chargepoint : event_handler.chargePoints()) + auto connected_chargepoints = event_handler.chargePoints(); + for (auto& iter_chargepoint : connected_chargepoints) { { auto chargepoint = iter_chargepoint.second->proxy();