Skip to content

Commit

Permalink
After a plug in timeout, a replug is required in order to get authori…
Browse files Browse the repository at this point in the history
…zation and start a transaction at this EVSE. The Auth module now marks an EVSE where a plug in time out occured in order to not select it for a later authorization request

Signed-off-by: Piet Gömpel <[email protected]>
  • Loading branch information
Pietfried committed Dec 2, 2024
1 parent 2b9d96d commit e1df1e0
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 3 deletions.
9 changes: 8 additions & 1 deletion modules/Auth/include/Connector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,12 @@ struct EVSEContext {
}

EVSEContext(int evse_id, int evse_index, const std::vector<Connector>& connectors) :
evse_id(evse_id), evse_index(evse_index), transaction_active(false), connectors(connectors), plugged_in(false) {
evse_id(evse_id),
evse_index(evse_index),
transaction_active(false),
connectors(connectors),
plugged_in(false),
plug_in_timeout(false) {
}

int32_t evse_id;
Expand All @@ -80,6 +85,8 @@ struct EVSEContext {
std::mutex plug_in_mutex;
std::mutex event_mutex;
bool plugged_in;
bool plug_in_timeout; // indicates no authorization received within connection_timeout. Replug is required for this
// EVSE to get authorization and start a transaction

bool is_available();
bool is_unavailable();
Expand Down
5 changes: 3 additions & 2 deletions modules/Auth/lib/AuthHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -668,14 +668,14 @@ void AuthHandler::handle_session_event(const int evse_id, const SessionEvent& ev

this->evses.at(evse_id)->timeout_timer.timeout(
[this, evse_id]() {
EVLOG_info << "Plug In timeout for evse#" << evse_id;
EVLOG_info << "Plug In timeout for evse#" << evse_id << ". Replug required for this EVSE";
this->withdraw_authorization_callback(this->evses.at(evse_id)->evse_index);
{
std::lock_guard<std::mutex> lk(this->plug_in_queue_mutex);
this->plug_in_queue.remove_if([evse_id](int value) { return value == evse_id; });
}

this->evses.at(evse_id)->plugged_in = false;
this->evses.at(evse_id)->plug_in_timeout = true;
},
std::chrono::seconds(this->connection_timeout));
}
Expand All @@ -693,6 +693,7 @@ void AuthHandler::handle_session_event(const int evse_id, const SessionEvent& ev
break;
case SessionEventEnum::SessionFinished: {
this->evses.at(evse_id)->plugged_in = false;
this->evses.at(evse_id)->plug_in_timeout = false;
this->evses.at(evse_id)->identifier.reset();
this->submit_event_for_connector(evse_id, connector_id, ConnectorEvent::SESSION_FINISHED);
this->evses.at(evse_id)->timeout_timer.stop();
Expand Down
4 changes: 4 additions & 0 deletions modules/Auth/lib/Connector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ std::string connector_state_to_string(const ConnectorState& state) {
} // namespace conversions

bool EVSEContext::is_available() {
if (this->plug_in_timeout) {
return false;
}

bool occupied = false;
bool available = false;
for (const auto& connector : this->connectors) {
Expand Down
26 changes: 26 additions & 0 deletions modules/Auth/tests/auth_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1401,4 +1401,30 @@ TEST_F(AuthTest, test_token_timed_out) {
std::this_thread::sleep_for(std::chrono::seconds(CONNECTION_TIMEOUT + 1));
}

/// \brief Test that in case of a plug in timeout, no authorization is given to the EVSE afterwards
TEST_F(AuthTest, test_plug_in_time_out) {
const SessionEvent session_event = get_session_started_event(types::evse_manager::StartSessionReason::EVConnected);
this->auth_handler->handle_session_event(1, session_event);

std::vector<int32_t> connectors{1};
ProvidedIdToken provided_token = get_provided_token(VALID_TOKEN_1, connectors);

std::this_thread::sleep_for(std::chrono::seconds(CONNECTION_TIMEOUT));

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

// no connector should be available since the plug-in event has timed out
TokenHandlingResult result;
std::thread t1([this, provided_token, &result]() { result = this->auth_handler->on_token(provided_token); });
t1.join();

ASSERT_TRUE(result == TokenHandlingResult::NO_CONNECTOR_AVAILABLE);

ASSERT_FALSE(this->auth_receiver->get_authorization(0));
ASSERT_FALSE(this->auth_receiver->get_authorization(1));
}

} // namespace module

0 comments on commit e1df1e0

Please sign in to comment.