From 4435b41c89a22e4fb3e09b4da83fd44e769e2b81 Mon Sep 17 00:00:00 2001 From: AssemblyJohn Date: Fri, 12 Apr 2024 15:58:27 +0300 Subject: [PATCH] Removed dependency on websocket++, minimized dependencies Signed-off-by: AssemblyJohn --- 3rd_party/websocketpp/base64.hpp | 171 +++++++++ 3rd_party/websocketpp/uri.hpp | 330 ++++++++++++++++++ CMakeLists.txt | 18 +- include/ocpp/common/types.hpp | 35 ++ include/ocpp/common/websocket/websocket.hpp | 13 +- .../ocpp/common/websocket/websocket_base.hpp | 23 +- .../websocket/websocket_libwebsockets.hpp | 4 +- .../ocpp/common/websocket/websocket_plain.hpp | 5 +- .../ocpp/common/websocket/websocket_tls.hpp | 10 +- .../ocpp/common/websocket/websocket_uri.hpp | 11 +- include/ocpp/v201/charge_point.hpp | 2 +- lib/CMakeLists.txt | 13 +- lib/ocpp/common/websocket/CMakeLists.txt | 14 +- lib/ocpp/common/websocket/websocket.cpp | 12 +- lib/ocpp/common/websocket/websocket_base.cpp | 17 +- .../websocket/websocket_libwebsockets.cpp | 17 +- lib/ocpp/common/websocket/websocket_plain.cpp | 49 ++- lib/ocpp/common/websocket/websocket_tls.cpp | 17 +- lib/ocpp/common/websocket/websocket_uri.cpp | 3 +- lib/ocpp/v16/charge_point_impl.cpp | 8 +- lib/ocpp/v201/charge_point.cpp | 12 +- 21 files changed, 686 insertions(+), 98 deletions(-) create mode 100644 3rd_party/websocketpp/base64.hpp create mode 100644 3rd_party/websocketpp/uri.hpp diff --git a/3rd_party/websocketpp/base64.hpp b/3rd_party/websocketpp/base64.hpp new file mode 100644 index 0000000000..7c91d9f2ce --- /dev/null +++ b/3rd_party/websocketpp/base64.hpp @@ -0,0 +1,171 @@ +/* + ****** + base64.hpp is a repackaging of the base64.cpp and base64.h files into a + single header suitable for use as a header only library. This conversion was + done by Peter Thorson (webmaster@zaphoyd.com) in 2012. All modifications to + the code are redistributed under the same license as the original, which is + listed below. + ****** + + base64.cpp and base64.h + + Copyright (C) 2004-2008 René Nyffenegger + + This source code is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this source code must not be misrepresented; you must not + claim that you wrote the original source code. If you use this source code + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original source code. + + 3. This notice may not be removed or altered from any source distribution. + + René Nyffenegger rene.nyffenegger@adp-gmbh.ch + +*/ + +#ifndef _BASE64_EVEREST_HPP_ +#define _BASE64_EVEREST_HPP_ + +#include + +namespace websocketpp_utils { + +static std::string const base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + +/// Test whether a character is a valid base64 character +/** + * @param c The character to test + * @return true if c is a valid base64 character + */ +static inline bool is_base64(unsigned char c) { + return (c == 43 || // + + (c >= 47 && c <= 57) || // /-9 + (c >= 65 && c <= 90) || // A-Z + (c >= 97 && c <= 122)); // a-z +} + +/// Encode a char buffer into a base64 string +/** + * @param input The input data + * @param len The length of input in bytes + * @return A base64 encoded string representing input + */ +inline std::string base64_encode(unsigned char const* input, size_t len) { + std::string ret; + int i = 0; + int j = 0; + unsigned char char_array_3[3]; + unsigned char char_array_4[4]; + + while (len--) { + char_array_3[i++] = *(input++); + if (i == 3) { + char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; + char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); + char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); + char_array_4[3] = char_array_3[2] & 0x3f; + + for (i = 0; (i < 4); i++) { + ret += base64_chars[char_array_4[i]]; + } + i = 0; + } + } + + if (i) { + for (j = i; j < 3; j++) { + char_array_3[j] = '\0'; + } + + char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; + char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); + char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); + char_array_4[3] = char_array_3[2] & 0x3f; + + for (j = 0; (j < i + 1); j++) { + ret += base64_chars[char_array_4[j]]; + } + + while ((i++ < 3)) { + ret += '='; + } + } + + return ret; +} + +/// Encode a string into a base64 string +/** + * @param input The input data + * @return A base64 encoded string representing input + */ +inline std::string base64_encode(std::string const& input) { + return base64_encode(reinterpret_cast(input.data()), input.size()); +} + +/// Decode a base64 encoded string into a string of raw bytes +/** + * @param input The base64 encoded input data + * @return A string representing the decoded raw bytes + */ +inline std::string base64_decode(std::string const& input) { + size_t in_len = input.size(); + int i = 0; + int j = 0; + int in_ = 0; + unsigned char char_array_4[4], char_array_3[3]; + std::string ret; + + while (in_len-- && (input[in_] != '=') && is_base64(input[in_])) { + char_array_4[i++] = input[in_]; + in_++; + if (i == 4) { + for (i = 0; i < 4; i++) { + char_array_4[i] = static_cast(base64_chars.find(char_array_4[i])); + } + + char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); + char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); + char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; + + for (i = 0; (i < 3); i++) { + ret += char_array_3[i]; + } + i = 0; + } + } + + if (i) { + for (j = i; j < 4; j++) + char_array_4[j] = 0; + + for (j = 0; j < 4; j++) + char_array_4[j] = static_cast(base64_chars.find(char_array_4[j])); + + char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); + char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); + char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; + + for (j = 0; (j < i - 1); j++) { + ret += static_cast(char_array_3[j]); + } + } + + return ret; +} + +} // namespace websocketpp_utils + +#endif // _BASE64_HPP_ \ No newline at end of file diff --git a/3rd_party/websocketpp/uri.hpp b/3rd_party/websocketpp/uri.hpp new file mode 100644 index 0000000000..036d35cd90 --- /dev/null +++ b/3rd_party/websocketpp/uri.hpp @@ -0,0 +1,330 @@ +/* + * Copyright (c) 2014, Peter Thorson. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the WebSocket++ Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef WEBSOCKETPP_URI_EVEREST_HPP +#define WEBSOCKETPP_URI_EVEREST_HPP + +#include +#include +#include +#include + +namespace websocketpp_utils { + +// TODO: figure out why this fixes horrible linking errors. + +/// Default port for ws:// +static uint16_t const uri_default_port = 80; +/// Default port for wss:// +static uint16_t const uri_default_secure_port = 443; + +class uri { +public: + explicit uri(std::string const& uri_string) : m_valid(false) { + std::string::const_iterator it; + std::string::const_iterator temp; + + int state = 0; + + it = uri_string.begin(); + size_t uri_len = uri_string.length(); + + if (uri_len >= 7 && std::equal(it, it + 6, "wss://")) { + m_secure = true; + m_scheme = "wss"; + it += 6; + } else if (uri_len >= 6 && std::equal(it, it + 5, "ws://")) { + m_secure = false; + m_scheme = "ws"; + it += 5; + } else if (uri_len >= 8 && std::equal(it, it + 7, "http://")) { + m_secure = false; + m_scheme = "http"; + it += 7; + } else if (uri_len >= 9 && std::equal(it, it + 8, "https://")) { + m_secure = true; + m_scheme = "https"; + it += 8; + } else { + return; + } + + // extract host. + // either a host string + // an IPv4 address + // or an IPv6 address + if (*it == '[') { + ++it; + // IPv6 literal + // extract IPv6 digits until ] + + // TODO: this doesn't work on g++... not sure why + // temp = std::find(it,it2,']'); + + temp = it; + while (temp != uri_string.end()) { + if (*temp == ']') { + break; + } + ++temp; + } + + if (temp == uri_string.end()) { + return; + } else { + // validate IPv6 literal parts + // can contain numbers, a-f and A-F + m_host.append(it, temp); + } + it = temp + 1; + if (it == uri_string.end()) { + state = 2; + } else if (*it == '/') { + state = 2; + ++it; + } else if (*it == ':') { + state = 1; + ++it; + } else { + // problem + return; + } + } else { + // IPv4 or hostname + // extract until : or / + while (state == 0) { + if (it == uri_string.end()) { + state = 2; + break; + } else if (*it == '/') { + state = 2; + } else if (*it == ':') { + // end hostname start port + state = 1; + } else { + m_host += *it; + } + ++it; + } + } + + // parse port + std::string port; + while (state == 1) { + if (it == uri_string.end()) { + // state is not used after this point presently. + // this should be re-enabled if it ever is needed in a future + // refactoring + // state = 3; + break; + } else if (*it == '/') { + state = 3; + } else { + port += *it; + } + ++it; + } + + m_port = get_port_from_string(port); + + m_resource = "/"; + m_resource.append(it, uri_string.end()); + + m_valid = true; + } + + uri(bool secure, std::string const& host, uint16_t port, std::string const& resource) : + m_scheme(secure ? "wss" : "ws"), + m_host(host), + m_resource(resource.empty() ? "/" : resource), + m_port(port), + m_secure(secure), + m_valid(true) { + } + + uri(bool secure, std::string const& host, std::string const& resource) : + m_scheme(secure ? "wss" : "ws"), + m_host(host), + m_resource(resource.empty() ? "/" : resource), + m_port(secure ? uri_default_secure_port : uri_default_port), + m_secure(secure), + m_valid(true) { + } + + uri(bool secure, std::string const& host, std::string const& port, std::string const& resource) : + m_scheme(secure ? "wss" : "ws"), m_host(host), m_resource(resource.empty() ? "/" : resource), m_secure(secure) { + m_port = get_port_from_string(port); + } + + uri(std::string const& scheme, std::string const& host, uint16_t port, std::string const& resource) : + m_scheme(scheme), + m_host(host), + m_resource(resource.empty() ? "/" : resource), + m_port(port), + m_secure(scheme == "wss" || scheme == "https"), + m_valid(true) { + } + + uri(std::string scheme, std::string const& host, std::string const& resource) : + m_scheme(scheme), + m_host(host), + m_resource(resource.empty() ? "/" : resource), + m_port((scheme == "wss" || scheme == "https") ? uri_default_secure_port : uri_default_port), + m_secure(scheme == "wss" || scheme == "https"), + m_valid(true) { + } + + uri(std::string const& scheme, std::string const& host, std::string const& port, std::string const& resource) : + m_scheme(scheme), + m_host(host), + m_resource(resource.empty() ? "/" : resource), + m_secure(scheme == "wss" || scheme == "https") { + m_port = get_port_from_string(port); + } + + bool get_valid() const { + return m_valid; + } + + bool get_secure() const { + return m_secure; + } + + std::string const& get_scheme() const { + return m_scheme; + } + + std::string const& get_host() const { + return m_host; + } + + std::string get_host_port() const { + if (m_port == (m_secure ? uri_default_secure_port : uri_default_port)) { + return m_host; + } else { + std::stringstream p; + p << m_host << ":" << m_port; + return p.str(); + } + } + + std::string get_authority() const { + std::stringstream p; + p << m_host << ":" << m_port; + return p.str(); + } + + uint16_t get_port() const { + return m_port; + } + + std::string get_port_str() const { + std::stringstream p; + p << m_port; + return p.str(); + } + + std::string const& get_resource() const { + return m_resource; + } + + std::string str() const { + std::stringstream s; + + s << m_scheme << "://" << m_host; + + if (m_port != (m_secure ? uri_default_secure_port : uri_default_port)) { + s << ":" << m_port; + } + + s << m_resource; + return s.str(); + } + + /// Return the query portion + /** + * Returns the query portion (after the ?) of the URI or an empty string if + * there is none. + * + * @return query portion of the URI. + */ + std::string get_query() const { + std::size_t found = m_resource.find('?'); + if (found != std::string::npos) { + return m_resource.substr(found + 1); + } else { + return ""; + } + } + + // get fragment + + // hi <3 + + // get the string representation of this URI + + // std::string base() const; // is this still needed? + + // setter methods set some or all (in the case of parse) based on the input. + // These functions throw a uri_exception on failure. + /*void set_uri(const std::string& uri); + + void set_secure(bool secure); + void set_host(const std::string& host); + void set_port(uint16_t port); + void set_port(const std::string& port); + void set_resource(const std::string& resource);*/ +private: + uint16_t get_port_from_string(std::string const& port) const { + if (port.empty()) { + return (m_secure ? uri_default_secure_port : uri_default_port); + } + + unsigned int t_port = static_cast(atoi(port.c_str())); + + if (t_port > 65535) { + throw new std::runtime_error("Invalid port"); + } + + if (t_port == 0) { + throw new std::runtime_error("Invalid port"); + } + + return static_cast(t_port); + } + + std::string m_scheme; + std::string m_host; + std::string m_resource; + uint16_t m_port; + bool m_secure; + bool m_valid; +}; + +} // namespace websocketpp_utils + +#endif // WEBSOCKETPP_URI_HPP diff --git a/CMakeLists.txt b/CMakeLists.txt index 0cf9e16c8d..13700dc543 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,7 @@ option(BUILD_TESTING "Build unit tests, used if standalone project" OFF) option(CMAKE_RUN_CLANG_TIDY "Run clang-tidy" OFF) option(LIBOCPP_BUILD_EXAMPLES "Build charge_point and central_system binaries." OFF) option(OCPP_INSTALL "Install the library (shared data might be installed anyway)" ${EVC_MAIN_PROJECT}) +option(LIBOCPP_ENABLE_DEPRECATED_WEBSOCKETPP "Usage of deprecated websocket++ instead of libwebsockets" OFF) if((${CMAKE_PROJECT_NAME} STREQUAL ${PROJECT_NAME} OR ${PROJECT_NAME}_BUILD_TESTING) AND BUILD_TESTING) set(LIBOCPP_BUILD_TESTING ON) @@ -32,21 +33,25 @@ if(NOT DISABLE_EDM) # In EDM mode, we can't install exports (because the dependencies usually do not install their exports) set(OCPP_INSTALL OFF) - # FIXME (aw): websocketpp doesn't play well with EDM/CPM - add_library(websocketpp::websocketpp INTERFACE IMPORTED) - set_target_properties(websocketpp::websocketpp PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${websocketpp_SOURCE_DIR}") - + if(LIBOCPP_ENABLE_DEPRECATED_WEBSOCKETPP) + # FIXME (aw): websocketpp doesn't play well with EDM/CPM + add_library(websocketpp::websocketpp INTERFACE IMPORTED) + set_target_properties(websocketpp::websocketpp PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${websocketpp_SOURCE_DIR}") + endif() else() find_package(date REQUIRED) find_package(nlohmann_json REQUIRED) - find_package(nlohmann_json_schema_validator REQUIRED) - find_package(websocketpp REQUIRED) + find_package(nlohmann_json_schema_validator REQUIRED) find_package(libwebsockets REQUIRED) find_package(fsm REQUIRED) find_package(everest-timer REQUIRED) find_package(everest-log REQUIRED) find_package(everest-evse_security REQUIRED) + + if(LIBOCPP_ENABLE_DEPRECATED_WEBSOCKETPP) + find_package(websocketpp REQUIRED) + endif() endif() # library code @@ -55,7 +60,6 @@ add_subdirectory(lib) # config and auxillary files add_subdirectory(config) - # packaging if (OCPP_INSTALL) install( diff --git a/include/ocpp/common/types.hpp b/include/ocpp/common/types.hpp index f53164a8f5..e2dfc64f7c 100644 --- a/include/ocpp/common/types.hpp +++ b/include/ocpp/common/types.hpp @@ -636,6 +636,41 @@ enum class MessageDirection { ChargingStationToCSMS }; +enum class ConnectionFailedReason { + InvalidCSMSCertificate = 0, +}; + +/// +/// \brief Reason why a websocket closes its connection +/// +enum class WebsocketCloseReason : uint8_t { + /// Normal closure, meaning that the purpose for which the connection was + /// established has been fulfilled. + Normal = 1, + /// Close the connection with a forced TCP drop. + /** + * This special value requests that the WebSocket connection be closed by + * forcibly dropping the TCP connection. This will leave the other side of + * the connection with a broken connection and some expensive timeouts. this + * should not be done except in extreme cases or in cases of malicious + * remote endpoints. + */ + ForceTcpDrop, + /// The endpoint was "going away", such as a server going down or a browser + /// navigating away from a page. + GoingAway, + /// A dummy value to indicate that the connection was closed abnormally. + /** + * In such a case there was no close frame to extract a value from. This + * value is illegal on the wire. + */ + AbnormalClose, + /// Indicates that the service is restarted. A client may reconnect and if + /// if it chooses to do so, should reconnect using a randomized delay of + /// 5-30s + ServiceRestart +}; + } // namespace ocpp #endif diff --git a/include/ocpp/common/websocket/websocket.hpp b/include/ocpp/common/websocket/websocket.hpp index 5631bc7e9b..e761a9858f 100644 --- a/include/ocpp/common/websocket/websocket.hpp +++ b/include/ocpp/common/websocket/websocket.hpp @@ -5,8 +5,11 @@ #include #include -#include -#include + +#include + +// #include +// #include namespace ocpp { /// @@ -18,7 +21,7 @@ class Websocket { std::unique_ptr websocket; std::function connected_callback; std::function disconnected_callback; - std::function closed_callback; + std::function closed_callback; std::function message_callback; std::shared_ptr logging; @@ -34,7 +37,7 @@ class Websocket { void set_connection_options(const WebsocketConnectionOptions& connection_options); /// \brief disconnect the websocket - void disconnect(websocketpp::close::status::value code); + void disconnect(WebsocketCloseReason code); // \brief reconnects the websocket after the delay void reconnect(std::error_code reason, long delay); @@ -50,7 +53,7 @@ class Websocket { /// \brief register a \p callback that is called when the websocket connection has been closed and will not attempt /// to reconnect - void register_closed_callback(const std::function& callback); + void register_closed_callback(const std::function& callback); /// \brief register a \p callback that is called when the websocket receives a message void register_message_callback(const std::function& callback); diff --git a/include/ocpp/common/websocket/websocket_base.hpp b/include/ocpp/common/websocket/websocket_base.hpp index 9d336d9960..c6aaa32e2b 100644 --- a/include/ocpp/common/websocket/websocket_base.hpp +++ b/include/ocpp/common/websocket/websocket_base.hpp @@ -9,8 +9,9 @@ #include #include -#include -#include + +// #include +// #include #include #include @@ -39,10 +40,6 @@ struct WebsocketConnectionOptions { bool verify_csms_allow_wildcards; }; -enum class ConnectionFailedReason { - InvalidCSMSCertificate = 0, -}; - /// /// \brief contains a websocket abstraction /// @@ -52,16 +49,14 @@ class WebsocketBase { WebsocketConnectionOptions connection_options; std::function connected_callback; std::function disconnected_callback; - std::function closed_callback; + std::function closed_callback; std::function message_callback; std::function connection_failed_callback; - websocketpp::lib::shared_ptr reconnect_timer; + std::shared_ptr reconnect_timer; std::unique_ptr ping_timer; - websocketpp::connection_hdl handle; std::mutex reconnect_mutex; std::mutex connection_mutex; std::atomic_int reconnect_backoff_ms; - websocketpp::transport::timer_handler reconnect_callback; std::atomic_int connection_attempts; std::atomic_bool shutting_down; std::atomic_bool reconnecting; @@ -87,7 +82,7 @@ class WebsocketBase { virtual void ping() = 0; /// \brief Called when a websocket pong timeout is received - void on_pong_timeout(websocketpp::connection_hdl hdl, std::string msg); + void on_pong_timeout(std::string msg); public: /// \brief Creates a new WebsocketBase object. The `connection_options` must be initialised with @@ -107,13 +102,13 @@ class WebsocketBase { virtual void reconnect(std::error_code reason, long delay) = 0; /// \brief disconnect the websocket - void disconnect(websocketpp::close::status::value code); + void disconnect(WebsocketCloseReason code); /// \brief indicates if the websocket is connected bool is_connected(); /// \brief closes the websocket - virtual void close(websocketpp::close::status::value code, const std::string& reason) = 0; + virtual void close(WebsocketCloseReason code, const std::string& reason) = 0; /// \brief register a \p callback that is called when the websocket is connected successfully void register_connected_callback(const std::function& callback); @@ -123,7 +118,7 @@ class WebsocketBase { /// \brief register a \p callback that is called when the websocket connection has been closed and will not attempt /// to reconnect - void register_closed_callback(const std::function& callback); + void register_closed_callback(const std::function& callback); /// \brief register a \p callback that is called when the websocket receives a message void register_message_callback(const std::function& callback); diff --git a/include/ocpp/common/websocket/websocket_libwebsockets.hpp b/include/ocpp/common/websocket/websocket_libwebsockets.hpp index 8448d25178..aeff1f9c8e 100644 --- a/include/ocpp/common/websocket/websocket_libwebsockets.hpp +++ b/include/ocpp/common/websocket/websocket_libwebsockets.hpp @@ -41,7 +41,7 @@ class WebsocketTlsTPM final : public WebsocketBase { void reconnect(std::error_code reason, long delay) override; /// \brief closes the websocket - void close(websocketpp::close::status::value code, const std::string& reason) override; + void close(WebsocketCloseReason code, const std::string& reason) override; /// \brief send a \p message over the websocket /// \returns true if the message was sent successfully @@ -81,6 +81,8 @@ class WebsocketTlsTPM final : public WebsocketBase { private: std::shared_ptr evse_security; + std::function reconnect_callback; + // Connection related data Everest::SteadyTimer reconnect_timer_tpm; std::unique_ptr websocket_thread; diff --git a/include/ocpp/common/websocket/websocket_plain.hpp b/include/ocpp/common/websocket/websocket_plain.hpp index c7f21fb7eb..753c22eec6 100644 --- a/include/ocpp/common/websocket/websocket_plain.hpp +++ b/include/ocpp/common/websocket/websocket_plain.hpp @@ -26,6 +26,9 @@ class WebsocketPlain final : public WebsocketBase { client ws_client; websocketpp::lib::shared_ptr websocket_thread; + websocketpp::connection_hdl handle; + websocketpp::transport::timer_handler reconnect_callback; + /// \brief Connect to a plain websocket void connect_plain(); @@ -60,7 +63,7 @@ class WebsocketPlain final : public WebsocketBase { void reconnect(std::error_code reason, long delay) override; /// \brief Closes a plaintext websocket connection - void close(websocketpp::close::status::value code, const std::string& reason) override; + void close(WebsocketCloseReason code, const std::string& reason) override; /// \brief send a \p message over the websocket /// \returns true if the message was sent successfully diff --git a/include/ocpp/common/websocket/websocket_tls.hpp b/include/ocpp/common/websocket/websocket_tls.hpp index 70c16ac211..07f6c75e18 100644 --- a/include/ocpp/common/websocket/websocket_tls.hpp +++ b/include/ocpp/common/websocket/websocket_tls.hpp @@ -26,6 +26,10 @@ class WebsocketTLS final : public WebsocketBase { tls_client wss_client; std::shared_ptr evse_security; websocketpp::lib::shared_ptr websocket_thread; + + websocketpp::connection_hdl handle; + websocketpp::transport::timer_handler reconnect_callback; + /// \brief Called when a TLS websocket connection gets initialized, manages the supported TLS versions, cipher lists /// and how verification of the server certificate is handled tls_context on_tls_init(std::string hostname, websocketpp::connection_hdl hdl, int32_t security_profile); @@ -55,10 +59,6 @@ class WebsocketTLS final : public WebsocketBase { explicit WebsocketTLS(const WebsocketConnectionOptions& connection_options, std::shared_ptr evse_security); - ~WebsocketTLS() { - this->websocket_thread->join(); - } - /// \brief connect to a TLS websocket /// \returns true if the websocket is initialized and a connection attempt is made bool connect() override; @@ -69,7 +69,7 @@ class WebsocketTLS final : public WebsocketBase { void reconnect(std::error_code reason, long delay) override; /// \brief closes the websocket - void close(websocketpp::close::status::value code, const std::string& reason) override; + void close(WebsocketCloseReason code, const std::string& reason) override; /// \brief send a \p message over the websocket /// \returns true if the message was sent successfully diff --git a/include/ocpp/common/websocket/websocket_uri.hpp b/include/ocpp/common/websocket/websocket_uri.hpp index 63b72348d9..c4475250c5 100644 --- a/include/ocpp/common/websocket/websocket_uri.hpp +++ b/include/ocpp/common/websocket/websocket_uri.hpp @@ -5,7 +5,8 @@ #include #include -#include + +#include <../3rd_party/websocketpp/uri.hpp> namespace ocpp { @@ -53,10 +54,10 @@ class Uri { return uri.str(); } - websocketpp::uri get_websocketpp_uri() { // FIXME: wrap needed `websocketpp:uri` functionality inside `Uri` - return websocketpp::uri(this->secure, this->host, this->port, - this->path_without_chargepoint_id /* is normalized with ending slash */ + - this->chargepoint_id); + websocketpp_utils::uri get_websocketpp_uri() { // FIXME: wrap needed `websocketpp:uri` functionality inside `Uri` + return websocketpp_utils::uri(this->secure, this->host, this->port, + this->path_without_chargepoint_id /* is normalized with ending slash */ + + this->chargepoint_id); } private: diff --git a/include/ocpp/v201/charge_point.hpp b/include/ocpp/v201/charge_point.hpp index 9ee781c530..72de60c5db 100644 --- a/include/ocpp/v201/charge_point.hpp +++ b/include/ocpp/v201/charge_point.hpp @@ -590,7 +590,7 @@ class ChargePoint : ocpp::ChargingStationBase { /// \brief Disconnects the the websocket connection to the CSMS if it is connected /// \param code Optional websocket close status code (default: normal). - void disconnect_websocket(websocketpp::close::status::value code = websocketpp::close::status::normal); + void disconnect_websocket(WebsocketCloseReason code = WebsocketCloseReason::Normal); /// \brief Chargepoint notifies about new firmware update status firmware_update_status. This function should be /// called during a Firmware Update to indicate the current firmware_update_status. diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index aa8fb95b80..e5b58c9e70 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -56,7 +56,6 @@ add_subdirectory(ocpp/v16/messages) add_subdirectory(ocpp/v201/messages) option(LIBOCPP_USE_BOOST_FILESYSTEM "Usage of boost/filesystem.hpp instead of std::filesystem" OFF) -option(LIBOCPP_ENABLE_DEPRECATED_WEBSOCKETPP "Usage of deprecated websocket++ instead of libwebsockets" OFF) target_include_directories(ocpp PUBLIC @@ -113,7 +112,7 @@ target_link_libraries(ocpp everest::timer nlohmann_json_schema_validator everest::evse_security - websocketpp::websocketpp + websockets_shared PRIVATE OpenSSL::SSL OpenSSL::Crypto @@ -124,12 +123,12 @@ target_link_libraries(ocpp date::date-tz ) -target_link_libraries(ocpp -PUBLIC - websockets_shared -) - if(LIBOCPP_ENABLE_DEPRECATED_WEBSOCKETPP) + target_link_libraries(ocpp + PUBLIC + websocketpp::websocketpp + ) + target_compile_definitions(ocpp PRIVATE LIBOCPP_ENABLE_DEPRECATED_WEBSOCKETPP diff --git a/lib/ocpp/common/websocket/CMakeLists.txt b/lib/ocpp/common/websocket/CMakeLists.txt index 401847cc53..4cd1e0f7e9 100644 --- a/lib/ocpp/common/websocket/CMakeLists.txt +++ b/lib/ocpp/common/websocket/CMakeLists.txt @@ -4,9 +4,13 @@ target_sources(ocpp websocket_base.cpp websocket_uri.cpp websocket.cpp - websocket_libwebsockets.cpp - - # TODO: remove when interface refactor is done - websocket_plain.cpp - websocket_tls.cpp + websocket_libwebsockets.cpp ) + +if(LIBOCPP_ENABLE_DEPRECATED_WEBSOCKETPP) + target_sources(ocpp + PRIVATE + websocket_plain.cpp + websocket_tls.cpp + ) +endif() diff --git a/lib/ocpp/common/websocket/websocket.cpp b/lib/ocpp/common/websocket/websocket.cpp index 8b9db8555c..ba6d0263de 100644 --- a/lib/ocpp/common/websocket/websocket.cpp +++ b/lib/ocpp/common/websocket/websocket.cpp @@ -5,7 +5,12 @@ #include #include +#ifdef LIBOCPP_ENABLE_DEPRECATED_WEBSOCKETPP +#include +#include +#else #include +#endif #include @@ -40,7 +45,7 @@ void Websocket::set_connection_options(const WebsocketConnectionOptions& connect this->websocket->set_connection_options(connection_options); } -void Websocket::disconnect(websocketpp::close::status::value code) { +void Websocket::disconnect(WebsocketCloseReason code) { this->logging->sys("Disconnecting"); this->websocket->disconnect(code); } @@ -72,11 +77,10 @@ void Websocket::register_disconnected_callback(const std::function& call }); } -void Websocket::register_closed_callback( - const std::function& callback) { +void Websocket::register_closed_callback(const std::function& callback) { this->closed_callback = callback; this->websocket->register_closed_callback( - [this](const websocketpp::close::status::value reason) { this->closed_callback(reason); }); + [this](const WebsocketCloseReason reason) { this->closed_callback(reason); }); } void Websocket::register_message_callback(const std::function& callback) { diff --git a/lib/ocpp/common/websocket/websocket_base.cpp b/lib/ocpp/common/websocket/websocket_base.cpp index fc55d32508..cd59ef3a76 100644 --- a/lib/ocpp/common/websocket/websocket_base.cpp +++ b/lib/ocpp/common/websocket/websocket_base.cpp @@ -2,6 +2,7 @@ // Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest #include +#include <../3rd_party/websocketpp/base64.hpp> #include #include namespace ocpp { @@ -43,8 +44,7 @@ void WebsocketBase::register_disconnected_callback(const std::function& this->disconnected_callback = callback; } -void WebsocketBase::register_closed_callback( - const std::function& callback) { +void WebsocketBase::register_closed_callback(const std::function& callback) { this->closed_callback = callback; } @@ -73,7 +73,7 @@ bool WebsocketBase::initialized() { return true; } -void WebsocketBase::disconnect(websocketpp::close::status::value code) { +void WebsocketBase::disconnect(WebsocketCloseReason code) { if (!this->initialized()) { EVLOG_error << "Cannot disconnect a websocket that was not initialized"; return; @@ -81,7 +81,7 @@ void WebsocketBase::disconnect(websocketpp::close::status::value code) { { std::lock_guard lk(this->reconnect_mutex); - if (code == websocketpp::close::status::normal) { + if (code == WebsocketCloseReason::Normal) { this->shutting_down = true; } @@ -109,7 +109,10 @@ std::optional WebsocketBase::getAuthorizationHeader() { EVLOG_debug << "AuthorizationKey present, encoding authentication header"; std::string plain_auth_header = this->connection_options.csms_uri.get_chargepoint_id() + ":" + authorization_key.value(); - auth_header.emplace(std::string("Basic ") + websocketpp::base64_encode(plain_auth_header)); + + // TODO (ioan): replace with libevse-security usage + auth_header.emplace(std::string("Basic ") + websocketpp_utils::base64_encode(plain_auth_header)); + EVLOG_debug << "Basic Auth header: " << auth_header.value(); } @@ -169,11 +172,11 @@ void WebsocketBase::set_authorization_key(const std::string& authorization_key) this->connection_options.authorization_key = authorization_key; } -void WebsocketBase::on_pong_timeout(websocketpp::connection_hdl hdl, std::string msg) { +void WebsocketBase::on_pong_timeout(std::string msg) { if (!this->reconnecting) { EVLOG_info << "Reconnecting because of a pong timeout after " << this->connection_options.pong_timeout_s << "s"; this->reconnecting = true; - this->close(websocketpp::close::status::going_away, "Pong timeout"); + this->close(WebsocketCloseReason::GoingAway, "Pong timeout"); } } diff --git a/lib/ocpp/common/websocket/websocket_libwebsockets.cpp b/lib/ocpp/common/websocket/websocket_libwebsockets.cpp index 430dd687ae..903949a244 100644 --- a/lib/ocpp/common/websocket/websocket_libwebsockets.cpp +++ b/lib/ocpp/common/websocket/websocket_libwebsockets.cpp @@ -622,14 +622,14 @@ bool WebsocketTlsTPM::connect() { } // Bind reconnect callback - this->reconnect_callback = [this](const websocketpp::lib::error_code& ec) { + this->reconnect_callback = [this]() { EVLOG_info << "Reconnecting to TLS websocket at uri: " << this->connection_options.csms_uri.string() << " with security profile: " << this->connection_options.security_profile; // close connection before reconnecting if (this->m_is_connected) { EVLOG_info << "Closing websocket connection before reconnecting"; - this->close(websocketpp::close::status::abnormal_close, "Reconnect"); + this->close(WebsocketCloseReason::AbnormalClose, "Reconnect"); } this->connect(); @@ -680,7 +680,7 @@ void WebsocketTlsTPM::reconnect(std::error_code reason, long delay) { if (this->m_is_connected) { EVLOG_info << "Closing websocket connection before reconnecting"; - this->close(websocketpp::close::status::abnormal_close, "Reconnect"); + this->close(WebsocketCloseReason::AbnormalClose, "Reconnect"); } EVLOG_info << "Reconnecting in: " << delay << "ms" @@ -688,12 +688,11 @@ void WebsocketTlsTPM::reconnect(std::error_code reason, long delay) { { std::lock_guard lk(this->reconnect_mutex); - this->reconnect_timer_tpm.timeout([this]() { this->reconnect_callback(websocketpp::lib::error_code()); }, - std::chrono::milliseconds(delay)); + this->reconnect_timer_tpm.timeout([this]() { this->reconnect_callback(); }, std::chrono::milliseconds(delay)); } } -void WebsocketTlsTPM::close(websocketpp::close::status::value code, const std::string& reason) { +void WebsocketTlsTPM::close(WebsocketCloseReason code, const std::string& reason) { EVLOG_info << "Closing TLS TPM websocket with reason: " << reason; { @@ -715,7 +714,7 @@ void WebsocketTlsTPM::close(websocketpp::close::status::value code, const std::s // Notify any message senders that are waiting, since we can't send messages any more msg_send_cv.notify_all(); - std::thread closing([this]() { this->closed_callback(websocketpp::close::status::normal); }); + std::thread closing([this]() { this->closed_callback(WebsocketCloseReason::Normal); }); closing.detach(); } @@ -741,7 +740,7 @@ void WebsocketTlsTPM::on_conn_close() { // Notify any message senders that are waiting, since we can't send messages any more msg_send_cv.notify_all(); - std::thread closing([this]() { this->closed_callback(websocketpp::close::status::normal); }); + std::thread closing([this]() { this->closed_callback(WebsocketCloseReason::Normal); }); closing.detach(); } @@ -765,7 +764,7 @@ void WebsocketTlsTPM::on_conn_fail() { this->connection_attempts += 1; } else { EVLOG_info << "Closed TLS websocket, reconnect attempts exhausted"; - this->close(websocketpp::close::status::normal, "Connection failed"); + this->close(WebsocketCloseReason::Normal, "Connection failed"); } } diff --git a/lib/ocpp/common/websocket/websocket_plain.cpp b/lib/ocpp/common/websocket/websocket_plain.cpp index 7370d55bc1..5a25fd152e 100644 --- a/lib/ocpp/common/websocket/websocket_plain.cpp +++ b/lib/ocpp/common/websocket/websocket_plain.cpp @@ -12,6 +12,40 @@ namespace ocpp { +websocketpp::close::status::value close_reason_to_value(WebsocketCloseReason reason) { + switch (reason) { + case WebsocketCloseReason::Normal: + return websocketpp::close::status::normal; + case WebsocketCloseReason::ForceTcpDrop: + return websocketpp::close::status::force_tcp_drop; + case WebsocketCloseReason::GoingAway: + return websocketpp::close::status::going_away; + case WebsocketCloseReason::AbnormalClose: + return websocketpp::close::status::abnormal_close; + case WebsocketCloseReason::ServiceRestart: + return websocketpp::close::status::service_restart; + } + + throw std::out_of_range("No known conversion for provided enum of type WebsocketCloseReason"); +} + +WebsocketCloseReason value_to_close_reason(websocketpp::close::status::value value) { + switch (value) { + case websocketpp::close::status::normal: + return WebsocketCloseReason::Normal; + case websocketpp::close::status::force_tcp_drop: + return WebsocketCloseReason::ForceTcpDrop; + case websocketpp::close::status::going_away: + return WebsocketCloseReason::GoingAway; + case websocketpp::close::status::abnormal_close: + return WebsocketCloseReason::AbnormalClose; + case websocketpp::close::status::service_restart: + return WebsocketCloseReason::ServiceRestart; + } + + throw std::out_of_range("No known conversion for provided enum of type websocketpp::close::status::value"); +} + WebsocketPlain::WebsocketPlain(const WebsocketConnectionOptions& connection_options) : WebsocketBase() { set_connection_options(connection_options); @@ -181,9 +215,8 @@ void WebsocketPlain::connect_plain() { websocketpp::lib::placeholders::_1, websocketpp::lib::placeholders::_2)); con->set_pong_timeout(this->connection_options.pong_timeout_s * 1000); // pong timeout in ms - con->set_pong_timeout_handler(websocketpp::lib::bind(&WebsocketPlain::on_pong_timeout, this, - websocketpp::lib::placeholders::_1, - websocketpp::lib::placeholders::_2)); + con->set_pong_timeout_handler( + websocketpp::lib::bind(&WebsocketPlain::on_pong_timeout, this, websocketpp::lib::placeholders::_2)); con->add_subprotocol(conversions::ocpp_protocol_version_to_string(this->connection_options.ocpp_version)); std::lock_guard lk(this->connection_mutex); @@ -228,7 +261,7 @@ void WebsocketPlain::on_close_plain(client* c, websocketpp::connection_hdl hdl) if (con->get_remote_close_code() != websocketpp::close::status::normal) { this->reconnect(error_code, this->get_reconnect_interval()); } else { - this->closed_callback(con->get_remote_close_code()); + this->closed_callback(value_to_close_reason(con->get_remote_close_code())); } } @@ -248,21 +281,21 @@ void WebsocketPlain::on_fail_plain(client* c, websocketpp::connection_hdl hdl) { this->connection_attempts <= this->connection_options.max_connection_attempts) { this->reconnect(ec, this->get_reconnect_interval()); } else { - this->close(websocketpp::close::status::normal, "Connection failed"); + this->close(WebsocketCloseReason::Normal, "Connection failed"); } } -void WebsocketPlain::close(websocketpp::close::status::value code, const std::string& reason) { +void WebsocketPlain::close(WebsocketCloseReason code, const std::string& reason) { EVLOG_info << "Closing plain websocket."; websocketpp::lib::error_code ec; this->cancel_reconnect_timer(); this->ws_client.stop_perpetual(); - this->ws_client.close(this->handle, code, reason, ec); + this->ws_client.close(this->handle, close_reason_to_value(code), reason, ec); if (ec) { EVLOG_error << "Error initiating close of plain websocket: " << ec.message(); // on_close_plain won't be called here so we have to call the closed_callback manually - this->closed_callback(websocketpp::close::status::abnormal_close); + this->closed_callback(WebsocketCloseReason::AbnormalClose); } else { EVLOG_info << "Closed plain websocket successfully."; } diff --git a/lib/ocpp/common/websocket/websocket_tls.cpp b/lib/ocpp/common/websocket/websocket_tls.cpp index bb82d43145..cb7c53a8e4 100644 --- a/lib/ocpp/common/websocket/websocket_tls.cpp +++ b/lib/ocpp/common/websocket/websocket_tls.cpp @@ -16,6 +16,9 @@ namespace ocpp { +extern websocketpp::close::status::value close_reason_to_value(WebsocketCloseReason reason); +extern WebsocketCloseReason value_to_close_reason(websocketpp::close::status::value value); + WebsocketTLS::WebsocketTLS(const WebsocketConnectionOptions& connection_options, std::shared_ptr evse_security) : WebsocketBase(), evse_security(evse_security) { @@ -304,8 +307,8 @@ void WebsocketTLS::connect_tls() { con->set_message_handler(websocketpp::lib::bind( &WebsocketTLS::on_message_tls, this, websocketpp::lib::placeholders::_1, websocketpp::lib::placeholders::_2)); con->set_pong_timeout(this->connection_options.pong_timeout_s * 1000); // pong timeout in ms - con->set_pong_timeout_handler(websocketpp::lib::bind( - &WebsocketTLS::on_pong_timeout, this, websocketpp::lib::placeholders::_1, websocketpp::lib::placeholders::_2)); + con->set_pong_timeout_handler( + websocketpp::lib::bind(&WebsocketTLS::on_pong_timeout, this, websocketpp::lib::placeholders::_2)); con->add_subprotocol(conversions::ocpp_protocol_version_to_string(this->connection_options.ocpp_version)); @@ -348,7 +351,7 @@ void WebsocketTLS::on_close_tls(tls_client* c, websocketpp::connection_hdl hdl) if (con->get_remote_close_code() != websocketpp::close::status::normal) { this->reconnect(error_code, this->get_reconnect_interval()); } else { - this->closed_callback(con->get_remote_close_code()); + this->closed_callback(value_to_close_reason(con->get_remote_close_code())); } } void WebsocketTLS::on_fail_tls(tls_client* c, websocketpp::connection_hdl hdl) { @@ -367,11 +370,11 @@ void WebsocketTLS::on_fail_tls(tls_client* c, websocketpp::connection_hdl hdl) { this->connection_attempts <= this->connection_options.max_connection_attempts) { this->reconnect(ec, this->get_reconnect_interval()); } else { - this->close(websocketpp::close::status::normal, "Connection failed"); + this->close(WebsocketCloseReason::Normal, "Connection failed"); } } -void WebsocketTLS::close(websocketpp::close::status::value code, const std::string& reason) { +void WebsocketTLS::close(WebsocketCloseReason code, const std::string& reason) { EVLOG_info << "Closing TLS websocket."; @@ -379,12 +382,12 @@ void WebsocketTLS::close(websocketpp::close::status::value code, const std::stri this->cancel_reconnect_timer(); this->wss_client.stop_perpetual(); - this->wss_client.close(this->handle, code, reason, ec); + this->wss_client.close(this->handle, close_reason_to_value(code), reason, ec); if (ec) { EVLOG_error << "Error initiating close of TLS websocket: " << ec.message(); // on_close_tls wont be called here so we have to call the closed_callback manually - this->closed_callback(websocketpp::close::status::abnormal_close); + this->closed_callback(WebsocketCloseReason::AbnormalClose); } else { EVLOG_info << "Closed TLS websocket successfully."; } diff --git a/lib/ocpp/common/websocket/websocket_uri.cpp b/lib/ocpp/common/websocket/websocket_uri.cpp index dc8e826992..f627a0e659 100644 --- a/lib/ocpp/common/websocket/websocket_uri.cpp +++ b/lib/ocpp/common/websocket/websocket_uri.cpp @@ -5,7 +5,6 @@ #include #include -#include #include #include @@ -50,7 +49,7 @@ Uri Uri::parse_and_validate(std::string uri, std::string chargepoint_id, int sec uri = "ws://" + uri; } - auto uri_temp = websocketpp::uri(uri); + auto uri_temp = websocketpp_utils::uri(uri); if (!uri_temp.get_valid()) { throw std::invalid_argument("given `uri` is invalid"); } diff --git a/lib/ocpp/v16/charge_point_impl.cpp b/lib/ocpp/v16/charge_point_impl.cpp index 8838c8916e..c3395c7549 100644 --- a/lib/ocpp/v16/charge_point_impl.cpp +++ b/lib/ocpp/v16/charge_point_impl.cpp @@ -187,7 +187,7 @@ void ChargePointImpl::init_websocket() { this->v2g_certificate_timer->stop(); } }); - this->websocket->register_closed_callback([this](const websocketpp::close::status::value reason) { + this->websocket->register_closed_callback([this](const WebsocketCloseReason reason) { if (this->switch_security_profile_callback != nullptr) { this->switch_security_profile_callback(); } @@ -259,7 +259,7 @@ void ChargePointImpl::connect_websocket() { void ChargePointImpl::disconnect_websocket() { if (this->websocket->is_connected()) { - this->websocket->disconnect(websocketpp::close::status::normal); + this->websocket->disconnect(WebsocketCloseReason::Normal); } } @@ -919,7 +919,7 @@ bool ChargePointImpl::stop() { this->stop_all_transactions(); this->database_handler->close_connection(); - this->websocket->disconnect(websocketpp::close::status::normal); + this->websocket->disconnect(WebsocketCloseReason::Normal); this->message_queue->stop(); this->stopped = true; @@ -1442,7 +1442,7 @@ void ChargePointImpl::handleChangeConfigurationRequest(ocpp::CallswitchSecurityProfile(security_profile, 1); }; // disconnected_callback will trigger security_profile_callback when it is set - this->websocket->disconnect(websocketpp::close::status::normal); + this->websocket->disconnect(WebsocketCloseReason::Normal); } } catch (const std::invalid_argument& e) { response.status = ConfigurationStatus::Rejected; diff --git a/lib/ocpp/v201/charge_point.cpp b/lib/ocpp/v201/charge_point.cpp index 094f5bd3c8..536d961a32 100644 --- a/lib/ocpp/v201/charge_point.cpp +++ b/lib/ocpp/v201/charge_point.cpp @@ -199,7 +199,7 @@ void ChargePoint::stop() { this->websocket_timer.stop(); this->client_certificate_expiration_check_timer.stop(); this->v2g_certificate_expiration_check_timer.stop(); - this->disconnect_websocket(websocketpp::close::status::normal); + this->disconnect_websocket(WebsocketCloseReason::Normal); this->message_queue->stop(); } @@ -211,7 +211,7 @@ void ChargePoint::connect_websocket() { } } -void ChargePoint::disconnect_websocket(websocketpp::close::status::value code) { +void ChargePoint::disconnect_websocket(WebsocketCloseReason code) { if (this->websocket != nullptr) { this->disable_automatic_websocket_reconnects = true; this->websocket->disconnect(code); @@ -903,7 +903,7 @@ void ChargePoint::init_websocket() { }); this->websocket->register_closed_callback( - [this, connection_options, configuration_slot](const websocketpp::close::status::value reason) { + [this, connection_options, configuration_slot](const WebsocketCloseReason reason) { EVLOG_warning << "Closed websocket of NetworkConfigurationPriority: " << this->network_configuration_priority + 1 << " which is configurationSlot: " << configuration_slot; @@ -911,7 +911,7 @@ void ChargePoint::init_websocket() { if (!this->disable_automatic_websocket_reconnects) { this->websocket_timer.timeout( [this, reason]() { - if (reason != websocketpp::close::status::service_restart) { + if (reason != WebsocketCloseReason::ServiceRestart) { this->next_network_configuration_priority(); } this->start_websocket(); @@ -1529,7 +1529,7 @@ void ChargePoint::handle_variable_changed(const SetVariableData& set_variable_da if (this->device_model->get_value(ControllerComponentVariables::SecurityProfile) < 3) { // TODO: A01.FR.11 log the change of BasicAuth in Security Log this->websocket->set_authorization_key(set_variable_data.attributeValue.get()); - this->websocket->disconnect(websocketpp::close::status::service_restart); + this->websocket->disconnect(WebsocketCloseReason::ServiceRestart); } } if (component_variable == ControllerComponentVariables::HeartbeatInterval and @@ -2041,7 +2041,7 @@ void ChargePoint::handle_certificate_signed_req(Call c if (response.status == CertificateSignedStatusEnum::Accepted and cert_signing_use == ocpp::CertificateSigningUseEnum::ChargingStationCertificate and this->device_model->get_value(ControllerComponentVariables::SecurityProfile) == 3) { - this->websocket->disconnect(websocketpp::close::status::service_restart); + this->websocket->disconnect(WebsocketCloseReason::ServiceRestart); } }