Skip to content

Commit

Permalink
added handlers for GetInstalledCertificateIds and InstallCertificate …
Browse files Browse the repository at this point in the history
…for v201 (#242)

added handling for deleting certificates




Feature/ev 312/ev 314 m1 (#221)

* add m1 handlers / callbacks



* switch to async call



* remove removed handler



* add logs



* tmp increase loglevel



* format; correct logging



---------



Adjust certificate hash data conversion (#227)

- Adjust  adjust handle_get_installed_certificate_ids_req;  to use ref.
- in CertificateHashDataChain ignore empty childCertificateHashData lists



feat: empty certificate types list is translated to all types for M03




fix codacy error: make from_ocpp_v201 argument const and by ref

Signed-off-by: Fabian Klemm <[email protected]>
Co-authored-by: pietfried <[email protected]>
  • Loading branch information
klemmpnx and Pietfried authored Nov 3, 2023
1 parent 4c5d505 commit a78f3e4
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 19 deletions.
1 change: 1 addition & 0 deletions include/ocpp/common/evse_security.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ ocpp::v201::CertificateHashDataChain to_ocpp_v201(ocpp::CertificateHashDataChain
ocpp::v201::OCSPRequestData to_ocpp_v201(ocpp::OCSPRequestData other);

ocpp::CertificateType from_ocpp_v201(ocpp::v201::GetCertificateIdUseEnum other);
std::vector<ocpp::CertificateType> from_ocpp_v201(const std::vector<ocpp::v201::GetCertificateIdUseEnum>& other);
ocpp::CaCertificateType from_ocpp_v201(ocpp::v201::InstallCertificateUseEnum other);
ocpp::CertificateSigningUseEnum from_ocpp_v201(ocpp::v201::CertificateSigningUseEnum other);
ocpp::HashAlgorithmEnumType from_ocpp_v201(ocpp::v201::HashAlgorithmEnum other);
Expand Down
13 changes: 13 additions & 0 deletions include/ocpp/v201/charge_point.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,22 @@
#include <ocpp/v201/types.hpp>
#include <ocpp/v201/utils.hpp>

#include "ocpp/v201/messages/Get15118EVCertificate.hpp"
#include <ocpp/v201/messages/Authorize.hpp>
#include <ocpp/v201/messages/BootNotification.hpp>
#include <ocpp/v201/messages/ChangeAvailability.hpp>
#include <ocpp/v201/messages/ClearCache.hpp>
#include <ocpp/v201/messages/DataTransfer.hpp>
#include <ocpp/v201/messages/DeleteCertificate.hpp>
#include <ocpp/v201/messages/GetBaseReport.hpp>
#include <ocpp/v201/messages/GetInstalledCertificateIds.hpp>
#include <ocpp/v201/messages/GetLocalListVersion.hpp>
#include <ocpp/v201/messages/GetLog.hpp>
#include <ocpp/v201/messages/GetReport.hpp>
#include <ocpp/v201/messages/GetTransactionStatus.hpp>
#include <ocpp/v201/messages/GetVariables.hpp>
#include <ocpp/v201/messages/Heartbeat.hpp>
#include <ocpp/v201/messages/InstallCertificate.hpp>
#include <ocpp/v201/messages/MeterValues.hpp>
#include <ocpp/v201/messages/NotifyEvent.hpp>
#include <ocpp/v201/messages/NotifyReport.hpp>
Expand Down Expand Up @@ -344,6 +348,11 @@ class ChargePoint : ocpp::ChargingStationBase {
// Functional Block L: Firmware management
void handle_firmware_update_req(Call<UpdateFirmwareRequest> call);

// Functional Block M: ISO 15118 Certificate Management
void handle_get_installed_certificate_ids_req(Call<GetInstalledCertificateIdsRequest> call);
void handle_install_certificate_req(Call<InstallCertificateRequest> call);
void handle_delete_certificate_req(Call<DeleteCertificateRequest> call);

// Functional Block P: DataTransfer
void handle_data_transfer_req(Call<DataTransferRequest> call);

Expand Down Expand Up @@ -410,6 +419,10 @@ class ChargePoint : ocpp::ChargingStationBase {
/// \param connector_id
void on_session_started(const int32_t evse_id, const int32_t connector_id);

/// \brief Event handler that should be called when the EV sends a certificate request (for update or installation)
/// \param request
Get15118EVCertificateResponse on_get_15118_ev_certificate_request(const Get15118EVCertificateRequest& request);

/// \brief Event handler that should be called when a transaction has started
/// \param evse_id
/// \param connector_id
Expand Down
12 changes: 10 additions & 2 deletions lib/ocpp/common/evse_security.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ ocpp::v201::CertificateHashDataChain to_ocpp_v201(ocpp::CertificateHashDataChain
ocpp::v201::CertificateHashDataChain lhs;
lhs.certificateType = to_ocpp_v201(other.certificateType);
lhs.certificateHashData = to_ocpp_v201(other.certificateHashData);
if (other.childCertificateHashData.has_value()) {
if (other.childCertificateHashData.has_value() && !other.childCertificateHashData.value().empty()) {
std::vector<ocpp::v201::CertificateHashDataType> v;
for (const auto& certificate_hash_data : other.childCertificateHashData.value()) {
v.push_back(to_ocpp_v201(certificate_hash_data));
Expand Down Expand Up @@ -151,6 +151,14 @@ ocpp::CertificateType from_ocpp_v201(ocpp::v201::GetCertificateIdUseEnum other)
}
}

std::vector<ocpp::CertificateType> from_ocpp_v201(const std::vector<ocpp::v201::GetCertificateIdUseEnum>& other) {
std::vector<ocpp::CertificateType> certificate_types;
for (const auto& certificate_id_use_enum : other) {
certificate_types.push_back(from_ocpp_v201(certificate_id_use_enum));
}
return certificate_types;
}

ocpp::CaCertificateType from_ocpp_v201(ocpp::v201::InstallCertificateUseEnum other) {
switch (other) {
case ocpp::v201::InstallCertificateUseEnum::V2GRootCertificate:
Expand Down Expand Up @@ -251,4 +259,4 @@ ocpp::OCSPRequestData from_ocpp_v201(ocpp::v201::OCSPRequestData other) {

} // namespace evse_security_conversions

} // namespace ocpp
} // namespace ocpp
18 changes: 1 addition & 17 deletions lib/ocpp/v16/charge_point_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2843,23 +2843,7 @@ void ChargePointImpl::handle_data_transfer_pnc_get_installed_certificates(Call<D
// prepare argument for getRootCertificate
std::vector<ocpp::CertificateType> certificate_types;
if (req.certificateType.has_value()) {
for (const auto& certificate_id_use_enum : req.certificateType.value()) {
if (certificate_id_use_enum == ocpp::v201::GetCertificateIdUseEnum::V2GRootCertificate) {
certificate_types.push_back(ocpp::CertificateType::V2GRootCertificate);
}
if (certificate_id_use_enum == ocpp::v201::GetCertificateIdUseEnum::MORootCertificate) {
certificate_types.push_back(ocpp::CertificateType::MORootCertificate);
}
if (certificate_id_use_enum == ocpp::v201::GetCertificateIdUseEnum::CSMSRootCertificate) {
certificate_types.push_back(ocpp::CertificateType::CSMSRootCertificate);
}
if (certificate_id_use_enum == ocpp::v201::GetCertificateIdUseEnum::V2GCertificateChain) {
certificate_types.push_back(ocpp::CertificateType::V2GCertificateChain);
}
if (certificate_id_use_enum == ocpp::v201::GetCertificateIdUseEnum::ManufacturerRootCertificate) {
certificate_types.push_back(ocpp::CertificateType::MFRootCertificate);
}
}
certificate_types = ocpp::evse_security_conversions::from_ocpp_v201(req.certificateType.value());
}

ocpp::v201::GetInstalledCertificateIdsResponse get_certificate_ids_response;
Expand Down
95 changes: 95 additions & 0 deletions lib/ocpp/v201/charge_point.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,23 @@ void ChargePoint::on_session_started(const int32_t evse_id, const int32_t connec
this->evses.at(evse_id)->submit_event(connector_id, ConnectorEvent::PlugIn);
}

Get15118EVCertificateResponse
ChargePoint::on_get_15118_ev_certificate_request(const Get15118EVCertificateRequest& request) {
EVLOG_debug << "Received Get15118EVCertificateRequest " << request;
auto future_res = this->send_async<Get15118EVCertificateRequest>(
ocpp::Call<Get15118EVCertificateRequest>(request, this->message_queue->createMessageId()));
const auto response_message = future_res.get();
EVLOG_debug << "Received Get15118EVCertificateResponse " << response_message.message;
if (response_message.messageType != MessageType::Get15118EVCertificateResponse) {
Get15118EVCertificateResponse response;
response.status = Iso15118EVCertificateStatusEnum::Failed;
return response;
}

ocpp::CallResult<Get15118EVCertificateResponse> call_result = response_message.message;
return call_result.msg;
}

void ChargePoint::on_transaction_started(
const int32_t evse_id, const int32_t connector_id, const std::string& session_id, const DateTime& timestamp,
const ocpp::v201::TriggerReasonEnum trigger_reason, const MeterValue& meter_start, const IdToken& id_token,
Expand Down Expand Up @@ -777,6 +794,15 @@ void ChargePoint::handle_message(const EnhancedMessage<v201::MessageType>& messa
case MessageType::GetTransactionStatus:
this->handle_get_transaction_status(json_message);
break;
case MessageType::GetInstalledCertificateIds:
this->handle_get_installed_certificate_ids_req(json_message);
break;
case MessageType::InstallCertificate:
this->handle_install_certificate_req(json_message);
break;
case MessageType::DeleteCertificate:
this->handle_delete_certificate_req(json_message);
break;
default:
if (message.messageTypeId == MessageTypeId::CALL) {
const auto call_error = CallError(message.uniqueId, "NotImplemented", "", json({}));
Expand Down Expand Up @@ -2237,6 +2263,75 @@ void ChargePoint::handle_firmware_update_req(Call<UpdateFirmwareRequest> call) {
}
}

void ChargePoint::handle_get_installed_certificate_ids_req(Call<GetInstalledCertificateIdsRequest> call) {
EVLOG_debug << "Received GetInstalledCertificateIdsRequest: " << call.msg << "\nwith messageId: " << call.uniqueId;
GetInstalledCertificateIdsResponse response;

const auto msg = call.msg;

// prepare argument for getRootCertificate
std::vector<ocpp::CertificateType> certificate_types;
if (msg.certificateType.has_value()) {
certificate_types = ocpp::evse_security_conversions::from_ocpp_v201(msg.certificateType.value());
} else {
certificate_types.push_back(CertificateType::CSMSRootCertificate);
certificate_types.push_back(CertificateType::MFRootCertificate);
certificate_types.push_back(CertificateType::MORootCertificate);
certificate_types.push_back(CertificateType::V2GCertificateChain);
certificate_types.push_back(CertificateType::V2GRootCertificate);
}

// retrieve installed certificates
const auto certificate_hash_data_chains = this->evse_security->get_installed_certificates(certificate_types);

// convert the common type back to the v201 type(s) for the response
std::vector<CertificateHashDataChain> certificate_hash_data_chain_v201;
for (const auto& certificate_hash_data_chain_entry : certificate_hash_data_chains) {
certificate_hash_data_chain_v201.push_back(
ocpp::evse_security_conversions::to_ocpp_v201(certificate_hash_data_chain_entry));
}

if (certificate_hash_data_chain_v201.empty()) {
response.status = GetInstalledCertificateStatusEnum::NotFound;
} else {
response.certificateHashDataChain = certificate_hash_data_chain_v201;
response.status = GetInstalledCertificateStatusEnum::Accepted;
}

ocpp::CallResult<GetInstalledCertificateIdsResponse> call_result(response, call.uniqueId);
this->send<GetInstalledCertificateIdsResponse>(call_result);
}

void ChargePoint::handle_install_certificate_req(Call<InstallCertificateRequest> call) {
EVLOG_debug << "Received InstallCertificateRequest: " << call.msg << "\nwith messageId: " << call.uniqueId;

const auto msg = call.msg;
InstallCertificateResponse response;

const auto result = this->evse_security->install_ca_certificate(
msg.certificate.get(), ocpp::evse_security_conversions::from_ocpp_v201(msg.certificateType));
response.status = ocpp::evse_security_conversions::to_ocpp_v201(result);

ocpp::CallResult<InstallCertificateResponse> call_result(response, call.uniqueId);
this->send<InstallCertificateResponse>(call_result);
}

void ChargePoint::handle_delete_certificate_req(Call<DeleteCertificateRequest> call) {
EVLOG_debug << "Received DeleteCertificateRequest: " << call.msg << "\nwith messageId: " << call.uniqueId;

const auto msg = call.msg;
DeleteCertificateResponse response;

const auto certificate_hash_data = ocpp::evse_security_conversions::from_ocpp_v201(msg.certificateHashData);

const auto status = this->evse_security->delete_certificate(certificate_hash_data);

response.status = ocpp::evse_security_conversions::to_ocpp_v201(status);

ocpp::CallResult<DeleteCertificateResponse> call_result(response, call.uniqueId);
this->send<DeleteCertificateResponse>(call_result);
}

void ChargePoint::handle_data_transfer_req(Call<DataTransferRequest> call) {
const auto msg = call.msg;
DataTransferResponse response;
Expand Down

0 comments on commit a78f3e4

Please sign in to comment.