Skip to content

Commit ca84690

Browse files
author
Cédric Jimenez
committed
[open-ocpp] Update to Open OCPP v1.0.0
1 parent 3ee6a27 commit ca84690

File tree

4 files changed

+313
-5
lines changed

4 files changed

+313
-5
lines changed

src/chargepoint/config/config.ini

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,8 @@ CertificateStoreMaxLength=50
9292
CpoName=SteVe
9393
SecurityProfile=0
9494
SupportedFileTransferProtocols=FTP,FTPS,HTTP,HTTPS
95+
CentralContractValidationAllowed=true
96+
CertSigningWaitMinimum=2
97+
CertSigningRepeatTimes=1
98+
ContractValidationOffline=true
99+
Iso15118PnCEnabled=false

src/chargepoint/ocpp/ChargePointEventsHandler.cpp

Lines changed: 235 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,35 @@ void ChargePointEventsHandler::transactionDeAuthorized(unsigned int connector_id
301301
cout << "Transaction deauthorized on connector : " << connector_id << endl;
302302
}
303303

304+
/** @copydoc bool IChargePointEventsHandler::getLocalLimitationsSchedule(unsigned int, ocpp::types::ChargingSchedule&) */
305+
bool ChargePointEventsHandler::getLocalLimitationsSchedule(unsigned int connector_id,
306+
unsigned int duration,
307+
ocpp::types::ChargingSchedule& schedule)
308+
{
309+
cout << "Local limitations schedule requested : " << connector_id << " - " << duration << endl;
310+
311+
// Connector data
312+
ConnectorData& connector_data = m_connectors->at(connector_id - 1);
313+
314+
// 1 period
315+
// local limitation = min of connector capacity and cable plugged
316+
ChargingSchedulePeriod period;
317+
if ((connector_data.status >= ChargePointStatus::Charging) && (connector_data.status < ChargePointStatus::Finishing))
318+
{
319+
period.limit = std::min(connector_data.max_setpoint, connector_data.car_cable_capacity);
320+
}
321+
else
322+
{
323+
period.limit = connector_data.max_setpoint;
324+
}
325+
period.numberPhases = connector_data.meter->getNumberOfPhases();
326+
period.startPeriod = 0;
327+
schedule.chargingRateUnit = ChargingRateUnitType::A;
328+
schedule.chargingSchedulePeriod.push_back(period);
329+
330+
return true;
331+
}
332+
304333
/** @copydoc bool IChargePointEventsHandler::resetRequested(ocpp::types::ResetType) */
305334
bool ChargePointEventsHandler::resetRequested(ocpp::types::ResetType reset_type)
306335
{
@@ -450,7 +479,7 @@ ocpp::types::CertificateStatusEnumType ChargePointEventsHandler::caCertificateRe
450479
<< " - certificate subject = " << certificate.subjectString() << endl;
451480

452481
// Check number of installed certificates
453-
if (getNumberOfCaCertificateInstalled(true, true) < m_config.ocppConfig().certificateStoreMaxLength())
482+
if (getNumberOfCaCertificateInstalled(true, true, true) < m_config.ocppConfig().certificateStoreMaxLength())
454483
{
455484
// Compute SHA256 to generate filename
456485
Sha2 sha256;
@@ -468,7 +497,7 @@ ocpp::types::CertificateStatusEnumType ChargePointEventsHandler::caCertificateRe
468497
{
469498
// Central System => Check AdditionalRootCertificateCheck configuration key
470499

471-
if (m_config.ocppConfig().additionalRootCertificateCheck() && (getNumberOfCaCertificateInstalled(false, true) == 0))
500+
if (m_config.ocppConfig().additionalRootCertificateCheck() && (getNumberOfCaCertificateInstalled(false, true, false) == 0))
472501
{
473502
// Additionnal checks :
474503
// - only 1 CA certificate allowed
@@ -724,7 +753,7 @@ std::string ChargePointEventsHandler::getLog(ocpp::types::LogEnumType
724753
bool ChargePointEventsHandler::hasCentralSystemCaCertificateInstalled()
725754
{
726755
// A better implementation would also check the validity dates of the certificates
727-
return ((getNumberOfCaCertificateInstalled(false, true) != 0) && (!m_config.stackConfig().tlsServerCertificateCa().empty()));
756+
return ((getNumberOfCaCertificateInstalled(false, true, false) != 0) && (!m_config.stackConfig().tlsServerCertificateCa().empty()));
728757
}
729758

730759
/** @copydoc bool IChargePointEventsHandler::hasChargePointCertificateInstalled() */
@@ -789,8 +818,206 @@ ocpp::types::UpdateFirmwareStatusEnumType ChargePointEventsHandler::checkFirmwar
789818
return ret;
790819
}
791820

821+
// ISO 15118 PnC extensions
822+
823+
/** @copydoc bool IChargePointEventsHandler::iso15118CheckEvCertificate(const ocpp::x509::Certificate&) */
824+
bool ChargePointEventsHandler::iso15118CheckEvCertificate(const ocpp::x509::Certificate& certificate)
825+
{
826+
bool ret = false;
827+
828+
cout << "ISO15118 EV certificate verification requested : certificate subject = " << certificate.subjectString() << endl;
829+
830+
// Look for MO certificates
831+
for (auto const& dir_entry : std::filesystem::directory_iterator{m_working_dir})
832+
{
833+
if (!dir_entry.is_directory())
834+
{
835+
std::string filename = dir_entry.path().filename();
836+
if (ocpp::helpers::startsWith(filename, "iso_mo_root_") && ocpp::helpers::endsWith(filename, ".pem"))
837+
{
838+
Certificate mo_cert(dir_entry.path());
839+
if (certificate.verify(mo_cert.certificateChain()))
840+
{
841+
cout << "Validated against certificate : " << mo_cert.subjectString() << endl;
842+
ret = true;
843+
break;
844+
}
845+
}
846+
}
847+
}
848+
849+
cout << "EV certificate validated : " << (ret ? "yes" : "no") << endl;
850+
851+
return ret;
852+
}
853+
854+
/** @copydoc bool IChargePointEventsHandler::iso15118ChargePointCertificateReceived(const ocpp::x509::Certificate&) */
855+
bool ChargePointEventsHandler::iso15118ChargePointCertificateReceived(const ocpp::x509::Certificate& certificate)
856+
{
857+
std::string ca_filename;
858+
bool ret = false;
859+
860+
cout << "ISO15118 Charge point certificate installation requested : certificate subject = " << certificate.subjectString() << endl;
861+
862+
// Compute SHA256 to generate filename
863+
Sha2 sha256;
864+
sha256.compute(certificate.pem().c_str(), certificate.pem().size());
865+
866+
std::stringstream name;
867+
name << "iso_cp_" << sha256.resultString() << ".pem";
868+
std::string cert_filename = m_working_dir / name.str();
869+
870+
// Save certificate
871+
if (certificate.toFile(cert_filename))
872+
{
873+
// Retrieve and save the corresponding key/pair with the new certificate
874+
std::string cert_key_filename = cert_filename + ".key";
875+
std::filesystem::copy("/tmp/charge_point_key.key", cert_key_filename);
876+
877+
cout << "Certificate saved : " << cert_filename << endl;
878+
ret = true;
879+
}
880+
else
881+
{
882+
cout << "Unable to save certificate : " << cert_filename << endl;
883+
}
884+
885+
return ret;
886+
}
887+
888+
/** @copydoc ocpp::types::DeleteCertificateStatusEnumType IChargePointEventsHandler::iso15118DeleteCertificate(ocpp::types::HashAlgorithmEnumType,
889+
const std::string&,
890+
const std::string&,
891+
const std::string&) */
892+
ocpp::types::DeleteCertificateStatusEnumType ChargePointEventsHandler::iso15118DeleteCertificate(
893+
ocpp::types::HashAlgorithmEnumType hash_algorithm,
894+
const std::string& issuer_name_hash,
895+
const std::string& issuer_key_hash,
896+
const std::string& serial_number)
897+
{
898+
cout << "ISO15118 certificate deletion requested : hash = " << HashAlgorithmEnumTypeHelper.toString(hash_algorithm)
899+
<< " - serial number = " << serial_number << endl;
900+
return deleteCertificate(hash_algorithm, issuer_name_hash, issuer_key_hash, serial_number);
901+
}
902+
903+
/** @copydoc void IChargePointEventsHandler::iso15118GetInstalledCertificates(
904+
bool,
905+
bool,
906+
bool,
907+
std::vector<std::tuple<GetCertificateIdUseEnumType, Certificate, std::vector<Certificate>>>&) */
908+
void ChargePointEventsHandler::iso15118GetInstalledCertificates(
909+
bool v2g_root_certificate,
910+
bool mo_root_certificate,
911+
bool v2g_certificate_chain,
912+
std::vector<std::tuple<ocpp::types::GetCertificateIdUseEnumType, ocpp::x509::Certificate, std::vector<ocpp::x509::Certificate>>>&
913+
certificates)
914+
{
915+
cout << "ISO15118 get installed certificates requested : v2g_root_certificate = " << (v2g_root_certificate ? "yes" : "no")
916+
<< " - mo_root_certificate = " << (mo_root_certificate ? "yes" : "no")
917+
<< " - v2g_certificate_chain = " << (v2g_certificate_chain ? "yes" : "no") << endl;
918+
919+
for (auto const& dir_entry : std::filesystem::directory_iterator{m_working_dir})
920+
{
921+
if (!dir_entry.is_directory())
922+
{
923+
std::string filename = dir_entry.path().filename();
924+
if (v2g_root_certificate)
925+
{
926+
if (ocpp::helpers::startsWith(filename, "iso_v2g_root_") && ocpp::helpers::endsWith(filename, ".pem"))
927+
{
928+
auto tuple = std::make_tuple(GetCertificateIdUseEnumType::V2GRootCertificate,
929+
Certificate(dir_entry.path()),
930+
std::vector<ocpp::x509::Certificate>());
931+
certificates.emplace_back(std::move(tuple));
932+
}
933+
}
934+
if (mo_root_certificate)
935+
{
936+
if (ocpp::helpers::startsWith(filename, "iso_mo_root_") && ocpp::helpers::endsWith(filename, ".pem"))
937+
{
938+
auto tuple = std::make_tuple(GetCertificateIdUseEnumType::MORootCertificate,
939+
Certificate(dir_entry.path()),
940+
std::vector<ocpp::x509::Certificate>());
941+
certificates.emplace_back(std::move(tuple));
942+
}
943+
}
944+
if (v2g_certificate_chain)
945+
{
946+
if (ocpp::helpers::startsWith(filename, "iso_v2g_chain_") && ocpp::helpers::endsWith(filename, ".pem"))
947+
{
948+
auto tuple = std::make_tuple(GetCertificateIdUseEnumType::V2GCertificateChain,
949+
Certificate(dir_entry.path()),
950+
std::vector<ocpp::x509::Certificate>());
951+
certificates.emplace_back(std::move(tuple));
952+
}
953+
}
954+
}
955+
}
956+
}
957+
958+
/** @copydoc ocpp::types::InstallCertificateStatusEnumType IChargePointEventsHandler::iso15118CertificateReceived(
959+
ocpp::types::InstallCertificateUseEnumType type,
960+
const ocpp::x509::Certificate&) */
961+
ocpp::types::InstallCertificateStatusEnumType ChargePointEventsHandler::iso15118CertificateReceived(
962+
ocpp::types::InstallCertificateUseEnumType type, const ocpp::x509::Certificate& certificate)
963+
{
964+
std::string cert_filename;
965+
InstallCertificateStatusEnumType ret = InstallCertificateStatusEnumType::Rejected;
966+
967+
cout << "ISO15118 certificate installation requested : type = " << InstallCertificateUseEnumTypeHelper.toString(type)
968+
<< " - certificate subject = " << certificate.subjectString() << endl;
969+
970+
// Check number of installed certificates
971+
if (getNumberOfCaCertificateInstalled(true, true, true) < m_config.ocppConfig().certificateStoreMaxLength())
972+
{
973+
// Compute SHA256 to generate filename
974+
Sha2 sha256;
975+
sha256.compute(certificate.pem().c_str(), certificate.pem().size());
976+
977+
if (type == InstallCertificateUseEnumType::V2GRootCertificate)
978+
{
979+
// V2 root certificate
980+
std::stringstream name;
981+
name << "iso_v2g_root_" << sha256.resultString() << ".pem";
982+
cert_filename = m_working_dir / name.str();
983+
}
984+
else
985+
{
986+
// MO root certificate
987+
std::stringstream name;
988+
name << "iso_mo_root_" << sha256.resultString() << ".pem";
989+
cert_filename = m_working_dir / name.str();
990+
}
991+
992+
// Save certificate
993+
if (certificate.toFile(cert_filename))
994+
{
995+
ret = InstallCertificateStatusEnumType::Accepted;
996+
cout << "Certificate saved : " << cert_filename << endl;
997+
}
998+
else
999+
{
1000+
ret = InstallCertificateStatusEnumType::Failed;
1001+
cout << "Unable to save certificate : " << cert_filename << endl;
1002+
}
1003+
}
1004+
else
1005+
{
1006+
cout << "Maximum number of certificates reached" << endl;
1007+
}
1008+
1009+
return ret;
1010+
}
1011+
1012+
/** @copydoc void IChargePointEventsHandler::iso15118GenerateCsr(std::string&) */
1013+
void ChargePointEventsHandler::iso15118GenerateCsr(std::string& csr)
1014+
{
1015+
cout << "Generate ISO15118 CSR requested" << endl;
1016+
generateCsr(csr);
1017+
}
1018+
7921019
/** @brief Get the number of installed CA certificates */
793-
unsigned int ChargePointEventsHandler::getNumberOfCaCertificateInstalled(bool manufacturer, bool central_system)
1020+
unsigned int ChargePointEventsHandler::getNumberOfCaCertificateInstalled(bool manufacturer, bool central_system, bool iso15118)
7941021
{
7951022
unsigned int count = 0;
7961023
for (auto const& dir_entry : std::filesystem::directory_iterator{m_working_dir})
@@ -806,6 +1033,10 @@ unsigned int ChargePointEventsHandler::getNumberOfCaCertificateInstalled(bool ma
8061033
{
8071034
count++;
8081035
}
1036+
if (iso15118 && ocpp::helpers::startsWith(filename, "iso_") && ocpp::helpers::endsWith(filename, ".pem"))
1037+
{
1038+
count++;
1039+
}
8091040
}
8101041
}
8111042
return count;

src/chargepoint/ocpp/ChargePointEventsHandler.h

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ class ChargePointEventsHandler : public ocpp::chargepoint::IChargePointEventsHan
101101
/** @copydoc void IChargePointEventsHandler::transactionDeAuthorized(unsigned int) */
102102
void transactionDeAuthorized(unsigned int connector_id) override;
103103

104+
/** @copydoc bool IChargePointEventsHandler::getLocalLimitationsSchedule(unsigned int, unsigned int, ocpp::types::ChargingSchedule&) */
105+
bool getLocalLimitationsSchedule(unsigned int connector_id, unsigned int duration, ocpp::types::ChargingSchedule& schedule) override;
106+
104107
/** @copydoc bool IChargePointEventsHandler::resetRequested(ocpp::types::ResetType) */
105108
bool resetRequested(ocpp::types::ResetType reset_type) override;
106109

@@ -167,6 +170,44 @@ class ChargePointEventsHandler : public ocpp::chargepoint::IChargePointEventsHan
167170
* const ocpp::x509::Certificate&) */
168171
ocpp::types::UpdateFirmwareStatusEnumType checkFirmwareSigningCertificate(const ocpp::x509::Certificate& signing_certificate) override;
169172

173+
// ISO 15118 PnC extensions
174+
175+
/** @copydoc bool IChargePointEventsHandler::iso15118CheckEvCertificate(const ocpp::x509::Certificate&) */
176+
bool iso15118CheckEvCertificate(const ocpp::x509::Certificate& certificate) override;
177+
178+
/** @copydoc bool IChargePointEventsHandler::iso15118ChargePointCertificateReceived(const ocpp::x509::Certificate&) */
179+
bool iso15118ChargePointCertificateReceived(const ocpp::x509::Certificate& certificate) override;
180+
181+
/** @copydoc ocpp::types::DeleteCertificateStatusEnumType IChargePointEventsHandler::iso15118DeleteCertificate(ocpp::types::HashAlgorithmEnumType,
182+
const std::string&,
183+
const std::string&,
184+
const std::string&) */
185+
ocpp::types::DeleteCertificateStatusEnumType iso15118DeleteCertificate(ocpp::types::HashAlgorithmEnumType hash_algorithm,
186+
const std::string& issuer_name_hash,
187+
const std::string& issuer_key_hash,
188+
const std::string& serial_number) override;
189+
190+
/** @copydoc void IChargePointEventsHandler::iso15118GetInstalledCertificates(
191+
bool,
192+
bool,
193+
bool,
194+
std::vector<std::tuple<GetCertificateIdUseEnumType, Certificate, std::vector<Certificate>>>&) */
195+
void iso15118GetInstalledCertificates(
196+
bool v2g_root_certificate,
197+
bool mo_root_certificate,
198+
bool v2g_certificate_chain,
199+
std::vector<std::tuple<ocpp::types::GetCertificateIdUseEnumType, ocpp::x509::Certificate, std::vector<ocpp::x509::Certificate>>>&
200+
certificates) override;
201+
202+
/** @copydoc ocpp::types::InstallCertificateStatusEnumType IChargePointEventsHandler::iso15118CertificateReceived(
203+
* ocpp::types::InstallCertificateUseEnumType type,
204+
const ocpp::x509::Certificate&) */
205+
ocpp::types::InstallCertificateStatusEnumType iso15118CertificateReceived(ocpp::types::InstallCertificateUseEnumType type,
206+
const ocpp::x509::Certificate& certificate) override;
207+
208+
/** @copydoc void IChargePointEventsHandler::iso15118GenerateCsr(std::string&) */
209+
void iso15118GenerateCsr(std::string& csr) override;
210+
170211
// API
171212

172213
/** @brief Indicate a pending remote start transaction */
@@ -210,7 +251,7 @@ class ChargePointEventsHandler : public ocpp::chargepoint::IChargePointEventsHan
210251
bool m_is_connected;
211252

212253
/** @brief Get the number of installed CA certificates */
213-
unsigned int getNumberOfCaCertificateInstalled(bool manufacturer, bool central_system);
254+
unsigned int getNumberOfCaCertificateInstalled(bool manufacturer, bool central_system, bool iso15118);
214255
};
215256

216257
#endif // CHARGEPOINTEVENTSHANDLER_H

0 commit comments

Comments
 (0)