From 8cf5f2d3a5f95223996087b5adf8bf4bb7559a15 Mon Sep 17 00:00:00 2001 From: zhaohe Date: Mon, 24 Apr 2023 18:40:28 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=96=B0=E6=A0=BC=E5=BC=8F=E5=8C=96so?= =?UTF-8?q?cketcanpp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/driver/sockcanpp/CanDriver.cpp | 482 +++++++++++---------- core/driver/sockcanpp/CanDriver.hpp | 212 +++++---- core/driver/sockcanpp/CanId.hpp | 421 ++++++++++-------- core/driver/sockcanpp/CanMessage.hpp | 71 +-- .../sockcanpp/exceptions/CanCloseException.hpp | 40 +- core/driver/sockcanpp/exceptions/CanException.hpp | 47 +- .../sockcanpp/exceptions/CanInitException.hpp | 40 +- .../exceptions/InvalidSocketException.hpp | 47 +- 8 files changed, 747 insertions(+), 613 deletions(-) diff --git a/core/driver/sockcanpp/CanDriver.cpp b/core/driver/sockcanpp/CanDriver.cpp index 6335cbb..779a722 100644 --- a/core/driver/sockcanpp/CanDriver.cpp +++ b/core/driver/sockcanpp/CanDriver.cpp @@ -56,234 +56,276 @@ namespace sockcanpp { - using exceptions::CanCloseException; - using exceptions::CanException; - using exceptions::CanInitException; - using exceptions::InvalidSocketException; - - using std::mutex; - using std::queue; - using std::string; - using std::strncpy; - using std::unique_lock; - using std::chrono::milliseconds; - using std::this_thread::sleep_for; - - ////////////////////////////////////// - // PUBLIC IMPLEMENTATION // - ////////////////////////////////////// - - const int32_t CanDriver::CAN_MAX_DATA_LENGTH = 8; - const int32_t CanDriver::CAN_SOCK_RAW = CAN_RAW; - const int32_t CanDriver::CAN_SOCK_SEVEN = 7; - - CanDriver::CanDriver(string canInterface, int32_t canProtocol, const CanId defaultSenderId): - CanDriver(canInterface, canProtocol, 0 /* match all */, defaultSenderId) {} - - CanDriver::CanDriver(const string canInterface, const int32_t canProtocol, const int32_t filterMask, const CanId defaultSenderId): - _defaultSenderId(defaultSenderId), _canProtocol(canProtocol), _canInterface(canInterface), _canFilterMask(filterMask), _socketFd(-1) { - initialiseSocketCan(); - } - - /** - * @brief Blocks until one or more CAN messages appear on the bus, or until the timeout runs out. - * - * @param timeout The time (in millis) to wait before timing out. - * - * @return true If messages are available on the bus. - * @return false Otherwise. - */ - bool CanDriver::waitForMessages(milliseconds timeout) { - if (_socketFd < 0) { throw InvalidSocketException("Invalid socket!", _socketFd); } - - unique_lock locky(_lock); - - fd_set readFileDescriptors; - timeval waitTime; - waitTime.tv_sec = timeout.count() / 1000; - waitTime.tv_usec = timeout.count() * 1000; - - FD_ZERO(&readFileDescriptors); - FD_SET(_socketFd, &readFileDescriptors); - _queueSize = select(_socketFd + 1, &readFileDescriptors, 0, 0, &waitTime); - - return _queueSize > 0; - } - - /** - * @brief Attempts to read a message from the associated CAN bus. - * - * @return CanMessage The message read from the bus. - */ - CanMessage CanDriver::readMessage() { - return readMessageLock(); - } - - /** - * @brief readMessage deadlock guard, attempts to read a message from the associated CAN bus. - * - * @return CanMessage The message read from the bus. - */ - CanMessage CanDriver::readMessageLock(bool const lock) { - std::unique_ptr> _lockLck{nullptr}; - if (lock) - _lockLck = std::unique_ptr>{new std::unique_lock{_lock}}; - if (0 > _socketFd) - throw InvalidSocketException("Invalid socket!", _socketFd); - int32_t readBytes{0}; - can_frame canFrame; - memset(&canFrame, 0, sizeof(can_frame)); - readBytes = read(_socketFd, &canFrame, sizeof(can_frame)); - if (0 > readBytes) - throw CanException(formatString("FAILED to read from CAN! Error: %d => %s", errno, strerror(errno)), _socketFd); - return CanMessage{canFrame}; - } - - /** - * @brief Attempts to send a CAN message on the associated bus. - * - * @param message The message to be sent. - * @param forceExtended Whether or not to force use of an extended ID. - * - * @return int32_t The amount of bytes sent on the bus. - */ - int32_t CanDriver::sendMessage(const CanMessage message, bool forceExtended) { - if (_socketFd < 0) { throw InvalidSocketException("Invalid socket!", _socketFd); } - - unique_lock locky(_lock); - - int32_t bytesWritten = 0; - - if (message.getFrameData().size() > CAN_MAX_DATA_LENGTH) { - throw CanException(formatString("INVALID data length! Message must be smaller than %d bytes!", CAN_MAX_DATA_LENGTH), _socketFd); - } - - auto canFrame = message.getRawFrame(); - - if (forceExtended || (message.getCanId() > CAN_SFF_MASK)) { canFrame.can_id |= CAN_EFF_FLAG; } - - bytesWritten = write(_socketFd, (const void*)&canFrame, sizeof(canFrame)); - - if (bytesWritten == -1) { throw CanException(formatString("FAILED to write data to socket! Error: %d => %s", errno, strerror(errno)), _socketFd); } - - return bytesWritten; - } - - /** - * @brief Attempts to send a queue of messages on the associated CAN bus. - * - * @param messages A queue containing the messages to be sent. - * @param delay If greater than 0, will delay the sending of the next message. - * @param forceExtended Whether or not to force use of an extended ID. - * - * @return int32_t The total amount of bytes sent. - */ - int32_t CanDriver::sendMessageQueue(queue messages, milliseconds delay, bool forceExtended) { - if (_socketFd < 0) { throw InvalidSocketException("Invalid socket!", _socketFd); } - - int32_t totalBytesWritten = 0; - - while (!messages.empty()) { - totalBytesWritten += sendMessage(messages.front(), forceExtended); - messages.pop(); - } - - return totalBytesWritten; - } - - /** - * @brief Attempts to read all messages stored in the buffer for the associated CAN bus. - * - * @return queue A queue containing the messages read from the bus buffer. - */ - queue CanDriver::readQueuedMessages() { - if (_socketFd < 0) - throw InvalidSocketException("Invalid socket!", _socketFd); - unique_lock locky(_lock); - queue messages; - for (int32_t i = _queueSize; 0 < i; --i) - messages.emplace(readMessageLock(false)); - return messages; - } - - /** - * @brief Attempts to set the filter mask for the associated CAN bus. - * - * @param mask The bit mask to apply. - */ - void CanDriver::setCanFilterMask(const int32_t mask) { - if (_socketFd < 0) { throw InvalidSocketException("Invalid socket!", _socketFd); } - - unique_lock locky(_lock); - can_filter canFilter; - - canFilter.can_id = _defaultSenderId; - canFilter.can_mask = mask; - - if (setsockopt(_socketFd, SOL_CAN_RAW, CAN_RAW_FILTER, &canFilter, sizeof(canFilter)) == -1) { - throw CanInitException(formatString("FAILED to set CAN filter mask %x on socket %d! Error: %d => %s", mask, _socketFd, errno, strerror(errno))); - } - - _canFilterMask = mask; - } - - ////////////////////////////////////// - // PROTECTED IMPLEMENTATION // - ////////////////////////////////////// - - - /** - * @brief Initialises the underlying CAN socket. - */ - void CanDriver::initialiseSocketCan() { - // unique_lock locky(_lock); - - struct sockaddr_can address; - struct ifreq ifaceRequest; - int64_t fdOptions = 0; - int32_t tmpReturn; +using exceptions::CanCloseException; +using exceptions::CanException; +using exceptions::CanInitException; +using exceptions::InvalidSocketException; + +using std::mutex; +using std::queue; +using std::string; +using std::strncpy; +using std::unique_lock; +using std::chrono::milliseconds; +using std::this_thread::sleep_for; + +////////////////////////////////////// +// PUBLIC IMPLEMENTATION // +////////////////////////////////////// + +const int32_t CanDriver::CAN_MAX_DATA_LENGTH = 8; +const int32_t CanDriver::CAN_SOCK_RAW = CAN_RAW; +const int32_t CanDriver::CAN_SOCK_SEVEN = 7; + +CanDriver::CanDriver(string canInterface, int32_t canProtocol, + const CanId defaultSenderId) + : CanDriver(canInterface, canProtocol, 0 /* match all */, defaultSenderId) { +} + +CanDriver::CanDriver(const string canInterface, const int32_t canProtocol, + const int32_t filterMask, const CanId defaultSenderId) + : _defaultSenderId(defaultSenderId), _canProtocol(canProtocol), + _canInterface(canInterface), _canFilterMask(filterMask), _socketFd(-1) { + initialiseSocketCan(); +} - memset(&address, 0, sizeof(sizeof(struct sockaddr_can))); - memset(&ifaceRequest, 0, sizeof(sizeof(struct ifreq))); +/** + * @brief Blocks until one or more CAN messages appear on the bus, or until the + * timeout runs out. + * + * @param timeout The time (in millis) to wait before timing out. + * + * @return true If messages are available on the bus. + * @return false Otherwise. + */ +bool CanDriver::waitForMessages(milliseconds timeout) { + if (_socketFd < 0) { + throw InvalidSocketException("Invalid socket!", _socketFd); + } + + unique_lock locky(_lock); + + fd_set readFileDescriptors; + timeval waitTime; + waitTime.tv_sec = timeout.count() / 1000; + waitTime.tv_usec = timeout.count() * 1000; + + FD_ZERO(&readFileDescriptors); + FD_SET(_socketFd, &readFileDescriptors); + _queueSize = select(_socketFd + 1, &readFileDescriptors, 0, 0, &waitTime); + + return _queueSize > 0; +} - _socketFd = socket(PF_CAN, SOCK_RAW, _canProtocol); +/** + * @brief Attempts to read a message from the associated CAN bus. + * + * @return CanMessage The message read from the bus. + */ +CanMessage CanDriver::readMessage() { return readMessageLock(); } - if (_socketFd == -1) { - throw CanInitException(formatString("FAILED to initialise socketcan! Error: %d => %s", errno, strerror(errno))); - } +/** + * @brief readMessage deadlock guard, attempts to read a message from the + * associated CAN bus. + * + * @return CanMessage The message read from the bus. + */ +CanMessage CanDriver::readMessageLock(bool const lock) { + std::unique_ptr> _lockLck{nullptr}; + if (lock) + _lockLck = std::unique_ptr>{ + new std::unique_lock{_lock}}; + if (0 > _socketFd) + throw InvalidSocketException("Invalid socket!", _socketFd); + int32_t readBytes{0}; + can_frame canFrame; + memset(&canFrame, 0, sizeof(can_frame)); + readBytes = read(_socketFd, &canFrame, sizeof(can_frame)); + if (0 > readBytes) + throw CanException(formatString("FAILED to read from CAN! Error: %d => %s", + errno, strerror(errno)), + _socketFd); + return CanMessage{canFrame}; +} - strcpy(ifaceRequest.ifr_name, _canInterface.c_str()); +/** + * @brief Attempts to send a CAN message on the associated bus. + * + * @param message The message to be sent. + * @param forceExtended Whether or not to force use of an extended ID. + * + * @return int32_t The amount of bytes sent on the bus. + */ +int32_t CanDriver::sendMessage(const CanMessage message, bool forceExtended) { + if (_socketFd < 0) { + throw InvalidSocketException("Invalid socket!", _socketFd); + } + + unique_lock locky(_lock); + + int32_t bytesWritten = 0; + + if (message.getFrameData().size() > CAN_MAX_DATA_LENGTH) { + throw CanException( + formatString( + "INVALID data length! Message must be smaller than %d bytes!", + CAN_MAX_DATA_LENGTH), + _socketFd); + } + + auto canFrame = message.getRawFrame(); + + if (forceExtended || (message.getCanId() > CAN_SFF_MASK)) { + canFrame.can_id |= CAN_EFF_FLAG; + } + + bytesWritten = write(_socketFd, (const void *)&canFrame, sizeof(canFrame)); + + if (bytesWritten == -1) { + throw CanException( + formatString("FAILED to write data to socket! Error: %d => %s", errno, + strerror(errno)), + _socketFd); + } + + return bytesWritten; +} + +/** + * @brief Attempts to send a queue of messages on the associated CAN bus. + * + * @param messages A queue containing the messages to be sent. + * @param delay If greater than 0, will delay the sending of the next message. + * @param forceExtended Whether or not to force use of an extended ID. + * + * @return int32_t The total amount of bytes sent. + */ +int32_t CanDriver::sendMessageQueue(queue messages, + milliseconds delay, bool forceExtended) { + if (_socketFd < 0) { + throw InvalidSocketException("Invalid socket!", _socketFd); + } - if ((tmpReturn = ioctl(_socketFd, SIOCGIFINDEX, &ifaceRequest)) == -1) { - throw CanInitException(formatString("FAILED to perform IO control operation on socket %s! Error: %d => %s", _canInterface.c_str(), errno, - strerror(errno))); - } + int32_t totalBytesWritten = 0; - fdOptions = fcntl(_socketFd, F_GETFL); - fdOptions |= O_NONBLOCK; - tmpReturn = fcntl(_socketFd, F_SETFL, fdOptions); - - address.can_family = AF_CAN; - address.can_ifindex = ifaceRequest.ifr_ifindex; - - setCanFilterMask(_canFilterMask); - - if ((tmpReturn = bind(_socketFd, (struct sockaddr*)&address, sizeof(address))) == -1) { - throw CanInitException(formatString("FAILED to bind to socket CAN! Error: %d => %s", errno, strerror(errno))); - } - } - - /** - * @brief Closes the underlying CAN socket. - */ - void CanDriver::uninitialiseSocketCan() { - unique_lock locky(_lock); + while (!messages.empty()) { + totalBytesWritten += sendMessage(messages.front(), forceExtended); + messages.pop(); + } + + return totalBytesWritten; +} + +/** + * @brief Attempts to read all messages stored in the buffer for the associated + * CAN bus. + * + * @return queue A queue containing the messages read from the bus + * buffer. + */ +queue CanDriver::readQueuedMessages() { + if (_socketFd < 0) + throw InvalidSocketException("Invalid socket!", _socketFd); + unique_lock locky(_lock); + queue messages; + for (int32_t i = _queueSize; 0 < i; --i) + messages.emplace(readMessageLock(false)); + return messages; +} + +/** + * @brief Attempts to set the filter mask for the associated CAN bus. + * + * @param mask The bit mask to apply. + */ +void CanDriver::setCanFilterMask(const int32_t mask) { + if (_socketFd < 0) { + throw InvalidSocketException("Invalid socket!", _socketFd); + } + + unique_lock locky(_lock); + can_filter canFilter; + + canFilter.can_id = _defaultSenderId; + canFilter.can_mask = mask; + + if (setsockopt(_socketFd, SOL_CAN_RAW, CAN_RAW_FILTER, &canFilter, + sizeof(canFilter)) == -1) { + throw CanInitException(formatString( + "FAILED to set CAN filter mask %x on socket %d! Error: %d => %s", mask, + _socketFd, errno, strerror(errno))); + } + + _canFilterMask = mask; +} + +////////////////////////////////////// +// PROTECTED IMPLEMENTATION // +////////////////////////////////////// + +/** + * @brief Initialises the underlying CAN socket. + */ +void CanDriver::initialiseSocketCan() { + // unique_lock locky(_lock); + + struct sockaddr_can address; + struct ifreq ifaceRequest; + int64_t fdOptions = 0; + int32_t tmpReturn; + + memset(&address, 0, sizeof(sizeof(struct sockaddr_can))); + memset(&ifaceRequest, 0, sizeof(sizeof(struct ifreq))); + + _socketFd = socket(PF_CAN, SOCK_RAW, _canProtocol); + + if (_socketFd == -1) { + throw CanInitException( + formatString("FAILED to initialise socketcan! Error: %d => %s", errno, + strerror(errno))); + } + + strcpy(ifaceRequest.ifr_name, _canInterface.c_str()); + + if ((tmpReturn = ioctl(_socketFd, SIOCGIFINDEX, &ifaceRequest)) == -1) { + throw CanInitException(formatString( + "FAILED to perform IO control operation on socket %s! Error: %d => %s", + _canInterface.c_str(), errno, strerror(errno))); + } + + fdOptions = fcntl(_socketFd, F_GETFL); + fdOptions |= O_NONBLOCK; + tmpReturn = fcntl(_socketFd, F_SETFL, fdOptions); + + address.can_family = AF_CAN; + address.can_ifindex = ifaceRequest.ifr_ifindex; + + setCanFilterMask(_canFilterMask); + + if ((tmpReturn = bind(_socketFd, (struct sockaddr *)&address, + sizeof(address))) == -1) { + throw CanInitException( + formatString("FAILED to bind to socket CAN! Error: %d => %s", errno, + strerror(errno))); + } +} + +/** + * @brief Closes the underlying CAN socket. + */ +void CanDriver::uninitialiseSocketCan() { + unique_lock locky(_lock); - if (_socketFd <= 0) { throw CanCloseException("Cannot close invalid socket!"); } + if (_socketFd <= 0) { + throw CanCloseException("Cannot close invalid socket!"); + } - if (close(_socketFd) == -1) { throw CanCloseException(formatString("FAILED to close CAN socket! Error: %d => %s", errno, strerror(errno))); } + if (close(_socketFd) == -1) { + throw CanCloseException(formatString( + "FAILED to close CAN socket! Error: %d => %s", errno, strerror(errno))); + } - _socketFd = -1; - } + _socketFd = -1; +} } // namespace sockcanpp diff --git a/core/driver/sockcanpp/CanDriver.hpp b/core/driver/sockcanpp/CanDriver.hpp index f7f31d0..35295b1 100644 --- a/core/driver/sockcanpp/CanDriver.hpp +++ b/core/driver/sockcanpp/CanDriver.hpp @@ -4,7 +4,7 @@ * @brief Contains the declarations for the SocketCAN wrapper in C++. * @version 0.1 * @date 2020-07-01 - * + * * @copyright Copyright (c) 2020 * * Copyright 2020 Simon Cahill @@ -41,101 +41,131 @@ /** * @brief Main library namespace. - * + * * This namespace contains the library's main code. */ namespace sockcanpp { - using std::chrono::milliseconds; - using std::mutex; - using std::string; - using std::queue; - - /** - * @brief CanDriver class; handles communication via CAN. - * - * This class provides the means of easily communicating with other devices via CAN in C++. - * - * @remarks - * This class may be inherited by other applications and modified to suit your needs. - */ - class CanDriver { - public: // +++ Static +++ - static const int32_t CAN_MAX_DATA_LENGTH; ///!< The maximum amount of bytes allowed in a single CAN frame - static const int32_t CAN_SOCK_RAW; ///!< The raw CAN protocol - static const int32_t CAN_SOCK_SEVEN; ///!< A separate CAN protocol, used by certain embedded device OEMs. - - public: // +++ Constructor / Destructor +++ - CanDriver(const string canInterface, const int32_t canProtocol, const CanId defaultSenderId = 0); ///!< Constructor - CanDriver(const string canInterface, const int32_t canProtocol, const int32_t filterMask, const CanId defaultSenderId = 0); - CanDriver() {} - virtual ~CanDriver() { uninitialiseSocketCan(); } ///!< Destructor - - public: // +++ Getter / Setter +++ - CanDriver& setDefaultSenderId(const CanId id) { this->_defaultSenderId = id; return *this; } ///!< Sets the default sender ID - - const CanId getDefaultSenderId() const { return this->_defaultSenderId; } ///!< Gets the default sender ID - - const int32_t getFilterMask() const { return this->_canFilterMask; } ///!< Gets the filter mask used by this instance - const int32_t getMessageQueueSize() const { return this->_queueSize; } ///!< Gets the amount of CAN messages found after last calling waitForMessages() - const int32_t getSocketFd() const { return this->_socketFd; } ///!< The socket file descriptor used by this instance. - - public: // +++ I/O +++ - virtual bool waitForMessages(milliseconds timeout = milliseconds(3000)); ///!< Waits for CAN messages to appear - - virtual CanMessage readMessage(); ///!< Attempts to read a single message from the bus - - virtual int32_t sendMessage(const CanMessage message, bool forceExtended = false); ///!< Attempts to send a single CAN message - virtual int32_t sendMessageQueue(queue messages, - milliseconds delay = milliseconds(20), bool forceExtended = false); ///!< Attempts to send a queue of messages - - virtual queue readQueuedMessages(); ///!< Attempts to read all queued messages from the bus - - virtual void setCanFilterMask(const int32_t mask); ///!< Attempts to set a new CAN filter mask to the BIOS - - protected: // +++ Socket Management +++ - virtual void initialiseSocketCan(); ///!< Initialises socketcan - virtual void uninitialiseSocketCan(); ///!< Uninitialises socketcan - - private: - virtual CanMessage readMessageLock(bool const lock = true); ///!< readMessage deadlock guard - CanId _defaultSenderId; ///!< The ID to send messages with if no other ID was set. - - int32_t _canFilterMask; ///!< The bit mask used to filter CAN messages - int32_t _canProtocol; ///!< The protocol used when communicating via CAN - int32_t _socketFd; ///!< The CAN socket file descriptor - int32_t _queueSize; ////!< The size of the message queue read by waitForMessages() - - mutex _lock; ///!< Mutex for thread-safety. - - string _canInterface; ///!< The CAN interface used for communication (e.g. can0, can1, ...) - - }; - - - - /** - * @brief Formats a std string object. - * - * @remarks Yoinked from https://github.com/Beatsleigher/liblogpp :) - * - * @tparam Args The formatting argument types. - * @param format The format string. - * @param args The format arguments (strings must be converted to C-style strings!) - * - * @return string The formatted string. - */ - template - string formatString(const string& format, Args... args) { - using std::unique_ptr; - auto stringSize = snprintf(NULL, 0, format.c_str(), args...) + 1; // +1 for \0 - unique_ptr buffer(new char[stringSize]); - - snprintf(buffer.get(), stringSize, format.c_str(), args...); - - return string(buffer.get(), buffer.get() + stringSize - 1); // std::string handles termination for us. - } +using std::mutex; +using std::queue; +using std::string; +using std::chrono::milliseconds; + +/** + * @brief CanDriver class; handles communication via CAN. + * + * This class provides the means of easily communicating with other devices via + * CAN in C++. + * + * @remarks + * This class may be inherited by other applications and modified to suit your + * needs. + */ +class CanDriver { +public: // +++ Static +++ + static const int32_t CAN_MAX_DATA_LENGTH; ///!< The maximum amount of bytes + /// allowed in a single CAN frame + static const int32_t CAN_SOCK_RAW; ///!< The raw CAN protocol + static const int32_t CAN_SOCK_SEVEN; ///!< A separate CAN protocol, used by + /// certain embedded device OEMs. + +public: // +++ Constructor / Destructor +++ + CanDriver(const string canInterface, const int32_t canProtocol, + const CanId defaultSenderId = 0); ///!< Constructor + CanDriver(const string canInterface, const int32_t canProtocol, + const int32_t filterMask, const CanId defaultSenderId = 0); + CanDriver() {} + virtual ~CanDriver() { uninitialiseSocketCan(); } ///!< Destructor + +public: // +++ Getter / Setter +++ + CanDriver &setDefaultSenderId(const CanId id) { + this->_defaultSenderId = id; + return *this; + } ///!< Sets the default sender ID + + const CanId getDefaultSenderId() const { + return this->_defaultSenderId; + } ///!< Gets the default sender ID + + const int32_t getFilterMask() const { + return this->_canFilterMask; + } ///!< Gets the filter mask used by this instance + const int32_t getMessageQueueSize() const { + return this->_queueSize; + } ///!< Gets the amount of CAN messages found after last calling + /// waitForMessages() + const int32_t getSocketFd() const { + return this->_socketFd; + } ///!< The socket file descriptor used by this instance. + +public: // +++ I/O +++ + virtual bool + waitForMessages(milliseconds timeout = milliseconds( + 3000)); ///!< Waits for CAN messages to appear + + virtual CanMessage + readMessage(); ///!< Attempts to read a single message from the bus + + virtual int32_t sendMessage( + const CanMessage message, + bool forceExtended = false); ///!< Attempts to send a single CAN message + virtual int32_t sendMessageQueue( + queue messages, milliseconds delay = milliseconds(20), + bool forceExtended = false); ///!< Attempts to send a queue of messages + + virtual queue + readQueuedMessages(); ///!< Attempts to read all queued messages from the bus + + virtual void + setCanFilterMask(const int32_t mask); ///!< Attempts to set a new CAN filter + /// mask to the BIOS + +protected: // +++ Socket Management +++ + virtual void initialiseSocketCan(); ///!< Initialises socketcan + virtual void uninitialiseSocketCan(); ///!< Uninitialises socketcan + +private: + virtual CanMessage + readMessageLock(bool const lock = true); ///!< readMessage deadlock guard + CanId _defaultSenderId; ///!< The ID to send messages with if no other ID was + /// set. + + int32_t _canFilterMask; ///!< The bit mask used to filter CAN messages + int32_t _canProtocol; ///!< The protocol used when communicating via CAN + int32_t _socketFd; ///!< The CAN socket file descriptor + int32_t + _queueSize; ////!< The size of the message queue read by waitForMessages() + + mutex _lock; ///!< Mutex for thread-safety. + + string _canInterface; ///!< The CAN interface used for communication (e.g. + /// can0, can1, ...) +}; +/** + * @brief Formats a std string object. + * + * @remarks Yoinked from https://github.com/Beatsleigher/liblogpp :) + * + * @tparam Args The formatting argument types. + * @param format The format string. + * @param args The format arguments (strings must be converted to C-style + * strings!) + * + * @return string The formatted string. + */ +template +string formatString(const string &format, Args... args) { + using std::unique_ptr; + auto stringSize = snprintf(NULL, 0, format.c_str(), args...) + 1; // +1 for \0 + unique_ptr buffer(new char[stringSize]); + + snprintf(buffer.get(), stringSize, format.c_str(), args...); + + return string(buffer.get(), buffer.get() + stringSize - + 1); // std::string handles termination for us. } +} // namespace sockcanpp + #endif // LIBSOCKCANPP_INCLUDE_CANDRIVER_HPP diff --git a/core/driver/sockcanpp/CanId.hpp b/core/driver/sockcanpp/CanId.hpp index dcff2d7..f21dff1 100644 --- a/core/driver/sockcanpp/CanId.hpp +++ b/core/driver/sockcanpp/CanId.hpp @@ -1,10 +1,11 @@ /** * @file CanId.hpp * @author Simon Cahill (simonc@online.de) - * @brief Contains the implementation of a value-type representing a CAN identifier. + * @brief Contains the implementation of a value-type representing a CAN + * identifier. * @version 0.1 * @date 2020-07-01 - * + * * @copyright Copyright (c) 2020 Simon Cahill * * Copyright 2020 Simon Cahill @@ -35,193 +36,233 @@ namespace sockcanpp { - using std::bitset; - using std::error_code; - using std::exception; - using std::generic_category; - using std::system_error; - - /** - * @brief Represents a CAN ID in a simple and easy-to-use manner. - */ - struct CanId { - public: // +++ Constructors +++ - CanId(const CanId& orig): _identifier(orig._identifier), _isErrorFrame(orig._isErrorFrame), - _isRemoteTransmissionRequest(orig._isRemoteTransmissionRequest), _isStandardFrameId(orig._isStandardFrameId), - _isExtendedFrameId(orig._isExtendedFrameId) { /* copy */ } - - CanId(const uint32_t identifier): _identifier(identifier) { - // TODO: Switch to using bitmasks! - - if (isValidIdentifier(identifier)) { - if (((int32_t)log2(identifier) + 1) < 11) { - _isStandardFrameId = true; - } else { _isExtendedFrameId = true; } - } else if (isErrorFrame(identifier)) { - _isErrorFrame = true; - } else if (isRemoteTransmissionRequest(identifier)) { - _isRemoteTransmissionRequest = true; - } - } - - CanId(): _identifier(0), _isStandardFrameId(true) { } - - public: // +++ Operators +++ - - operator int16_t() const { return isStandardFrameId() ? (int16_t)_identifier : throw system_error(error_code(0xbad1d, generic_category()), "INVALID CAST: ID is extended or invalid!"); } - operator uint16_t() const { return isStandardFrameId() ? (uint16_t)_identifier : throw system_error(error_code(0xbad1d, generic_category()), "INVALID CAST: ID is extended or invalid!"); } - operator int32_t() const { return _identifier; } - operator uint32_t() const { return _identifier; } - - - CanId operator &(CanId& x) const { return _identifier & x._identifier; } - CanId operator &(const CanId x) const { return _identifier & x._identifier; } - CanId operator &(const int16_t x) const { return _identifier & x; } - CanId operator &(const uint16_t x) const { return _identifier & x; } - CanId operator &(const int32_t x) const { return _identifier & x; } - CanId operator &(const uint32_t x) const { return _identifier & x; } - CanId operator &(const int64_t x) const { return _identifier & x; } - CanId operator &(const uint64_t x) const { return _identifier & x; } - - CanId operator |(CanId& x) const { return _identifier | x._identifier; } - CanId operator |(const CanId x) const { return _identifier | x._identifier; } - CanId operator |(const int16_t x) const { return _identifier | x; } - CanId operator |(const uint16_t x) const { return _identifier | x; } - CanId operator |(const int32_t x) const { return _identifier | x; } - CanId operator |(const uint32_t x) const { return _identifier | x; } - CanId operator |(const int64_t x) const { return _identifier | x; } - CanId operator |(const uint64_t x) const { return _identifier | x; } - - bool operator ==(CanId& x) const { return _identifier == x._identifier; } - bool operator ==(const CanId& x) const { return _identifier == x._identifier; } - bool operator ==(const int16_t x) const { return int16_t (_identifier) == x; } - bool operator ==(const uint16_t x) const { return uint16_t (_identifier) == x; } - bool operator ==(const int32_t x) const { return int32_t (_identifier) == x; } - bool operator ==(const uint32_t x) const { return uint32_t (_identifier) == x; } - bool operator ==(const int64_t x) const { return (x > UINT32_MAX || x < INT32_MIN) ? false : x == int64_t(_identifier); } - bool operator ==(const uint64_t x) const { return x > UINT32_MAX ? false : x == uint64_t(_identifier); } - bool operator !=(CanId& x) const { return _identifier != x._identifier; } - bool operator !=(const CanId& x) const { return _identifier != x._identifier; } - bool operator !=(const int16_t x) const { return int16_t(_identifier) != x; } - bool operator !=(const uint16_t x) const { return uint16_t(_identifier) != x; } - bool operator !=(const int32_t x) const { return int32_t(_identifier) != x; } - bool operator !=(const uint32_t x) const { return uint32_t(_identifier) != x; } - bool operator !=(const int64_t x) const { return (x > UINT32_MAX || x < INT32_MIN) ? false : x != _identifier; } - bool operator !=(const uint64_t x) const { return x > UINT32_MAX ? false : x != _identifier; } - - bool operator <(CanId& x) const { return x._identifier < _identifier; } - bool operator <(int32_t x) const { return x < int32_t(_identifier); } - bool operator <(uint32_t x) const { return x < uint32_t(_identifier); } - bool operator <(int16_t x) const { return x < int16_t(_identifier); } - bool operator <(uint16_t x) const { return x < uint16_t(_identifier); } - bool operator <=(CanId& x) const { return x._identifier <= _identifier; } - bool operator >(CanId& x) const { return x._identifier > _identifier; } - bool operator >(int32_t x) const { return x > int32_t(_identifier); } - bool operator >(uint32_t x) const { return x > uint32_t(_identifier); } - bool operator >(int16_t x) const { return x > int16_t(_identifier); } - bool operator >(uint16_t x) const { return x > uint16_t(_identifier); } - bool operator >=(CanId& x) const { return x._identifier >= _identifier; } - bool operator <(const CanId& x) const { return x._identifier < _identifier; } - bool operator <=(const CanId& x) const { return x._identifier <= _identifier; } - bool operator >(const CanId& x) const { return x._identifier > _identifier; } - bool operator >=(const CanId& x) const { return x._identifier >= _identifier; } - - CanId operator =(const int32_t val) { - uint32_t tmpVal = val; - auto tmp = (isValidIdentifier(tmpVal) ? CanId(val) : throw system_error(error_code(0x5421, generic_category()), "INVALID CAST: ID is extended or invalid!")); - return tmp; - } - - CanId operator =(const uint32_t val) { - uint32_t tmp = val; - return (isValidIdentifier(tmp) ? CanId(val) : throw system_error(error_code(0x5421, generic_category()), "INVALID CAST: ID is extended or invalid!")); - } - - CanId operator =(const int64_t val) { return operator =((int32_t)val); } - - CanId operator +(CanId& x) const { return _identifier + x._identifier; } - CanId operator +(const CanId& x) const { return _identifier + x._identifier; } - CanId operator +(const int16_t x) const { return _identifier + x; } - CanId operator +(const uint16_t x) const { return _identifier + x; } - CanId operator +(const int32_t x) const { return _identifier + x; } - CanId operator +(const uint32_t x) const { return _identifier + x; } - CanId operator +(const int64_t x) const { return _identifier + x; } - CanId operator +(const uint64_t x) const { return _identifier + x; } - - CanId operator -(CanId& x) const { return _identifier - x._identifier; } - CanId operator -(const CanId& x) const { return _identifier - x._identifier; } - CanId operator -(const int16_t x) const { return _identifier - x; } - CanId operator -(const uint16_t x) const { return _identifier - x; } - CanId operator -(const int32_t x) const { return _identifier - x; } - CanId operator -(const uint32_t x) const { return _identifier - x; } - CanId operator -(const int64_t x) const { return _identifier - x; } - CanId operator -(const uint64_t x) const { return _identifier - x; } - - public: // +++ Validity Checks +++ - /** - * @brief Indicates whether or not a given integer is a valid CAN identifier. - * - * @param value The integer to check. - * - * @return true If value is a valid CAN identifier. - * @return false Otherwise. - */ - static bool isValidIdentifier(uint32_t value) { - int32_t tmpValue = ((int32_t)log2(value) + 2); // Get bit count - - // Check for extended frame flag - if (tmpValue >= 29) { - value = (value & CAN_EFF_FLAG) ? (value & CAN_EFF_MASK) : (value & CAN_SFF_MASK); - tmpValue = ((int32_t)log2(value) + 1); // Get bit count again - } - - return (value == 0) /* Default value, also valid ID */ || ((tmpValue <= 29 && tmpValue > 0)); - } - - /** - * @brief Indicates whether or not a given integer contains the error frame flag or not. - * - * @param value The integer to check. - * - * @return true If value has the error frame flag (bit) set to 1. - * @return false Otherwise. - */ - static bool isErrorFrame(uint32_t value) { - try { return bitset(value).test(29); } - catch (...) { return false; /* Brute-force, but works. */ } - } - - /** - * @brief Indicates whether the received frame is a remote transmission request. - * - * @param value The integer to check. - * - * @return true If the frame is a remote transmission request. - * @return false Otherwise. - */ - static bool isRemoteTransmissionRequest(uint32_t value) { - try { return bitset(value).test(30); } - catch (...) { return false; /* Brute-force, but works. */ } - } - - public: // +++ Getters +++ - bool hasErrorFrameFlag() const { return _isErrorFrame; } - bool hasRtrFrameFlag() const { return _isRemoteTransmissionRequest; } - bool isStandardFrameId() const { return _isStandardFrameId; } - bool isExtendedFrameId() const { return _isExtendedFrameId; } - - public: // +++ Equality Checks +++ - bool equals(CanId otherId) const { return *this == otherId; } - - private: // +++ Variables +++ - bool _isErrorFrame = false; - bool _isRemoteTransmissionRequest = false; - bool _isStandardFrameId = false; - bool _isExtendedFrameId = false; - - uint32_t _identifier = 0; - }; - -} +using std::bitset; +using std::error_code; +using std::exception; +using std::generic_category; +using std::system_error; + +/** + * @brief Represents a CAN ID in a simple and easy-to-use manner. + */ +struct CanId { +public: // +++ Constructors +++ + CanId(const CanId &orig) + : _identifier(orig._identifier), _isErrorFrame(orig._isErrorFrame), + _isRemoteTransmissionRequest(orig._isRemoteTransmissionRequest), + _isStandardFrameId(orig._isStandardFrameId), + _isExtendedFrameId(orig._isExtendedFrameId) { /* copy */ + } + + CanId(const uint32_t identifier) : _identifier(identifier) { + // TODO: Switch to using bitmasks! + + if (isValidIdentifier(identifier)) { + if (((int32_t)log2(identifier) + 1) < 11) { + _isStandardFrameId = true; + } else { + _isExtendedFrameId = true; + } + } else if (isErrorFrame(identifier)) { + _isErrorFrame = true; + } else if (isRemoteTransmissionRequest(identifier)) { + _isRemoteTransmissionRequest = true; + } + } + + CanId() : _identifier(0), _isStandardFrameId(true) {} + +public: // +++ Operators +++ + operator int16_t() const { + return isStandardFrameId() + ? (int16_t)_identifier + : throw system_error(error_code(0xbad1d, generic_category()), + "INVALID CAST: ID is extended or invalid!"); + } + operator uint16_t() const { + return isStandardFrameId() + ? (uint16_t)_identifier + : throw system_error(error_code(0xbad1d, generic_category()), + "INVALID CAST: ID is extended or invalid!"); + } + operator int32_t() const { return _identifier; } + operator uint32_t() const { return _identifier; } + + CanId operator&(CanId &x) const { return _identifier & x._identifier; } + CanId operator&(const CanId x) const { return _identifier & x._identifier; } + CanId operator&(const int16_t x) const { return _identifier & x; } + CanId operator&(const uint16_t x) const { return _identifier & x; } + CanId operator&(const int32_t x) const { return _identifier & x; } + CanId operator&(const uint32_t x) const { return _identifier & x; } + CanId operator&(const int64_t x) const { return _identifier & x; } + CanId operator&(const uint64_t x) const { return _identifier & x; } + + CanId operator|(CanId &x) const { return _identifier | x._identifier; } + CanId operator|(const CanId x) const { return _identifier | x._identifier; } + CanId operator|(const int16_t x) const { return _identifier | x; } + CanId operator|(const uint16_t x) const { return _identifier | x; } + CanId operator|(const int32_t x) const { return _identifier | x; } + CanId operator|(const uint32_t x) const { return _identifier | x; } + CanId operator|(const int64_t x) const { return _identifier | x; } + CanId operator|(const uint64_t x) const { return _identifier | x; } + + bool operator==(CanId &x) const { return _identifier == x._identifier; } + bool operator==(const CanId &x) const { return _identifier == x._identifier; } + bool operator==(const int16_t x) const { return int16_t(_identifier) == x; } + bool operator==(const uint16_t x) const { return uint16_t(_identifier) == x; } + bool operator==(const int32_t x) const { return int32_t(_identifier) == x; } + bool operator==(const uint32_t x) const { return uint32_t(_identifier) == x; } + bool operator==(const int64_t x) const { + return (x > UINT32_MAX || x < INT32_MIN) ? false + : x == int64_t(_identifier); + } + bool operator==(const uint64_t x) const { + return x > UINT32_MAX ? false : x == uint64_t(_identifier); + } + bool operator!=(CanId &x) const { return _identifier != x._identifier; } + bool operator!=(const CanId &x) const { return _identifier != x._identifier; } + bool operator!=(const int16_t x) const { return int16_t(_identifier) != x; } + bool operator!=(const uint16_t x) const { return uint16_t(_identifier) != x; } + bool operator!=(const int32_t x) const { return int32_t(_identifier) != x; } + bool operator!=(const uint32_t x) const { return uint32_t(_identifier) != x; } + bool operator!=(const int64_t x) const { + return (x > UINT32_MAX || x < INT32_MIN) ? false : x != _identifier; + } + bool operator!=(const uint64_t x) const { + return x > UINT32_MAX ? false : x != _identifier; + } + + bool operator<(CanId &x) const { return x._identifier < _identifier; } + bool operator<(int32_t x) const { return x < int32_t(_identifier); } + bool operator<(uint32_t x) const { return x < uint32_t(_identifier); } + bool operator<(int16_t x) const { return x < int16_t(_identifier); } + bool operator<(uint16_t x) const { return x < uint16_t(_identifier); } + bool operator<=(CanId &x) const { return x._identifier <= _identifier; } + bool operator>(CanId &x) const { return x._identifier > _identifier; } + bool operator>(int32_t x) const { return x > int32_t(_identifier); } + bool operator>(uint32_t x) const { return x > uint32_t(_identifier); } + bool operator>(int16_t x) const { return x > int16_t(_identifier); } + bool operator>(uint16_t x) const { return x > uint16_t(_identifier); } + bool operator>=(CanId &x) const { return x._identifier >= _identifier; } + bool operator<(const CanId &x) const { return x._identifier < _identifier; } + bool operator<=(const CanId &x) const { return x._identifier <= _identifier; } + bool operator>(const CanId &x) const { return x._identifier > _identifier; } + bool operator>=(const CanId &x) const { return x._identifier >= _identifier; } + + CanId operator=(const int32_t val) { + uint32_t tmpVal = val; + auto tmp = + (isValidIdentifier(tmpVal) + ? CanId(val) + : throw system_error(error_code(0x5421, generic_category()), + "INVALID CAST: ID is extended or invalid!")); + return tmp; + } + + CanId operator=(const uint32_t val) { + uint32_t tmp = val; + return ( + isValidIdentifier(tmp) + ? CanId(val) + : throw system_error(error_code(0x5421, generic_category()), + "INVALID CAST: ID is extended or invalid!")); + } + + CanId operator=(const int64_t val) { return operator=((int32_t)val); } + + CanId operator+(CanId &x) const { return _identifier + x._identifier; } + CanId operator+(const CanId &x) const { return _identifier + x._identifier; } + CanId operator+(const int16_t x) const { return _identifier + x; } + CanId operator+(const uint16_t x) const { return _identifier + x; } + CanId operator+(const int32_t x) const { return _identifier + x; } + CanId operator+(const uint32_t x) const { return _identifier + x; } + CanId operator+(const int64_t x) const { return _identifier + x; } + CanId operator+(const uint64_t x) const { return _identifier + x; } + + CanId operator-(CanId &x) const { return _identifier - x._identifier; } + CanId operator-(const CanId &x) const { return _identifier - x._identifier; } + CanId operator-(const int16_t x) const { return _identifier - x; } + CanId operator-(const uint16_t x) const { return _identifier - x; } + CanId operator-(const int32_t x) const { return _identifier - x; } + CanId operator-(const uint32_t x) const { return _identifier - x; } + CanId operator-(const int64_t x) const { return _identifier - x; } + CanId operator-(const uint64_t x) const { return _identifier - x; } + +public: // +++ Validity Checks +++ + /** + * @brief Indicates whether or not a given integer is a valid CAN identifier. + * + * @param value The integer to check. + * + * @return true If value is a valid CAN identifier. + * @return false Otherwise. + */ + static bool isValidIdentifier(uint32_t value) { + int32_t tmpValue = ((int32_t)log2(value) + 2); // Get bit count + + // Check for extended frame flag + if (tmpValue >= 29) { + value = (value & CAN_EFF_FLAG) ? (value & CAN_EFF_MASK) + : (value & CAN_SFF_MASK); + tmpValue = ((int32_t)log2(value) + 1); // Get bit count again + } + + return (value == 0) /* Default value, also valid ID */ || + ((tmpValue <= 29 && tmpValue > 0)); + } + + /** + * @brief Indicates whether or not a given integer contains the error frame + * flag or not. + * + * @param value The integer to check. + * + * @return true If value has the error frame flag (bit) set to 1. + * @return false Otherwise. + */ + static bool isErrorFrame(uint32_t value) { + try { + return bitset(value).test(29); + } catch (...) { + return false; /* Brute-force, but works. */ + } + } + + /** + * @brief Indicates whether the received frame is a remote transmission + * request. + * + * @param value The integer to check. + * + * @return true If the frame is a remote transmission request. + * @return false Otherwise. + */ + static bool isRemoteTransmissionRequest(uint32_t value) { + try { + return bitset(value).test(30); + } catch (...) { + return false; /* Brute-force, but works. */ + } + } + +public: // +++ Getters +++ + bool hasErrorFrameFlag() const { return _isErrorFrame; } + bool hasRtrFrameFlag() const { return _isRemoteTransmissionRequest; } + bool isStandardFrameId() const { return _isStandardFrameId; } + bool isExtendedFrameId() const { return _isExtendedFrameId; } + +public: // +++ Equality Checks +++ + bool equals(CanId otherId) const { return *this == otherId; } + +private: // +++ Variables +++ + bool _isErrorFrame = false; + bool _isRemoteTransmissionRequest = false; + bool _isStandardFrameId = false; + bool _isExtendedFrameId = false; + + uint32_t _identifier = 0; +}; + +} // namespace sockcanpp #endif // LIBSOCKPP_INCLUDE_CANID_HPP diff --git a/core/driver/sockcanpp/CanMessage.hpp b/core/driver/sockcanpp/CanMessage.hpp index 675c072..0a64423 100644 --- a/core/driver/sockcanpp/CanMessage.hpp +++ b/core/driver/sockcanpp/CanMessage.hpp @@ -4,7 +4,7 @@ * @brief Contains the implementation of a CAN message representation in C++. * @version 0.1 * @date 2020-07-01 - * + * * @copyright Copyright (c) 2020 Simon Cahill * * Copyright 2020 Simon Cahill @@ -42,48 +42,51 @@ namespace sockcanpp { - using std::error_code; - using std::generic_category; - using std::memcpy; - using std::string; - using std::system_error; +using std::error_code; +using std::generic_category; +using std::memcpy; +using std::string; +using std::system_error; - /** - * @brief Represents a CAN message that was received. - */ - class CanMessage { - public: // +++ Constructor / Destructor +++ - CanMessage(const struct can_frame frame): - _canIdentifier(frame.can_id), _frameData((const char*)frame.data, frame.can_dlc), _rawFrame(frame) { } +/** + * @brief Represents a CAN message that was received. + */ +class CanMessage { +public: // +++ Constructor / Destructor +++ + CanMessage(const struct can_frame frame) + : _canIdentifier(frame.can_id), + _frameData((const char *)frame.data, frame.can_dlc), _rawFrame(frame) {} - CanMessage(const CanId canId, const string frameData): _canIdentifier(canId), _frameData(frameData) { - if (frameData.size() > 8) { - throw system_error(error_code(0xbadd1c, generic_category()), "Payload too big!"); - } + CanMessage(const CanId canId, const string frameData) + : _canIdentifier(canId), _frameData(frameData) { + if (frameData.size() > 8) { + throw system_error(error_code(0xbadd1c, generic_category()), + "Payload too big!"); + } - struct can_frame rawFrame; - rawFrame.can_id = canId; - memcpy(rawFrame.data, frameData.data(), frameData.size()); - rawFrame.can_dlc = frameData.size(); + struct can_frame rawFrame; + rawFrame.can_id = canId; + memcpy(rawFrame.data, frameData.data(), frameData.size()); + rawFrame.can_dlc = frameData.size(); - _rawFrame = rawFrame; - } + _rawFrame = rawFrame; + } - virtual ~CanMessage() {} + virtual ~CanMessage() {} - public: // +++ Getters +++ - const CanId getCanId() const { return this->_canIdentifier; } - const string getFrameData() const { return this->_frameData; } - const can_frame getRawFrame() const { return this->_rawFrame; } +public: // +++ Getters +++ + const CanId getCanId() const { return this->_canIdentifier; } + const string getFrameData() const { return this->_frameData; } + const can_frame getRawFrame() const { return this->_rawFrame; } - private: - CanId _canIdentifier; +private: + CanId _canIdentifier; - string _frameData; + string _frameData; - struct can_frame _rawFrame; - }; + struct can_frame _rawFrame; +}; -} +} // namespace sockcanpp #endif // LIBSOCKCANPP_INCLUDE_CANMESSAGE_HPP diff --git a/core/driver/sockcanpp/exceptions/CanCloseException.hpp b/core/driver/sockcanpp/exceptions/CanCloseException.hpp index 854d4cb..dc38ae4 100644 --- a/core/driver/sockcanpp/exceptions/CanCloseException.hpp +++ b/core/driver/sockcanpp/exceptions/CanCloseException.hpp @@ -1,10 +1,11 @@ /** * @file CanCloseException.hpp * @author Simon Cahill (simonc@online.de) - * @brief Contains the implementation of an exception that may be thrown when an error occurs while closing a CAN socket. + * @brief Contains the implementation of an exception that may be thrown when an + * error occurs while closing a CAN socket. * @version 0.1 * @date 2020-07-02 - * + * * @copyright Copyright (c) 2020 Simon Cahill * * Copyright 2020 Simon Cahill @@ -28,26 +29,29 @@ #include #include -namespace sockcanpp { namespace exceptions { +namespace sockcanpp { +namespace exceptions { - using std::exception; - using std::string; +using std::exception; +using std::string; - /** - * @brief An exception that may be thrown when an error occurs while closing a CAN socket. - */ - class CanCloseException: public exception { - public: // +++ Constructor / Destructor +++ - CanCloseException(string message): _message(message) {} - ~CanCloseException() {} +/** + * @brief An exception that may be thrown when an error occurs while closing a + * CAN socket. + */ +class CanCloseException : public exception { +public: // +++ Constructor / Destructor +++ + CanCloseException(string message) : _message(message) {} + ~CanCloseException() {} - public: // +++ Overrides +++ - const char* what() { return _message.c_str(); } +public: // +++ Overrides +++ + const char *what() { return _message.c_str(); } - private: - string _message; - }; +private: + string _message; +}; -} /* exceptions */ } /* sockcanpp */ +} // namespace exceptions +} // namespace sockcanpp #endif // LIBSOCKCANPP_INCLUDE_EXCEPTIONS_CANCLOSEEXCEPTION_HPP \ No newline at end of file diff --git a/core/driver/sockcanpp/exceptions/CanException.hpp b/core/driver/sockcanpp/exceptions/CanException.hpp index 3c71f5b..c21f772 100644 --- a/core/driver/sockcanpp/exceptions/CanException.hpp +++ b/core/driver/sockcanpp/exceptions/CanException.hpp @@ -1,10 +1,11 @@ /** * @file CanException.hpp * @author Simon Cahill (simonc@online.de) - * @brief Contains the implementation of a general-purpose exception which may be thrown when an error occurs when performing IO on a CAN socket. + * @brief Contains the implementation of a general-purpose exception which may + * be thrown when an error occurs when performing IO on a CAN socket. * @version 0.1 * @date 2020-07-02 - * + * * @copyright Copyright (c) 2020 Simon Cahill * * Copyright 2020 Simon Cahill @@ -28,31 +29,35 @@ #include #include -namespace sockcanpp { namespace exceptions { +namespace sockcanpp { +namespace exceptions { - using std::exception; - using std::string; +using std::exception; +using std::string; - /** - * @brief An exception that may be thrown when an error occurs while closing a CAN socket. - */ - class CanException: public exception { - public: // +++ Constructor / Destructor +++ - CanException(string message, int32_t socket): _message(message), _socket(socket) {} - ~CanException() {} +/** + * @brief An exception that may be thrown when an error occurs while closing a + * CAN socket. + */ +class CanException : public exception { +public: // +++ Constructor / Destructor +++ + CanException(string message, int32_t socket) + : _message(message), _socket(socket) {} + ~CanException() {} - public: // +++ Overrides +++ - const char* what() { return _message.c_str(); } +public: // +++ Overrides +++ + const char *what() { return _message.c_str(); } - public: // +++ Getter +++ - const int32_t getSocket() const { return _socket; } +public: // +++ Getter +++ + const int32_t getSocket() const { return _socket; } - private: - int32_t _socket; +private: + int32_t _socket; - string _message; - }; + string _message; +}; -} /* exceptions */ } /* sockcanpp */ +} // namespace exceptions +} // namespace sockcanpp #endif // LIBSOCKCANPP_INCLUDE_EXCEPTIONS_CANEXCEPTION_HPP \ No newline at end of file diff --git a/core/driver/sockcanpp/exceptions/CanInitException.hpp b/core/driver/sockcanpp/exceptions/CanInitException.hpp index 8f3707a..1bf6135 100644 --- a/core/driver/sockcanpp/exceptions/CanInitException.hpp +++ b/core/driver/sockcanpp/exceptions/CanInitException.hpp @@ -1,10 +1,11 @@ /** * @file CanInitException.hpp * @author Simon Cahill (simonc@online.de) - * @brief Contains the implementation of an exception that is thrown when a CAN socket couldn't be inintialised. + * @brief Contains the implementation of an exception that is thrown when a CAN + * socket couldn't be inintialised. * @version 0.1 * @date 2020-07-02 - * + * * @copyright Copyright (c) 2020 Simon Cahill * * Copyright 2020 Simon Cahill @@ -28,26 +29,29 @@ #include #include -namespace sockcanpp { namespace exceptions { +namespace sockcanpp { +namespace exceptions { - using std::exception; - using std::string; +using std::exception; +using std::string; - /** - * @brief An exception that may be thrown when an error occurred while initialising a CAN socket. - */ - class CanInitException: public exception { - public: // +++ Constructor / Destructor +++ - CanInitException(string message): _message(message) { } - virtual ~CanInitException() { } +/** + * @brief An exception that may be thrown when an error occurred while + * initialising a CAN socket. + */ +class CanInitException : public exception { +public: // +++ Constructor / Destructor +++ + CanInitException(string message) : _message(message) {} + virtual ~CanInitException() {} - public: // +++ Override +++ - const char* what() { return _message.c_str(); } +public: // +++ Override +++ + const char *what() { return _message.c_str(); } - private: - string _message; - }; +private: + string _message; +}; -} /* exceptions */ } /* sockcanpp */ +} // namespace exceptions +} // namespace sockcanpp #endif // LIBSOCKCANPP_INCLUDE_EXCEPTIONS_CANINITEXCEPTION_HPP \ No newline at end of file diff --git a/core/driver/sockcanpp/exceptions/InvalidSocketException.hpp b/core/driver/sockcanpp/exceptions/InvalidSocketException.hpp index f7ab7dd..c92148c 100644 --- a/core/driver/sockcanpp/exceptions/InvalidSocketException.hpp +++ b/core/driver/sockcanpp/exceptions/InvalidSocketException.hpp @@ -1,10 +1,11 @@ /** * @file InvalidSocketException.hpp * @author Simon Cahill (simonc@online.de) - * @brief Contains the implementation of an exception that may be thrown when an invalid CAN socket is detected. + * @brief Contains the implementation of an exception that may be thrown when an + * invalid CAN socket is detected. * @version 0.1 * @date 2020-07-02 - * + * * @copyright Copyright (c) 2020 Simon Cahill * * Copyright 2020 Simon Cahill @@ -28,31 +29,35 @@ #include #include -namespace sockcanpp { namespace exceptions { +namespace sockcanpp { +namespace exceptions { - using std::exception; - using std::string; +using std::exception; +using std::string; - /** - * @brief An exception that may be thrown when an error occurs while closing a CAN socket. - */ - class InvalidSocketException: public exception { - public: // +++ Constructor / Destructor +++ - InvalidSocketException(string message, int32_t socket): _message(message), _socket(socket) {} - ~InvalidSocketException() {} +/** + * @brief An exception that may be thrown when an error occurs while closing a + * CAN socket. + */ +class InvalidSocketException : public exception { +public: // +++ Constructor / Destructor +++ + InvalidSocketException(string message, int32_t socket) + : _message(message), _socket(socket) {} + ~InvalidSocketException() {} - public: // +++ Overrides +++ - const char* what() { return _message.c_str(); } +public: // +++ Overrides +++ + const char *what() { return _message.c_str(); } - public: // +++ Getter +++ - const int32_t getSocket() const { return _socket; } +public: // +++ Getter +++ + const int32_t getSocket() const { return _socket; } - private: - int32_t _socket; +private: + int32_t _socket; - string _message; - }; + string _message; +}; -} /* exceptions */ } /* sockcanpp */ +} // namespace exceptions +} // namespace sockcanpp #endif // LIBSOCKCANPP_INCLUDE_EXCEPTIONS_INVALIDSOCKETEXCEPTION_HPP \ No newline at end of file