From 59ae3bcd69a5e39e6f0899f1f37895ab967d96ea Mon Sep 17 00:00:00 2001 From: Felix Mauch Date: Tue, 9 Apr 2019 14:39:34 +0200 Subject: [PATCH] Documented URStream and TCPSocket --- include/ur_rtde_driver/comm/stream.h | 102 ++++++++++++++++------- include/ur_rtde_driver/comm/tcp_socket.h | 42 +++++++++- src/comm/tcp_socket.cpp | 4 +- 3 files changed, 116 insertions(+), 32 deletions(-) diff --git a/include/ur_rtde_driver/comm/stream.h b/include/ur_rtde_driver/comm/stream.h index 7cfd37d..b2fafd1 100644 --- a/include/ur_rtde_driver/comm/stream.h +++ b/include/ur_rtde_driver/comm/stream.h @@ -32,13 +32,77 @@ namespace ur_driver { namespace comm { +/*! + * \brief The stream is an abstraction of the TCPSocket that offers reading a full UR data package + * out of the socket. This means, it has to have some knowledge about the package structure to + * peek at the field defining the package length. This is why it is templated with the package + * header type. + */ template class URStream : public TCPSocket { -private: - std::string host_; - int port_; - std::mutex write_mutex_, read_mutex_; +public: + /*! + * \brief Creates a new URStream object. Note, that this does not immediately open the socket, + * that has to be done separately by calling the connect() function. + * + * \param host IP address of the remote host + * \param port Port on which the socket shall be connected + */ + URStream(std::string& host, int port) : host_(host), port_(port) + { + } + + /*! + * \brief Connects to the configured socket. + * + * \returns True on success, false if connection could not be established. + */ + bool connect() + { + return TCPSocket::setup(host_, port_); + } + + /*! + * \brief Disconnects from the configured socket. + */ + void disconnect() + { + LOG_INFO("Disconnecting from %s:%d", host_.c_str(), port_); + TCPSocket::close(); + } + + /*! + * \brief Returns whether the underlying socket is currently closed + */ + bool closed() + { + return getState() == SocketState::Closed; + } + + /*! + * \brief Reads a full UR package out of a socket. For this, it looks into the package and reads + * the byte length from the socket directly. It returns as soon as all bytes for the package are + * read from the socket. + * + * \param[out] buf The byte buffer where the content shall be stored + * \param[in] buf_len Number of bytes allocated for the buffer + * \param[out] read Number of bytes actually read from the socket + * + * \returns True on success, false on error, e.g. the buffer is smaller than the package size. + */ + bool read(uint8_t* buf, const size_t buf_len, size_t& read); + + /*! + * \brief Writes directly to the underlying socket (with a mutex guard) + * + * \param[in] buf Byte stream that should be sent + * \param[in] buf_len Number of bytes in buffer + * \param[out] written Number of bytes actually written to the socket. + * + * \returns false if sending went wrong + */ + bool write(const uint8_t* buf, const size_t buf_len, size_t& written); protected: virtual bool open(int socket_fd, struct sockaddr* address, size_t address_len) @@ -46,39 +110,21 @@ protected: return ::connect(socket_fd, address, address_len) == 0; } -public: - URStream(std::string& host, int port) : host_(host), port_(port) - { - } - - bool connect() - { - return TCPSocket::setup(host_, port_); - } - void disconnect() - { - LOG_INFO("Disconnecting from %s:%d", host_.c_str(), port_); - TCPSocket::close(); - } - - bool closed() - { - return getState() == SocketState::Closed; - } - - bool read(uint8_t* buf, size_t buf_len, size_t& read); - bool write(const uint8_t* buf, size_t buf_len, size_t& written); +private: + std::string host_; + int port_; + std::mutex write_mutex_, read_mutex_; }; template -bool URStream::write(const uint8_t* buf, size_t buf_len, size_t& written) +bool URStream::write(const uint8_t* buf, const size_t buf_len, size_t& written) { std::lock_guard lock(write_mutex_); return TCPSocket::write(buf, buf_len, written); } template -bool URStream::read(uint8_t* buf, size_t buf_len, size_t& total) +bool URStream::read(uint8_t* buf, const size_t buf_len, size_t& total) { std::lock_guard lock(read_mutex_); diff --git a/include/ur_rtde_driver/comm/tcp_socket.h b/include/ur_rtde_driver/comm/tcp_socket.h index 32c4b01..a9c51a6 100644 --- a/include/ur_rtde_driver/comm/tcp_socket.h +++ b/include/ur_rtde_driver/comm/tcp_socket.h @@ -36,6 +36,9 @@ enum class SocketState Closed }; +/*! + * \brief Class for TCP socket abstraction + */ class TCPSocket { private: @@ -66,12 +69,47 @@ public: } bool setSocketFD(int socket_fd); + /*! + * \brief Determines the IP address of the local machine + * + * \returns The IP address of the local machine. + */ std::string getIP(); + /*! + * \brief Reads one byte from the socket + * + * \param character[out] Target buffer + * + * \returns True on success, false otherwise + */ bool read(char* character); - bool read(uint8_t* buf, size_t buf_len, size_t& read); - bool write(const uint8_t* buf, size_t buf_len, size_t& written); + /*! + * \brief Reads data from the socket + * + * \param[out] buf Buffer where the data shall be stored + * \param[in] buf_len Number of bytes allocated for the buffer + * \param[out] read Number of bytes actually read + * + * \returns True on success, false otherwise + */ + bool read(uint8_t* buf, const size_t buf_len, size_t& read); + + /*! + * \brief Writes to the socket + * + * \param[in] buf Buffer of bytes to write + * \param[in] buf_len Number of bytes in the buffer + * \param[out] written Number of bytes actually written + * + * \returns True on success, false otherwise + */ + bool write(const uint8_t* buf, const size_t buf_len, size_t& written); + + /*! + * \brief Closes the connection to the socket. + */ void close(); }; } // namespace comm diff --git a/src/comm/tcp_socket.cpp b/src/comm/tcp_socket.cpp index 577fd4e..76ec7c6 100644 --- a/src/comm/tcp_socket.cpp +++ b/src/comm/tcp_socket.cpp @@ -144,7 +144,7 @@ bool TCPSocket::read(char* character) return read((uint8_t*)character, 1, read_chars); } -bool TCPSocket::read(uint8_t* buf, size_t buf_len, size_t& read) +bool TCPSocket::read(uint8_t* buf, const size_t buf_len, size_t& read) { read = 0; @@ -165,7 +165,7 @@ bool TCPSocket::read(uint8_t* buf, size_t buf_len, size_t& read) return true; } -bool TCPSocket::write(const uint8_t* buf, size_t buf_len, size_t& written) +bool TCPSocket::write(const uint8_t* buf, const size_t buf_len, size_t& written) { written = 0;