2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   32#include <linux/can/raw.h> 
   35#include <sys/socket.h> 
   52#include "exceptions/CanCloseException.hpp" 
   53#include "exceptions/CanException.hpp" 
   54#include "exceptions/CanInitException.hpp" 
   55#include "exceptions/InvalidSocketException.hpp" 
   68    using std::unique_lock;
 
   69    using std::chrono::milliseconds;
 
   70    using std::this_thread::sleep_for;
 
   80#pragma region Object Construction 
   81    CanDriver::CanDriver(string canInterface, int32_t canProtocol, 
const CanId defaultSenderId):
 
   84    CanDriver::
CanDriver(
const string canInterface, 
const int32_t canProtocol, 
const int32_t filterMask, 
const CanId defaultSenderId):
 
   92
   93
   94
   95
   96
   97
   98
  102        unique_lock<mutex> locky(
_lock);
 
  104        fd_set readFileDescriptors;
 
  106        waitTime.tv_sec = timeout.count() / 1000;
 
  107        waitTime.tv_usec = timeout.count() * 1000;
 
  109        FD_ZERO(&readFileDescriptors);
 
  117
  118
  119
  120
  126
  127
  128
  129
  131    std::unique_ptr<std::unique_lock<std::mutex>> _lockLck{
nullptr};
 
  133        _lockLck = std::unique_ptr<std::unique_lock<std::mutex>>{
new std::unique_lock<std::mutex>{
_lock}};
 
  136        int32_t readBytes{0};
 
  138        memset(&canFrame, 0, 
sizeof(can_frame));
 
  139        readBytes = read(
_socketFd, &canFrame, 
sizeof(can_frame));
 
  146
  147
  148
  149
  150
  151
  152
  158        int32_t bytesWritten = 0;
 
  166        if (forceExtended || ((uint32_t)message
.getCanId() > CAN_SFF_MASK)) { canFrame.can_id |= CAN_EFF_FLAG; }
 
  168        bytesWritten = write(
_socketFd, (
const void*)&canFrame, 
sizeof(canFrame));
 
  176
  177
  178
  179
  180
  181
  182
  183
  187        int32_t totalBytesWritten = 0;
 
  189        while (!messages.empty()) {
 
  190            totalBytesWritten += 
sendMessage(messages.front()
, forceExtended
);
 
  194        return totalBytesWritten;
 
  198
  199
  200
  201
  205        unique_lock<mutex> locky(
_lock);
 
  213
  214
  215
  216
  220        unique_lock<mutex> locky(
_lock);
 
  221        can_filter canFilter;
 
  224        canFilter.can_mask = mask;
 
  226        if (setsockopt(
_socketFd, SOL_CAN_RAW, CAN_RAW_FILTER, &canFilter, 
sizeof(canFilter)) == -1) {
 
  238#pragma region Socket Management 
  241
  242
  246        struct sockaddr_can address;
 
  247        struct ifreq ifaceRequest;
 
  248        int64_t fdOptions = 0;
 
  251        memset(&address, 0, 
sizeof(
sizeof(
struct sockaddr_can)));
 
  252        memset(&ifaceRequest, 0, 
sizeof(
sizeof(
struct ifreq)));
 
  262        if ((tmpReturn = ioctl(
_socketFd, SIOCGIFINDEX, &ifaceRequest)) == -1) {
 
  268        fdOptions |= O_NONBLOCK;
 
  269        tmpReturn = fcntl(
_socketFd, F_SETFL, fdOptions);
 
  271        address.can_family = AF_CAN;
 
  272        address.can_ifindex = ifaceRequest.ifr_ifindex;
 
  276        if ((tmpReturn = bind(
_socketFd, (
struct sockaddr*)&address, 
sizeof(address))) == -1) {
 
  282
  283
  285        unique_lock<mutex> locky(
_lock);
 
CanDriver class; handles communication via CAN.
 
virtual CanMessage readMessage()
!< Waits for CAN messages to appear
 
static const int32_t CAN_SOCK_RAW
!< The maximum amount of bytes allowed in a single CAN frame
 
static const int32_t CAN_SOCK_SEVEN
!< The raw CAN protocol
 
CanId _defaultSenderId
!< readMessage deadlock guard
 
int32_t _queueSize
!< The CAN socket file descriptor
 
virtual queue< CanMessage > readQueuedMessages()
!< Attempts to send a queue of messages
 
int32_t _canProtocol
!< The bit mask used to filter CAN messages
 
virtual int32_t sendMessageQueue(queue< CanMessage > messages, milliseconds delay=milliseconds(20), bool forceExtended=false)
!< Attempts to send a single CAN message
 
virtual CanMessage readMessageLock(bool const lock=true)
!< Uninitialises socketcan
 
CanDriver(const string canInterface, const int32_t canProtocol, const int32_t filterMask, const CanId defaultSenderId=0)
!< Constructor
 
int32_t _socketFd
!< The protocol used when communicating via CAN
 
int32_t _canFilterMask
!< The ID to send messages with if no other ID was set.
 
virtual bool waitForMessages(milliseconds timeout=milliseconds(3000))
!< The socket file descriptor used by this instance.
 
mutex _lock
!< Mutex for thread-safety.
 
virtual void initialiseSocketCan()
!< Attempts to set a new CAN filter mask to the BIOS
 
virtual int32_t sendMessage(const CanMessage message, bool forceExtended=false)
!< Attempts to read a single message from the bus
 
virtual void setCanFilterMask(const int32_t mask)
!< Attempts to read all queued messages from the bus
 
virtual void uninitialiseSocketCan()
!< Initialises socketcan
 
static const int32_t CAN_MAX_DATA_LENGTH
 
Represents a CAN message that was received.
 
const string getFrameData() const
 
const can_frame getRawFrame() const
 
CanMessage(const struct can_frame frame)
 
const CanId getCanId() const
 
CanCloseException(string message)
 
CanException(string message, int32_t socket)
 
CanInitException(string message)
 
InvalidSocketException(string message, int32_t socket)
 
string formatString(const string &format, Args... args)
Formats a std string object.
 
Represents a CAN ID in a simple and easy-to-use manner.