From 8d3ac08c176dd5320443fcb81116721961c8cb3c Mon Sep 17 00:00:00 2001 From: Matthew Matl Date: Tue, 2 Apr 2024 23:20:17 -0700 Subject: [PATCH] fix: attach 8-bit path segments to session info --- docs/source/misc/8-bit_path_segments.rst | 22 +++++++++++------ src/MessageRouter.cpp | 6 ++--- src/MessageRouter.h | 8 +----- src/SessionInfo.cpp | 19 ++++++++++++--- src/SessionInfo.h | 31 ++++++++++++++++++++++-- src/SessionInfoIf.h | 6 +++++ 6 files changed, 68 insertions(+), 24 deletions(-) diff --git a/docs/source/misc/8-bit_path_segments.rst b/docs/source/misc/8-bit_path_segments.rst index 25b7572..eadb01e 100644 --- a/docs/source/misc/8-bit_path_segments.rst +++ b/docs/source/misc/8-bit_path_segments.rst @@ -2,24 +2,30 @@ =================== Some devices only support 8-bit path segments. In order to set up -**EIPScanner** to use 8-bit path segments, a *MessageRouter* with the -**USE_8_BIT_PATH_SEGMENTS** flag set should be passed to the *ConnectionManager* -upon construction: +**EIPScanner** to use 8-bit path segments, specify the **use_8_bit_path_segments** +parameter when creating the *SessionInfo* object for the adapter. .. code-block:: cpp - #include "MessageRouter.h" + #include #include "ConnectionManager.h" + #include "MessageRouter.h" + #include "SessionInfo.h" + using eipScanner::cip::connectionManager::ConnectionParameters; using eipScanner::ConnectionManager; using eipScanner::MessageRouter; + using eipScanner::SessionInfo; int main() { - MessageRouter::SPtr mr_ptr = std::make_shared(MessageRouter::USE_8_BIT_PATH_SEGMENTS); - ConnectionManager _connectionManager = ConnectionManager(mr_ptr); - - /* ConnectionManager now uses 8-bit path segments */ + auto si = std::make_shared("172.28.1.3", 0xAF12, true); + + /* The connection now uses 8-bit path segments for the forward open*/ + ConnectionManager connectionManager; + ConnectionParameters parameters; + auto io = connectionManager.forwardOpen(si, parameters); + connectionManager.forwardClose(si, io); return 0; } diff --git a/src/MessageRouter.cpp b/src/MessageRouter.cpp index 16f2232..f2c55b9 100644 --- a/src/MessageRouter.cpp +++ b/src/MessageRouter.cpp @@ -22,9 +22,7 @@ namespace eipScanner { using eip::EncapsPacket; using eip::EncapsPacketFactory; - MessageRouter::MessageRouter(bool use_8_bit_path_segments) - : _use_8_bit_path_segments(use_8_bit_path_segments) - {}; + MessageRouter::MessageRouter() {}; MessageRouter::~MessageRouter() = default; @@ -43,7 +41,7 @@ namespace eipScanner { Logger(LogLevel::INFO) << "Send request: service=0x" << std::hex << static_cast(service) << " epath=" << path.toString(); - MessageRouterRequest request{service, path, data, _use_8_bit_path_segments}; + MessageRouterRequest request{service, path, data, si->getUse8BitPathSegments()}; CommonPacketItemFactory commonPacketItemFactory; CommonPacket commonPacket; diff --git a/src/MessageRouter.h b/src/MessageRouter.h index c4a0bda..4e4c1c4 100644 --- a/src/MessageRouter.h +++ b/src/MessageRouter.h @@ -21,13 +21,10 @@ namespace eipScanner { class MessageRouter { public: using SPtr = std::shared_ptr; - - static constexpr bool USE_8_BIT_PATH_SEGMENTS = true; - /** * @brief Default constructor */ - MessageRouter(bool use_8_bit_path_segments=false); + MessageRouter(); /** * @brief Default destructor @@ -73,9 +70,6 @@ namespace eipScanner { */ virtual cip::MessageRouterResponse sendRequest(SessionInfoIf::SPtr si, cip::CipUsint service, const cip::EPath& path) const; - - private: - bool _use_8_bit_path_segments; }; } diff --git a/src/SessionInfo.cpp b/src/SessionInfo.cpp index cbfb179..fa1f6e5 100644 --- a/src/SessionInfo.cpp +++ b/src/SessionInfo.cpp @@ -17,9 +17,18 @@ namespace eipScanner { using eip::EncapsPacketFactory; using eip::EncapsStatusCodes; + SessionInfo::SessionInfo(const std::string &host, int port, const std::chrono::milliseconds &timeout, bool use_8_bit_path_segments) : SessionInfo(host, port, timeout) { + _use_8_bit_path_segments = use_8_bit_path_segments; + } + + SessionInfo::SessionInfo(const std::string &host, int port, bool use_8_bit_path_segments) : SessionInfo(host, port, std::chrono::milliseconds(1000)) { + _use_8_bit_path_segments = use_8_bit_path_segments; + } + SessionInfo::SessionInfo(const std::string &host, int port, const std::chrono::milliseconds &timeout) : _socket{sockets::EndPoint(host, port), timeout} - , _sessionHandle{0} { + , _sessionHandle{0} + , _use_8_bit_path_segments{false} { _socket.setRecvTimeout(timeout); EncapsPacket packet = EncapsPacketFactory().createRegisterSessionPacket(); @@ -35,7 +44,7 @@ namespace eipScanner { } SessionInfo::SessionInfo(const std::string &host, int port) - : SessionInfo(host, port, std::chrono::milliseconds(1000)) { + : SessionInfo(host, port, std::chrono::milliseconds(1000), false) { } SessionInfo::~SessionInfo() { @@ -76,4 +85,8 @@ namespace eipScanner { return _socket.getRemoteEndPoint(); } -} \ No newline at end of file + bool SessionInfo::getUse8BitPathSegments() const { + return _use_8_bit_path_segments; + } + +} diff --git a/src/SessionInfo.h b/src/SessionInfo.h index 313abe6..2e0834f 100644 --- a/src/SessionInfo.h +++ b/src/SessionInfo.h @@ -27,7 +27,28 @@ namespace eipScanner { * @brief Establishes an EIP session with an EIP adapter * @param host The IP address of the adapter * @param port The port of the adapter - * @param timeout timout to connect and receive the response + * @param timeout timeout to connect and receive the response + * @param use_8_bit_path_segments use 8-bit instead of 16-bit path segments + * @throw std::runtime_error + * @throw std::system_error + */ + SessionInfo(const std::string &host, int port, const std::chrono::milliseconds& timeout, bool use_8_bit_path_segments); + + /** + * @brief Establishes an EIP session with an EIP adapter + * @param host The IP address of the adapter + * @param port The port of the adapter + * @param use_8_bit_path_segments use 8-bit instead of 16-bit path segments + * @throw std::runtime_error + * @throw std::system_error + */ + SessionInfo(const std::string &host, int port, bool use_8_bit_path_segments); + + /** + * @brief Establishes an EIP session with an EIP adapter + * @param host The IP address of the adapter + * @param port The port of the adapter + * @param timeout timeout to connect and receive the response * @throw std::runtime_error * @throw std::system_error */ @@ -66,10 +87,16 @@ namespace eipScanner { */ sockets::EndPoint getRemoteEndPoint() const override; + /** + * Gets whether this connection should use 8-bit path segments. + * @return + */ + bool getUse8BitPathSegments() const override; + private: sockets::TCPSocket _socket; cip::CipUdint _sessionHandle; - + bool _use_8_bit_path_segments; }; } diff --git a/src/SessionInfoIf.h b/src/SessionInfoIf.h index 974a7e5..1a4088e 100644 --- a/src/SessionInfoIf.h +++ b/src/SessionInfoIf.h @@ -37,6 +37,12 @@ namespace eipScanner { * @return */ virtual sockets::EndPoint getRemoteEndPoint() const = 0; + + /** + * Gets whether this connection should use 8-bit path segments. + * @return + */ + virtual bool getUse8BitPathSegments() const = 0; }; } #endif //EIPSCANNER_SESSIONINFOIF_H