Skip to content

Commit edea495

Browse files
committed
refactor(OCPP): Move ConnectivityManager from v2 to common namespace
* Move ConnectivityManager to common namespace for reuse across OCPP versions * Refactor constructor to accept logging and message callbacks via setters instead of constructor parameters * Add ChargePoint constructor accepting shared ConnectivityManagerInterface for external injection * Add validation that MessageLogging instance is provided to websocket at construction Signed-off-by: Piet Gömpel <pietgoempel@gmail.com>
1 parent ce530cd commit edea495

20 files changed

Lines changed: 265 additions & 169 deletions

File tree

lib/everest/ocpp/doc/networkconnectivity/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ be activated before it is possible to connect to this interface. To do this, you
1414

1515
In the implementation of this callback, you have to create a promise and return the future to the promise:
1616
```cpp
17-
std::promise<ocpp::v2::ConfigNetworkResult> promise();
18-
std::future<ocpp::v2::ConfigNetworkResult> future = promise.get_future();
17+
std::promise<ocpp::ConfigNetworkResult> promise();
18+
std::future<ocpp::ConfigNetworkResult> future = promise.get_future();
1919
return future;
2020
```
2121

lib/everest/ocpp/include/ocpp/v2/connectivity_manager.hpp renamed to lib/everest/ocpp/include/ocpp/common/connectivity_manager.hpp

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@
1010
#include <functional>
1111
#include <future>
1212
#include <optional>
13+
1314
namespace ocpp {
1415
namespace v2 {
15-
1616
class DeviceModelAbstract;
17+
}
1718

1819
/// \brief The result of a configuration of a network profile.
1920
struct ConfigNetworkResult {
@@ -22,15 +23,24 @@ struct ConfigNetworkResult {
2223
};
2324

2425
using WebsocketConnectionCallback =
25-
std::function<void(int configuration_slot, const NetworkConnectionProfile& network_connection_profile,
26+
std::function<void(int configuration_slot, const ocpp::v2::NetworkConnectionProfile& network_connection_profile,
2627
const OcppProtocolVersion version)>;
2728
using WebsocketConnectionFailedCallback = std::function<void(ConnectionFailedReason reason)>;
2829
using ConfigureNetworkConnectionProfileCallback = std::function<std::future<ConfigNetworkResult>(
29-
const std::int32_t configuration_slot, const NetworkConnectionProfile& network_connection_profile)>;
30+
const std::int32_t configuration_slot, const ocpp::v2::NetworkConnectionProfile& network_connection_profile)>;
3031

3132
class ConnectivityManagerInterface {
3233
public:
3334
virtual ~ConnectivityManagerInterface() = default;
35+
36+
/// \brief Set the \p callback that is called when a message is received from the websocket
37+
///
38+
virtual void set_message_callback(const std::function<void(const std::string& message)>& callback) = 0;
39+
40+
/// \brief Set the logger \p logging
41+
///
42+
virtual void set_logging(std::shared_ptr<MessageLogging> logging) = 0;
43+
3444
/// \brief Set the websocket \p authorization_key
3545
///
3646
virtual void set_websocket_authorization_key(const std::string& authorization_key) = 0;
@@ -63,7 +73,7 @@ class ConnectivityManagerInterface {
6373
/// \brief Gets the cached NetworkConnectionProfile based on the given \p configuration_slot.
6474
/// This returns the value from the cached network connection profiles.
6575
/// \return Returns a profile if the slot is found
66-
virtual std::optional<NetworkConnectionProfile>
76+
virtual std::optional<ocpp::v2::NetworkConnectionProfile>
6777
get_network_connection_profile(const std::int32_t configuration_slot) const = 0;
6878

6979
/// \brief Get the priority of the given configuration slot.
@@ -107,7 +117,7 @@ class ConnectivityManagerInterface {
107117
///
108118
/// \param ocpp_interface The interface that is disconnected.
109119
///
110-
virtual void on_network_disconnected(OCPPInterfaceEnum ocpp_interface) = 0;
120+
virtual void on_network_disconnected(ocpp::v2::OCPPInterfaceEnum ocpp_interface) = 0;
111121

112122
/// \brief Called when the charging station certificate is changed
113123
///
@@ -120,7 +130,7 @@ class ConnectivityManagerInterface {
120130
class ConnectivityManager : public ConnectivityManagerInterface {
121131
private:
122132
/// \brief Reference to the device model
123-
DeviceModelAbstract& device_model;
133+
ocpp::v2::DeviceModelAbstract& device_model;
124134
/// \brief Pointer to the evse security class
125135
std::shared_ptr<EvseSecurity> evse_security;
126136
/// \brief Pointer to the logger
@@ -144,32 +154,33 @@ class ConnectivityManager : public ConnectivityManagerInterface {
144154
std::int32_t active_network_configuration_priority;
145155
int last_known_security_level;
146156
/// @brief Local cached network connection profiles
147-
std::vector<SetNetworkProfileRequest> cached_network_connection_profiles;
157+
std::vector<ocpp::v2::SetNetworkProfileRequest> cached_network_connection_profiles;
148158
/// @brief local cached network connection priorities
149159
std::vector<std::int32_t> network_connection_slots;
150160
OcppProtocolVersion connected_ocpp_version;
151161

152162
public:
153-
ConnectivityManager(DeviceModelAbstract& device_model, std::shared_ptr<EvseSecurity> evse_security,
154-
std::shared_ptr<MessageLogging> logging,
155-
const std::function<void(const std::string& message)>& message_callback);
163+
ConnectivityManager(ocpp::v2::DeviceModelAbstract& device_model, std::shared_ptr<EvseSecurity> evse_security);
156164

165+
void set_message_callback(const std::function<void(const std::string& message)>& callback) override;
166+
void set_logging(std::shared_ptr<MessageLogging> logging) override;
157167
void set_websocket_authorization_key(const std::string& authorization_key) override;
158168
void set_websocket_connection_options(const WebsocketConnectionOptions& connection_options) override;
159169
void set_websocket_connection_options_without_reconnect() override;
160170
void set_websocket_connected_callback(WebsocketConnectionCallback callback) override;
161171
void set_websocket_disconnected_callback(WebsocketConnectionCallback callback) override;
162172
void set_websocket_connection_failed_callback(WebsocketConnectionFailedCallback callback) override;
163173
void set_configure_network_connection_profile_callback(ConfigureNetworkConnectionProfileCallback callback) override;
164-
std::optional<NetworkConnectionProfile>
174+
std::optional<ocpp::v2::NetworkConnectionProfile>
165175
get_network_connection_profile(const std::int32_t configuration_slot) const override;
166-
std::optional<std::int32_t> get_priority_from_configuration_slot(const int configuration_slot) const override;
176+
std::optional<std::int32_t>
177+
get_priority_from_configuration_slot(const std::int32_t configuration_slot) const override;
167178
const std::vector<int>& get_network_connection_slots() const override;
168179
bool is_websocket_connected() override;
169180
void connect(std::optional<std::int32_t> network_profile_slot = std::nullopt) override;
170181
void disconnect() override;
171182
bool send_to_websocket(const std::string& message) override;
172-
void on_network_disconnected(OCPPInterfaceEnum ocpp_interface) override;
183+
void on_network_disconnected(ocpp::v2::OCPPInterfaceEnum ocpp_interface) override;
173184
void on_charging_station_certificate_changed() override;
174185
void confirm_successful_connection() override;
175186

@@ -190,7 +201,7 @@ class ConnectivityManager : public ConnectivityManagerInterface {
190201
/// \return The network configuration containing the network interface to use, nullptr if the request failed or the
191202
/// callback is not configured
192203
std::optional<ConfigNetworkResult>
193-
handle_configure_network_connection_profile_callback(int slot, const NetworkConnectionProfile& profile);
204+
handle_configure_network_connection_profile_callback(int slot, const ocpp::v2::NetworkConnectionProfile& profile);
194205

195206
/// \brief Function invoked when the web socket connected with the \p security_profile
196207
///
@@ -237,5 +248,4 @@ class ConnectivityManager : public ConnectivityManagerInterface {
237248
void remove_network_connection_profiles_below_actual_security_profile();
238249
};
239250

240-
} // namespace v2
241251
} // namespace ocpp

lib/everest/ocpp/include/ocpp/v2/charge_point.hpp

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,28 @@ class ChargePointInterface {
8989
/// The handlers
9090
/// @{
9191

92+
///
93+
/// \brief Shall be called when a websocket connection has been established in case the connectivity_handler is
94+
/// provided exernally.
95+
/// \param configuration_slot The network profile slot used for the connection.
96+
/// \param network_connection_profile The network connection profile used for the connection.
97+
virtual void on_websocket_connected(const int configuration_slot,
98+
const NetworkConnectionProfile& network_connection_profile,
99+
const OcppProtocolVersion ocpp_version) = 0;
100+
101+
///
102+
/// \brief Shall be called when a websocket connection has been disconnected in case the connectivity_handler is
103+
/// provided externally.
104+
/// \param configuration_slot The network profile slot used for the connection.
105+
/// \param network_connection_profile The network connection profile used for the connection.
106+
virtual void on_websocket_disconnected(const int configuration_slot,
107+
const NetworkConnectionProfile& network_connection_profile) = 0;
108+
109+
/// \brief Shall be called when a websocket connection attempt has failed in case the connectivity_handler is
110+
/// provided externally.
111+
/// \param reason The reason why the connection failed.
112+
virtual void on_websocket_connection_failed(ConnectionFailedReason reason) = 0;
113+
92114
///
93115
/// \brief Can be called when a network is disconnected, for example when an ethernet cable is removed.
94116
///
@@ -345,7 +367,7 @@ class ChargePoint : public ChargePointInterface, private ocpp::ChargingStationBa
345367
private:
346368
std::shared_ptr<DeviceModelAbstract> device_model;
347369
std::unique_ptr<EvseManager> evse_manager;
348-
std::unique_ptr<ConnectivityManager> connectivity_manager;
370+
std::shared_ptr<ConnectivityManagerInterface> connectivity_manager;
349371

350372
std::unique_ptr<MessageDispatcherInterface<MessageType>> message_dispatcher;
351373

@@ -412,12 +434,7 @@ class ChargePoint : public ChargePointInterface, private ocpp::ChargingStationBa
412434
// internal helper functions
413435
void initialize(const std::map<std::int32_t, std::int32_t>& evse_connector_structure,
414436
const std::string& message_log_path);
415-
void websocket_connected_callback(const int configuration_slot,
416-
const NetworkConnectionProfile& network_connection_profile,
417-
const OcppProtocolVersion ocpp_version);
418-
void websocket_disconnected_callback(const int configuration_slot,
419-
const NetworkConnectionProfile& network_connection_profile);
420-
void websocket_connection_failed(ConnectionFailedReason reason);
437+
OcspUpdater make_ocsp_updater();
421438
void update_dm_availability_state(const std::int32_t evse_id, const std::int32_t connector_id,
422439
const ConnectorStatusEnum status);
423440

@@ -463,6 +480,22 @@ class ChargePoint : public ChargePointInterface, private ocpp::ChargingStationBa
463480
/// @name Constructors for 2.0.1
464481
/// @{
465482

483+
/// \brief Construct a new ChargePoint object
484+
/// \param evse_connector_structure Map that defines the structure of EVSE and connectors of the chargepoint. The
485+
/// key represents the id of the EVSE and the value represents the number of connectors for this EVSE. The ids of
486+
/// the EVSEs have to increment starting with 1.
487+
/// \param device_model device model instance
488+
/// \param database_handler database handler instance
489+
/// \param evse_security Pointer to evse_security that manages security related operations
490+
/// \param connectivity_manager connectivity manager instance
491+
/// \param message_log_path Path to where logfiles are written to
492+
/// \param callbacks Callbacks that will be registered for ChargePoint
493+
ChargePoint(const std::map<int32_t, int32_t>& evse_connector_structure,
494+
std::shared_ptr<DeviceModelAbstract> device_model, std::shared_ptr<DatabaseHandler> database_handler,
495+
const std::shared_ptr<EvseSecurity> evse_security,
496+
const std::shared_ptr<ConnectivityManagerInterface> connectivity_manager,
497+
const std::string& message_log_path, const Callbacks& callbacks);
498+
466499
/// \brief Construct a new ChargePoint object
467500
/// \param evse_connector_structure Map that defines the structure of EVSE and connectors of the chargepoint. The
468501
/// key represents the id of the EVSE and the value represents the number of connectors for this EVSE. The ids of
@@ -527,6 +560,12 @@ class ChargePoint : public ChargePointInterface, private ocpp::ChargingStationBa
527560
void connect_websocket(std::optional<std::int32_t> network_profile_slot = std::nullopt) override;
528561
void disconnect_websocket() override;
529562

563+
void on_websocket_connected(const int configuration_slot,
564+
const NetworkConnectionProfile& network_connection_profile,
565+
const OcppProtocolVersion ocpp_version) override;
566+
void on_websocket_disconnected(const int configuration_slot,
567+
const NetworkConnectionProfile& network_connection_profile) override;
568+
void on_websocket_connection_failed(ConnectionFailedReason reason) override;
530569
void on_network_disconnected(OCPPInterfaceEnum ocpp_interface) override;
531570

532571
void on_firmware_update_status_notification(std::int32_t request_id,

lib/everest/ocpp/include/ocpp/v2/charge_point_callbacks.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#include <cstdint>
44
#include <memory>
55

6-
#include <ocpp/v2/connectivity_manager.hpp>
6+
#include <ocpp/common/connectivity_manager.hpp>
77
#include <ocpp/v2/device_model.hpp>
88

99
#include <ocpp/v2/messages/BootNotification.hpp>

lib/everest/ocpp/include/ocpp/v2/functional_blocks/functional_block_context.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88

99
namespace ocpp {
1010
class EvseSecurity;
11+
class ConnectivityManagerInterface;
1112

1213
namespace v2 {
1314
class DeviceModelAbstract;
14-
class ConnectivityManagerInterface;
1515
class EvseManagerInterface;
1616
class DatabaseHandlerInterface;
1717
class ComponentStateManagerInterface;

lib/everest/ocpp/include/ocpp/v2/message_dispatcher.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33

44
#pragma once
55

6+
#include <ocpp/common/connectivity_manager.hpp>
67
#include <ocpp/common/message_dispatcher.hpp>
7-
#include <ocpp/v2/connectivity_manager.hpp>
88
#include <ocpp/v2/device_model_abstract.hpp>
99

1010
namespace ocpp {

lib/everest/ocpp/lib/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ target_sources(ocpp
2121
PRIVATE
2222
ocpp/common/call_types.cpp
2323
ocpp/common/charging_station_base.cpp
24+
ocpp/common/connectivity_manager.cpp
2425
ocpp/common/ocpp_logging.cpp
2526
ocpp/common/schemas.cpp
2627
ocpp/common/types.cpp
@@ -89,7 +90,6 @@ if(LIBOCPP_ENABLE_V2)
8990
ocpp/v2/types.cpp
9091
ocpp/v2/utils.cpp
9192
ocpp/v2/component_state_manager.cpp
92-
ocpp/v2/connectivity_manager.cpp
9393
ocpp/v2/message_dispatcher.cpp
9494
ocpp/v2/functional_blocks/authorization.cpp
9595
ocpp/v2/functional_blocks/availability.cpp

lib/everest/ocpp/lib/ocpp/v2/connectivity_manager.cpp renamed to lib/everest/ocpp/lib/ocpp/common/connectivity_manager.cpp

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// SPDX-License-Identifier: Apache-2.0
22
// Copyright 2020 - 2024 Pionix GmbH and Contributors to EVerest
33

4-
#include <ocpp/v2/connectivity_manager.hpp>
4+
#include <ocpp/common/connectivity_manager.hpp>
55

66
#include <everest/logging.hpp>
77
#include <ocpp/v2/ctrlr_component_variables.hpp>
@@ -17,23 +17,37 @@ constexpr std::int32_t default_network_config_timeout_seconds = 60;
1717
} // namespace
1818

1919
namespace ocpp {
20-
namespace v2 {
2120

22-
ConnectivityManager::ConnectivityManager(DeviceModelAbstract& device_model, std::shared_ptr<EvseSecurity> evse_security,
23-
std::shared_ptr<MessageLogging> logging,
24-
const std::function<void(const std::string& message)>& message_callback) :
21+
using NetworkConnectionProfile = ocpp::v2::NetworkConnectionProfile;
22+
using AttributeEnum = ocpp::v2::AttributeEnum;
23+
using DeviceModel = ocpp::v2::DeviceModel;
24+
using OCPPInterfaceEnum = ocpp::v2::OCPPInterfaceEnum;
25+
using SetNetworkProfileRequest = ocpp::v2::SetNetworkProfileRequest;
26+
namespace ControllerComponentVariables = ocpp::v2::ControllerComponentVariables;
27+
28+
ConnectivityManager::ConnectivityManager(ocpp::v2::DeviceModelAbstract& device_model,
29+
std::shared_ptr<EvseSecurity> evse_security) :
2530
device_model{device_model},
2631
evse_security{evse_security},
27-
logging{logging},
32+
message_callback([](const std::string& message) {
33+
EVLOG_warning << "No message callback set in ConnectivityManager. Dropping message: " << message;
34+
}),
2835
websocket{nullptr},
29-
message_callback{message_callback},
3036
wants_to_be_connected{false},
3137
active_network_configuration_priority{0},
3238
last_known_security_level{0},
3339
connected_ocpp_version{OcppProtocolVersion::Unknown} {
3440
cache_network_connection_profiles();
3541
}
3642

43+
void ConnectivityManager::set_message_callback(const std::function<void(const std::string& message)>& callback) {
44+
this->message_callback = callback;
45+
}
46+
47+
void ConnectivityManager::set_logging(std::shared_ptr<MessageLogging> logging) {
48+
this->logging = logging;
49+
}
50+
3751
void ConnectivityManager::set_websocket_authorization_key(const std::string& authorization_key) {
3852
if (this->websocket != nullptr) {
3953
this->websocket->set_authorization_key(authorization_key);
@@ -338,7 +352,7 @@ ConnectivityManager::get_ws_connection_options(const std::int32_t configuration_
338352
this->device_model.get_value<std::string>(ControllerComponentVariables::SecurityCtrlrIdentity),
339353
network_connection_profile.securityProfile);
340354

341-
const auto ocpp_versions = utils::get_ocpp_protocol_versions(
355+
const auto ocpp_versions = ocpp::v2::utils::get_ocpp_protocol_versions(
342356
this->device_model.get_value<std::string>(ControllerComponentVariables::SupportedOcppVersions));
343357

344358
WebsocketConnectionOptions connection_options{
@@ -525,5 +539,4 @@ void ConnectivityManager::remove_network_connection_profiles_below_actual_securi
525539
AttributeEnum::Actual, new_network_priority, VARIABLE_ATTRIBUTE_VALUE_SOURCE_INTERNAL);
526540
}
527541

528-
} // namespace v2
529542
} // namespace ocpp

lib/everest/ocpp/lib/ocpp/common/websocket/websocket.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ namespace ocpp {
1616
Websocket::Websocket(const WebsocketConnectionOptions& connection_options, std::shared_ptr<EvseSecurity> evse_security,
1717
std::shared_ptr<MessageLogging> logging) :
1818
logging(logging) {
19+
20+
if (logging == nullptr) {
21+
throw std::runtime_error("Websocket requires a valid MessageLogging instance");
22+
}
23+
1924
this->websocket = std::make_unique<WebsocketLibwebsockets>(connection_options, evse_security);
2025
}
2126

0 commit comments

Comments
 (0)