diff --git a/3rd_party/websocketpp_utils/base64.hpp b/3rd_party/websocketpp_utils/base64.hpp new file mode 100644 index 000000000..9ef499e69 --- /dev/null +++ b/3rd_party/websocketpp_utils/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 ocpp { + +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 ocpp + +#endif // _BASE64_HPP_ \ No newline at end of file diff --git a/3rd_party/websocketpp_utils/uri.hpp b/3rd_party/websocketpp_utils/uri.hpp new file mode 100644 index 000000000..e61c98517 --- /dev/null +++ b/3rd_party/websocketpp_utils/uri.hpp @@ -0,0 +1,312 @@ +/* + * 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 ocpp { + +// 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_valid); + + m_resource = "/"; + m_resource.append(it, uri_string.end()); + } + + 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, m_valid); + } + + 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, m_valid); + } + + 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 ""; + } + } + +private: + uint16_t get_port_from_string(std::string const& port, bool& out_valid) const { + out_valid = true; + 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) { + out_valid = false; + } + + if (t_port == 0) { + out_valid = false; + } + + 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 ocpp + +#endif // WEBSOCKETPP_URI_HPP diff --git a/CMakeLists.txt b/CMakeLists.txt index b51eb71f9..f7df741a0 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() # config and auxillary files diff --git a/dependencies.yaml b/dependencies.yaml index e64e28192..79487392f 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -28,6 +28,7 @@ date: websocketpp: git: https://github.com/zaphoyd/websocketpp.git git_tag: 0.8.2 + cmake_condition: "LIBOCPP_ENABLE_DEPRECATED_WEBSOCKETPP" libevse-security: git: https://github.com/EVerest/libevse-security.git git_tag: v0.6.0 diff --git a/include/ocpp/common/types.hpp b/include/ocpp/common/types.hpp index f53164a8f..43859368e 100644 --- a/include/ocpp/common/types.hpp +++ b/include/ocpp/common/types.hpp @@ -636,6 +636,22 @@ enum class MessageDirection { ChargingStationToCSMS }; +enum class ConnectionFailedReason { + InvalidCSMSCertificate = 0, +}; + +/// +/// \brief Reason why a websocket closes its connection +/// +enum class WebsocketCloseReason : uint8_t { + /// Normal closure + Normal = 1, + ForceTcpDrop, + GoingAway, + AbnormalClose, + ServiceRestart +}; + } // namespace ocpp #endif diff --git a/include/ocpp/common/websocket/websocket.hpp b/include/ocpp/common/websocket/websocket.hpp index 5631bc7e9..6ee4bec0e 100644 --- a/include/ocpp/common/websocket/websocket.hpp +++ b/include/ocpp/common/websocket/websocket.hpp @@ -5,8 +5,8 @@ #include #include -#include -#include + +#include namespace ocpp { /// @@ -18,7 +18,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,10 +34,10 @@ class Websocket { void set_connection_options(const WebsocketConnectionOptions& connection_options); /// \brief disconnect the websocket - void disconnect(websocketpp::close::status::value code); + void disconnect(const WebsocketCloseReason code); // \brief reconnects the websocket after the delay - void reconnect(std::error_code reason, long delay); + void reconnect(long delay); /// \brief indicates if the websocket is connected bool is_connected(); @@ -50,7 +50,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 9d336d996..c66e8f9aa 100644 --- a/include/ocpp/common/websocket/websocket_base.hpp +++ b/include/ocpp/common/websocket/websocket_base.hpp @@ -9,8 +9,6 @@ #include #include -#include -#include #include #include @@ -39,10 +37,6 @@ struct WebsocketConnectionOptions { bool verify_csms_allow_wildcards; }; -enum class ConnectionFailedReason { - InvalidCSMSCertificate = 0, -}; - /// /// \brief contains a websocket abstraction /// @@ -52,16 +46,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 +79,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 @@ -104,16 +96,16 @@ class WebsocketBase { void set_connection_options_base(const WebsocketConnectionOptions& connection_options); /// \brief reconnect the websocket after the delay - virtual void reconnect(std::error_code reason, long delay) = 0; + virtual void reconnect(long delay) = 0; /// \brief disconnect the websocket - void disconnect(websocketpp::close::status::value code); + void disconnect(const 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(const 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 +115,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 0fd37b1a2..dd55e8b45 100644 --- a/include/ocpp/common/websocket/websocket_libwebsockets.hpp +++ b/include/ocpp/common/websocket/websocket_libwebsockets.hpp @@ -38,10 +38,10 @@ class WebsocketTlsTPM final : public WebsocketBase { /// \brief Reconnects the websocket using the delay, a reason for this reconnect can be provided with the /// \param reason parameter /// \param delay delay of the reconnect attempt - void reconnect(std::error_code reason, long delay) override; + void reconnect(long delay) override; /// \brief closes the websocket - void close(websocketpp::close::status::value code, const std::string& reason) override; + void close(const 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 c7f21fb7e..d23618d52 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(); @@ -57,10 +60,10 @@ class WebsocketPlain final : public WebsocketBase { /// \brief Reconnects the websocket using the delay, a reason for this reconnect can be provided with the /// \p reason parameter - void reconnect(std::error_code reason, long delay) override; + void reconnect(long delay) override; /// \brief Closes a plaintext websocket connection - void close(websocketpp::close::status::value code, const std::string& reason) override; + void close(const 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 70c16ac21..80855249e 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); @@ -66,10 +70,10 @@ class WebsocketTLS final : public WebsocketBase { /// \brief Reconnects the websocket using the delay, a reason for this reconnect can be provided with the /// \param reason parameter /// \param delay delay of the reconnect attempt - void reconnect(std::error_code reason, long delay) override; + void reconnect(long delay) override; /// \brief closes the websocket - void close(websocketpp::close::status::value code, const std::string& reason) override; + void close(const 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 63b72348d..5603899aa 100644 --- a/include/ocpp/common/websocket/websocket_uri.hpp +++ b/include/ocpp/common/websocket/websocket_uri.hpp @@ -5,10 +5,21 @@ #include #include + +#if LIBOCPP_ENABLE_DEPRECATED_WEBSOCKETPP #include +#else +#include +#endif namespace ocpp { +#if LIBOCPP_ENABLE_DEPRECATED_WEBSOCKETPP +typedef websocketpp::uri ev_uri; +#else +typedef ocpp::uri ev_uri; +#endif + class Uri { public: Uri(){}; @@ -53,10 +64,9 @@ 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); + ev_uri get_websocketpp_uri() { // FIXME: wrap needed `websocketpp:uri` functionality inside `Uri` + return ev_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 9ee781c53..200b7809e 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(const 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 989098d58..eea396e2d 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -63,7 +63,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 @@ -71,6 +70,11 @@ target_include_directories(ocpp $ ) +target_include_directories(ocpp + PUBLIC + $ +) + ############# # Logging configuration # @@ -120,7 +124,7 @@ target_link_libraries(ocpp everest::timer nlohmann_json_schema_validator everest::evse_security - websocketpp::websocketpp + websockets_shared PRIVATE OpenSSL::SSL OpenSSL::Crypto @@ -131,12 +135,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 401847cc5..4cd1e0f7e 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 8b9db8555..9feb843d7 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,14 +45,14 @@ 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(const WebsocketCloseReason code) { this->logging->sys("Disconnecting"); this->websocket->disconnect(code); } -void Websocket::reconnect(std::error_code reason, long delay) { +void Websocket::reconnect(long delay) { this->logging->sys("Reconnecting"); - this->websocket->reconnect(reason, delay); + this->websocket->reconnect(delay); } bool Websocket::is_connected() { @@ -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 fc55d3250..ae5181a5a 100644 --- a/lib/ocpp/common/websocket/websocket_base.cpp +++ b/lib/ocpp/common/websocket/websocket_base.cpp @@ -4,6 +4,7 @@ #include #include +#include namespace ocpp { WebsocketBase::WebsocketBase() : @@ -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(const 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 ") + ocpp::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 61f7ddebc..4bdfb0c1f 100644 --- a/lib/ocpp/common/websocket/websocket_libwebsockets.cpp +++ b/lib/ocpp/common/websocket/websocket_libwebsockets.cpp @@ -14,6 +14,8 @@ #include #include +#include + #define USING_OPENSSL_3 (OPENSSL_VERSION_NUMBER >= 0x30000000L) #if USING_OPENSSL_3 @@ -414,7 +416,6 @@ void WebsocketTlsTPM::client_loop() { // lws_set_log_level(LLL_ERR | LLL_WARN | LLL_NOTICE | LLL_INFO | LLL_DEBUG | LLL_PARSER | LLL_HEADER | LLL_EXT | // LLL_CLIENT | LLL_LATENCY | LLL_THREAD | LLL_USER, nullptr); - lws_set_log_level(LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE, nullptr); lws_context_creation_info info; memset(&info, 0, sizeof(lws_context_creation_info)); @@ -622,14 +623,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(); @@ -670,8 +671,8 @@ bool WebsocketTlsTPM::connect() { return (connected); } -void WebsocketTlsTPM::reconnect(std::error_code reason, long delay) { - EVLOG_info << "Attempting TLS TPM reconnect with reason: " << reason << " and delay:" << delay; +void WebsocketTlsTPM::reconnect(long delay) { + EVLOG_info << "Attempting TLS TPM reconnect with delay:" << delay; if (this->shutting_down) { EVLOG_info << "Not reconnecting because the websocket is being shutdown."; @@ -680,7 +681,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 +689,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(const WebsocketCloseReason code, const std::string& reason) { EVLOG_info << "Closing TLS TPM websocket with reason: " << reason; { @@ -719,7 +719,7 @@ void WebsocketTlsTPM::close(websocketpp::close::status::value code, const std::s recv_buffered_message.clear(); std::thread closing([this]() { - this->closed_callback(websocketpp::close::status::normal); + this->closed_callback(WebsocketCloseReason::Normal); this->disconnected_callback(); }); closing.detach(); @@ -754,7 +754,7 @@ void WebsocketTlsTPM::on_conn_close() { recv_buffered_message.clear(); std::thread closing([this]() { - this->closed_callback(websocketpp::close::status::normal); + this->closed_callback(WebsocketCloseReason::Normal); this->disconnected_callback(); }); closing.detach(); @@ -775,13 +775,13 @@ void WebsocketTlsTPM::on_conn_fail() { // -1 indicates to always attempt to reconnect if (this->connection_options.max_connection_attempts == -1 or this->connection_attempts <= this->connection_options.max_connection_attempts) { - this->reconnect(std::error_code(), this->get_reconnect_interval()); + this->reconnect(this->get_reconnect_interval()); // Increment reconn attempts 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 7370d55bc..973e4015c 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); @@ -86,7 +120,7 @@ bool WebsocketPlain::send(const std::string& message) { if (ec) { EVLOG_error << "Error sending message over plain websocket: " << ec.message(); - this->reconnect(ec, this->get_reconnect_interval()); + this->reconnect(this->get_reconnect_interval()); EVLOG_info << "(plain) Called reconnect()"; return false; } @@ -96,7 +130,7 @@ bool WebsocketPlain::send(const std::string& message) { return true; } -void WebsocketPlain::reconnect(std::error_code reason, long delay) { +void WebsocketPlain::reconnect(long delay) { if (this->shutting_down) { EVLOG_info << "Not reconnecting because the websocket is being shutdown."; return; @@ -124,17 +158,6 @@ void WebsocketPlain::reconnect(std::error_code reason, long delay) { } } - // TODO(kai): complete error handling, especially making sure that a reconnect is only attempted in reasonable - // circumstances - switch (reason.value()) { - case websocketpp::close::status::force_tcp_drop: - /* code */ - break; - - default: - break; - } - // TODO: spec-conform reconnect, refer to status codes from: // https://github.com/zaphoyd/websocketpp/blob/master/websocketpp/close.hpp } @@ -181,9 +204,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); @@ -226,9 +248,9 @@ void WebsocketPlain::on_close_plain(client* c, websocketpp::connection_hdl hdl) << "), reason: " << con->get_remote_close_reason(); // dont reconnect on normal code if (con->get_remote_close_code() != websocketpp::close::status::normal) { - this->reconnect(error_code, this->get_reconnect_interval()); + this->reconnect(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())); } } @@ -246,23 +268,23 @@ void WebsocketPlain::on_fail_plain(client* c, websocketpp::connection_hdl hdl) { // -1 indicates to always attempt to reconnect if (this->connection_options.max_connection_attempts == -1 or this->connection_attempts <= this->connection_options.max_connection_attempts) { - this->reconnect(ec, this->get_reconnect_interval()); + this->reconnect(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(const 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 bb82d4314..92d640dc5 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) { @@ -97,7 +100,7 @@ bool WebsocketTLS::send(const std::string& message) { if (ec) { EVLOG_error << "Error sending message over TLS websocket: " << ec.message(); - this->reconnect(ec, this->get_reconnect_interval()); + this->reconnect(this->get_reconnect_interval()); EVLOG_info << "(TLS) Called reconnect()"; return false; } @@ -107,7 +110,7 @@ bool WebsocketTLS::send(const std::string& message) { return true; } -void WebsocketTLS::reconnect(std::error_code reason, long delay) { +void WebsocketTLS::reconnect(long delay) { if (this->shutting_down) { EVLOG_info << "Not reconnecting because the websocket is being shutdown."; return; @@ -134,17 +137,6 @@ void WebsocketTLS::reconnect(std::error_code reason, long delay) { } } - // TODO(kai): complete error handling, especially making sure that a reconnect is only attempted in reasonable - // circumstances - switch (reason.value()) { - case websocketpp::close::status::force_tcp_drop: - /* code */ - break; - - default: - break; - } - // TODO: spec-conform reconnect, refer to status codes from: // https://github.com/zaphoyd/websocketpp/blob/master/websocketpp/close.hpp } @@ -304,8 +296,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)); @@ -346,9 +338,9 @@ void WebsocketTLS::on_close_tls(tls_client* c, websocketpp::connection_hdl hdl) << "), reason: " << con->get_remote_close_reason(); // dont reconnect on normal close if (con->get_remote_close_code() != websocketpp::close::status::normal) { - this->reconnect(error_code, this->get_reconnect_interval()); + this->reconnect(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) { @@ -365,13 +357,13 @@ void WebsocketTLS::on_fail_tls(tls_client* c, websocketpp::connection_hdl hdl) { // -1 indicates to always attempt to reconnect if (this->connection_options.max_connection_attempts == -1 or this->connection_attempts <= this->connection_options.max_connection_attempts) { - this->reconnect(ec, this->get_reconnect_interval()); + this->reconnect(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(const WebsocketCloseReason code, const std::string& reason) { EVLOG_info << "Closing TLS websocket."; @@ -379,12 +371,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 dc8e82699..dc0cc3e32 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 = ev_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 74de9cd16..00a10ecd1 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; @@ -1403,7 +1403,7 @@ void ChargePointImpl::handleChangeConfigurationRequest(ocpp::Call call_result(response, call.uniqueId); this->send(call_result); responded = true; - this->websocket->reconnect(std::error_code(), 1000); + this->websocket->reconnect(1000); } else { EVLOG_info << "AuthorizationKey was changed while on security profile 3. Nothing to do."; } @@ -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; @@ -2298,7 +2298,7 @@ void ChargePointImpl::handleCertificateSignedRequest(ocpp::Callconfiguration->getSecurityProfile() == 3) { - this->websocket->reconnect(std::error_code(), 1000); + this->websocket->reconnect(1000); } } diff --git a/lib/ocpp/v201/charge_point.cpp b/lib/ocpp/v201/charge_point.cpp index 4c95da8e8..1768529bc 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); @@ -906,7 +906,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; @@ -914,7 +914,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(); @@ -1533,7 +1533,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 @@ -2042,7 +2042,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); } }