Skip to content

Commit

Permalink
Merge branch 'main' into feature/additional-unit-tests
Browse files Browse the repository at this point in the history
  • Loading branch information
hikinggrass authored Jan 13, 2025
2 parents df30d3c + 3401718 commit 4b05520
Show file tree
Hide file tree
Showing 8 changed files with 309 additions and 37 deletions.
4 changes: 2 additions & 2 deletions modules/Auth/include/AuthHandler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ class AuthHandler {
bool any_parent_id_present(const std::vector<int>& evse_ids);
bool equals_master_pass_group_id(const std::optional<types::authorization::IdToken> parent_id_token);

TokenHandlingResult handle_token(const ProvidedIdToken& provided_token);
TokenHandlingResult handle_token(const ProvidedIdToken& provided_token, std::unique_lock<std::mutex>& lk);

/**
* @brief Method selects an evse based on the configured selection algorithm. It might block until an event
Expand All @@ -262,7 +262,7 @@ class AuthHandler {
* @param selected_evses
* @return int
*/
int select_evse(const std::vector<int>& selected_evses);
int select_evse(const std::vector<int>& selected_evses, std::unique_lock<std::mutex>& lk);

int get_latest_plugin(const std::vector<int>& evse_ids);
void notify_evse(int evse_id, const ProvidedIdToken& provided_token, const ValidationResult& validation_result);
Expand Down
16 changes: 6 additions & 10 deletions modules/Auth/lib/AuthHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ void AuthHandler::initialize() {
}

TokenHandlingResult AuthHandler::on_token(const ProvidedIdToken& provided_token) {
this->event_mutex.lock(); // lock mutex directly because it needs to be unlocked within handle_token
std::unique_lock<std::mutex> lk(this->event_mutex);

TokenHandlingResult result;

// check if token is already currently processed
Expand All @@ -83,7 +84,7 @@ TokenHandlingResult AuthHandler::on_token(const ProvidedIdToken& provided_token)
// process token if not already in process
this->tokens_in_process.insert(provided_token.id_token.value);
this->publish_token_validation_status_callback(provided_token, TokenValidationStatus::Processing);
result = this->handle_token(provided_token);
result = this->handle_token(provided_token, lk);
} else {
// do nothing if token is currently processed
EVLOG_info << "Received token " << everest::staging::helpers::redact(provided_token.id_token.value)
Expand Down Expand Up @@ -114,11 +115,10 @@ TokenHandlingResult AuthHandler::on_token(const ProvidedIdToken& provided_token)

EVLOG_info << "Result for token: " << everest::staging::helpers::redact(provided_token.id_token.value) << ": "
<< conversions::token_handling_result_to_string(result);
this->event_mutex.unlock();
return result;
}

TokenHandlingResult AuthHandler::handle_token(const ProvidedIdToken& provided_token) {
TokenHandlingResult AuthHandler::handle_token(const ProvidedIdToken& provided_token, std::unique_lock<std::mutex>& lk) {
std::vector<int> referenced_evses = this->get_referenced_evses(provided_token);

// Only provided token with type RFID can be used to stop a transaction
Expand Down Expand Up @@ -273,10 +273,7 @@ TokenHandlingResult AuthHandler::handle_token(const ProvidedIdToken& provided_to
- process it against placed reservations
- compare referenced_evses against the evses listed in the validation_result
*/
this->event_mutex
.unlock(); // unlock to allow other threads to continue processing in case select_evse is blocking
int evse_id = this->select_evse(referenced_evses); // might block
this->event_mutex.lock(); // lock again after evse is selected
int evse_id = this->select_evse(referenced_evses, lk); // might block
EVLOG_debug << "Selected evse#" << evse_id
<< " for token: " << everest::staging::helpers::redact(provided_token.id_token.value);
if (evse_id != -1) { // indicates timeout of evse selection
Expand Down Expand Up @@ -449,8 +446,7 @@ int AuthHandler::get_latest_plugin(const std::vector<int>& evse_ids) {
return -1;
}

int AuthHandler::select_evse(const std::vector<int>& selected_evses) {
std::unique_lock<std::mutex> lk(this->event_mutex);
int AuthHandler::select_evse(const std::vector<int>& selected_evses, std::unique_lock<std::mutex>& lk) {
if (selected_evses.size() == 1) {
return selected_evses.at(0);
}
Expand Down
5 changes: 5 additions & 0 deletions modules/Auth/lib/Connector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ bool EVSEContext::is_available() {
return false;
}

// if an identifier is present, an EVSE is not considered available
if (this->identifier.has_value()) {
return false;
}

bool occupied = false;
bool available = false;
for (const auto& connector : this->connectors) {
Expand Down
29 changes: 29 additions & 0 deletions modules/Auth/tests/auth_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1567,4 +1567,33 @@ TEST_F(AuthTest, test_plug_in_time_out) {
ASSERT_FALSE(this->auth_receiver->get_authorization(1));
}

/// \brief Test if a valid id_token is rejected in case a previous token is already assigned to the EVSE
TEST_F(AuthTest, test_subsequent_valid_tokens) {
std::vector<int32_t> connectors{1};
ProvidedIdToken provided_token_1 = get_provided_token(VALID_TOKEN_1, connectors);
ProvidedIdToken provided_token_2 = get_provided_token(VALID_TOKEN_2, connectors);

EXPECT_CALL(mock_publish_token_validation_status_callback,
Call(Field(&ProvidedIdToken::id_token, provided_token_1.id_token), TokenValidationStatus::Processing));
EXPECT_CALL(mock_publish_token_validation_status_callback,
Call(Field(&ProvidedIdToken::id_token, provided_token_1.id_token), TokenValidationStatus::Accepted));
EXPECT_CALL(mock_publish_token_validation_status_callback,
Call(Field(&ProvidedIdToken::id_token, provided_token_2.id_token), TokenValidationStatus::Processing));
EXPECT_CALL(mock_publish_token_validation_status_callback,
Call(Field(&ProvidedIdToken::id_token, provided_token_2.id_token), TokenValidationStatus::Rejected));

TokenHandlingResult result1;
TokenHandlingResult result2;

std::thread t1([this, provided_token_1, &result1]() { result1 = this->auth_handler->on_token(provided_token_1); });
t1.join();
std::thread t2([this, provided_token_2, &result2]() { result2 = this->auth_handler->on_token(provided_token_2); });
t2.join();

ASSERT_TRUE(result1 == TokenHandlingResult::ACCEPTED);
ASSERT_TRUE(result2 == TokenHandlingResult::NO_CONNECTOR_AVAILABLE);
ASSERT_TRUE(this->auth_receiver->get_authorization(0));
ASSERT_FALSE(this->auth_receiver->get_authorization(1));
}

} // namespace module
43 changes: 43 additions & 0 deletions modules/EvseV2G/doc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
.. _everest_modules_handwritten_EvseV2G:

*******************************************
EvseV2G
*******************************************

:ref:`Link <everest_modules_EvseV2G>` to the module's reference.
This module includes a DIN70121 and ISO15118-2 implementation provided by chargebyte GmbH

Feature List
============

This document contains feature lists for DIN70121 and ISO15118-2 features, which EvseV2G supports.
These lists serve as a quick overview of which features are supported.

DIN70121
--------

=============== ==================
Feature Supported
=============== ==================
DC :heavy_check_mark:
ExternalPayment :heavy_check_mark:
=============== ==================

ISO15118-2
----------

======================= ==================
Feature Supported
======================= ==================
AC :heavy_check_mark:
DC :heavy_check_mark:
TCP & TLS 1.2 :heavy_check_mark:
ExternalPayment :heavy_check_mark:
Plug&Charge :heavy_check_mark:
CertificateInstallation :heavy_check_mark:
CertificateUpdate
Pause/Resume :heavy_check_mark:
Schedule Renegotation
Smart Charging
Internet Service
======================= ==================
12 changes: 12 additions & 0 deletions modules/RsPaymentTerminal/manifest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,18 @@ config:
password:
description: Password for the Feig terminal.
type: integer
accept_credit_cards:
description: Indicates whether credit cards should be accepted for the connectors given with `credit_card_connectors`
type: boolean
default: true
credit_card_connectors:
description: >-
If the `accept_credit_cards` is set to true credit cards
will only provide authentication to the given connectors.
If list is empty, authentication will happen to all the connectors.
type: string
default: ""

requires:
session:
interface: session_cost
Expand Down
Loading

0 comments on commit 4b05520

Please sign in to comment.