From 66410732321d5cbe50f7b95848d970ccaa9d573e Mon Sep 17 00:00:00 2001 From: Marc Emmers Date: Tue, 29 Aug 2023 15:28:28 +0200 Subject: [PATCH] Move function to appropriate location and use the request directly without the call wrapper Signed-off-by: Marc Emmers --- include/ocpp/v201/charge_point.hpp | 7 ++- lib/ocpp/v201/charge_point.cpp | 80 ++++++++++++++++++++++++++---- 2 files changed, 75 insertions(+), 12 deletions(-) diff --git a/include/ocpp/v201/charge_point.hpp b/include/ocpp/v201/charge_point.hpp index dd24310993..dd548eee20 100644 --- a/include/ocpp/v201/charge_point.hpp +++ b/include/ocpp/v201/charge_point.hpp @@ -155,6 +155,12 @@ class ChargePoint : ocpp::ChargingStationBase { void handle_variable_changed(const SetVariableData& set_variable_data); bool validate_set_variable(const SetVariableData& set_variable_data); + ///\brief Apply a local list request to the database if allowed + /// + ///\param request The local list request to apply + ///\retval Accepted if applied, otherwise will return either Failed or VersionMismatch + SendLocalListStatusEnum apply_local_authorization_list(const SendLocalListRequest& request); + /// /// \brief Get evseid for the given transaction id. /// \param transaction_id The transactionid @@ -242,7 +248,6 @@ class ChargePoint : ocpp::ChargingStationBase { void handle_clear_cache_req(Call call); // Functional Block D: Local authorization list management - SendLocalListStatusEnum apply_local_authorization_list(const Call& call); void handle_send_local_authorization_list_req(Call call); void handle_get_local_authorization_list_version_req(Call call); diff --git a/lib/ocpp/v201/charge_point.cpp b/lib/ocpp/v201/charge_point.cpp index 9859e04c1f..3718bc4e3f 100644 --- a/lib/ocpp/v201/charge_point.cpp +++ b/lib/ocpp/v201/charge_point.cpp @@ -760,6 +760,64 @@ bool ChargePoint::validate_set_variable(const SetVariableData& set_variable_data // TODO(piet): other special validating of variables requested to change can be added here... } +SendLocalListStatusEnum ChargePoint::apply_local_authorization_list(const SendLocalListRequest& request) { + auto status = SendLocalListStatusEnum::Failed; + + auto has_duplicate_in_list = [](const std::vector& list) { + for (auto it1 = list.begin(); it1 != list.end(); ++it1) { + for (auto it2 = it1 + 1; it2 != list.end(); ++it2) { + if (it1->idToken.idToken == it2->idToken.idToken and it1->idToken.type == it2->idToken.type) { + return true; + } + } + } + return false; + }; + + if (request.versionNumber == 0) { + // D01.FR.18: Do nothing, not allowed, respond with failed + } else if (request.updateType == UpdateEnum::Full) { + if (!request.localAuthorizationList.has_value() or request.localAuthorizationList.value().empty()) { + this->database_handler->clear_local_authorization_list(); + status = SendLocalListStatusEnum::Accepted; + } else { + const auto& list = request.localAuthorizationList.value(); + + auto has_no_token_info = [](const AuthorizationData& item) { return !item.idTokenInfo.has_value(); }; + + if (!has_duplicate_in_list(list) and + std::find_if(list.begin(), list.end(), has_no_token_info) == list.end()) { + this->database_handler->clear_local_authorization_list(); + this->database_handler->insert_or_update_local_authorization_list(list); + status = SendLocalListStatusEnum::Accepted; + } + } + } else if (request.updateType == UpdateEnum::Differential) { + if (request.versionNumber <= this->database_handler->get_local_authorization_list_version()) { + // D01.FR.19: Do not allow version numbers smaller than current to update differentially + status = SendLocalListStatusEnum::VersionMismatch; + } else if (!request.localAuthorizationList.has_value() or request.localAuthorizationList.value().empty()) { + // D01.FR.05: Do not update database with empty list, only update version number + status = SendLocalListStatusEnum::Accepted; + } else if (has_duplicate_in_list(request.localAuthorizationList.value())) { + // Do nothing with duplicate in list + } else { + const auto& list = request.localAuthorizationList.value(); + + for (auto& item : list) { + if (item.idTokenInfo.has_value()) { + this->database_handler->insert_or_update_local_authorization_list_entry(item.idToken, + item.idTokenInfo.value()); + } else { + this->database_handler->delete_local_authorization_list_entry(item.idToken); + } + } + status = SendLocalListStatusEnum::Accepted; + } + } + return status; +} + std::optional ChargePoint::get_transaction_evseid(const CiString<36>& transaction_id) { for (auto const& [evse_id, evse] : evses) { if (evse->has_active_transaction()) { @@ -1539,7 +1597,7 @@ DataTransferResponse ChargePoint::data_transfer_req(const CiString<255>& vendorI return response; } -SendLocalListStatusEnum ChargePoint::apply_local_authorization_list(const Call& call) { +SendLocalListStatusEnum ChargePoint::apply_local_authorization_list(const SendLocalListRequest& request) { auto status = SendLocalListStatusEnum::Failed; auto has_duplicate_in_list = [](const std::vector& list) { @@ -1553,14 +1611,14 @@ SendLocalListStatusEnum ChargePoint::apply_local_authorization_list(const Calldatabase_handler->clear_local_authorization_list(); status = SendLocalListStatusEnum::Accepted; } else { - const auto& list = call.msg.localAuthorizationList.value(); + const auto& list = request.localAuthorizationList.value(); auto has_no_token_info = [](const AuthorizationData& item) { return !item.idTokenInfo.has_value(); }; @@ -1571,17 +1629,17 @@ SendLocalListStatusEnum ChargePoint::apply_local_authorization_list(const Calldatabase_handler->get_local_authorization_list_version()) { + } else if (request.updateType == UpdateEnum::Differential) { + if (request.versionNumber <= this->database_handler->get_local_authorization_list_version()) { // D01.FR.19: Do not allow version numbers smaller than current to update differentially status = SendLocalListStatusEnum::VersionMismatch; - } else if (!call.msg.localAuthorizationList.has_value() or call.msg.localAuthorizationList.value().empty()) { + } else if (!request.localAuthorizationList.has_value() or request.localAuthorizationList.value().empty()) { // D01.FR.05: Do not update database with empty list, only update version number status = SendLocalListStatusEnum::Accepted; - } else if (has_duplicate_in_list(call.msg.localAuthorizationList.value())) { + } else if (has_duplicate_in_list(request.localAuthorizationList.value())) { // Do nothing with duplicate in list } else { - const auto& list = call.msg.localAuthorizationList.value(); + const auto& list = request.localAuthorizationList.value(); for (auto& item : list) { if (item.idTokenInfo.has_value()) { @@ -1602,7 +1660,7 @@ void ChargePoint::handle_send_local_authorization_list_req(Calldevice_model->get_optional_value(ControllerComponentVariables::LocalAuthListCtrlrEnabled) .value_or(false)) { - response.status = apply_local_authorization_list(call); + response.status = apply_local_authorization_list(call.msg); } else { response.status = SendLocalListStatusEnum::Failed; }