Libsockcanpp
A complete C++ wrapper around socketcan.
Loading...
Searching...
No Matches
Public Member Functions | Static Public Attributes | Protected Member Functions | Private Member Functions | Private Attributes
sockcanpp::CanDriver Class Reference

CanDriver class; handles communication via CAN. More...

#include <CanDriver.hpp>

Collaboration diagram for sockcanpp::CanDriver:
Collaboration graph
[legend]

Public Member Functions

 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 (const string &canInterface, const int32_t canProtocol, const filtermap_t &filters, const CanId defaultSenderId=0)
 
 CanDriver ()=default
 
virtual ~CanDriver ()
 Destructor.
 
CanDriversetDefaultSenderId (const CanId &id)
 Sets the default sender ID.
 
CanId getDefaultSenderId () const
 Gets the default sender ID.
 
filtermap_t getFilterMask () const
 Gets the filter mask used by this instance.
 
int32_t getMessageQueueSize () const
 Gets the amount of CAN messages found after last calling waitForMessages()
 
int32_t getSocketFd () const
 The socket file descriptor used by this instance.
 
string getCanInterface () const
 The CAN interface used by this instance.
 
virtual bool waitForMessages (microseconds timeout=3000us)
 Waits for CAN messages to appear.
 
virtual bool waitForMessages (milliseconds timeout=3000ms)
 Waits for CAN messages to appear.
 
virtual bool waitForMessages (nanoseconds timeout=3000ns)
 Waits for CAN messages to appear.
 
virtual CanMessage readMessage ()
 Attempts to read a single message from the bus.
 
virtual ssize_t sendMessage (const CanMessage &message, bool forceExtended=false)
 Attempts to send a single CAN message.
 
virtual ssize_t sendMessageQueue (queue< CanMessage > &messages, microseconds delay=20us, bool forceExtended=false)
 Attempts to send a queue of messages.
 
virtual ssize_t sendMessageQueue (queue< CanMessage > &messages, milliseconds delay=20ms, bool forceExtended=false)
 Attempts to send a queue of messages.
 
virtual ssize_t sendMessageQueue (queue< CanMessage > &messages, nanoseconds delay=20ns, bool forceExtended=false)
 Attempts to send a queue of messages.
 
virtual queue< CanMessagereadQueuedMessages ()
 Attempts to read all queued messages from the bus.
 
virtual void allowCanFdFrames (const bool enabled=true) const
 Sets the CAN FD frame option for the interface.
 
virtual void joinCanFilters () const
 Configures the socket to join the CAN filters.
 
virtual void setCanFilterMask (const int32_t mask, const CanId &filterId)
 Attempts to set a new CAN filter mask to the interface.
 
virtual void setCanFilters (const filtermap_t &filters)
 Sets the CAN filters for the interface.
 
virtual void setErrorFilter (const bool enabled=true) const
 Sets the error filter for the interface.
 
virtual void setReceiveOwnMessages (const bool enabled=true) const
 Sets the receive own messages option for the interface.
 

Static Public Attributes

static constexpr int32_t CAN_MAX_DATA_LENGTH = 8
 The maximum amount of bytes allowed in a single CAN frame.
 
static constexpr int32_t CAN_SOCK_RAW = CAN_RAW
 The raw CAN protocol.
 
static constexpr int32_t CAN_SOCK_SEVEN = 7
 A separate CAN protocol, used by certain embedded device OEMs.
 

Protected Member Functions

virtual void initialiseSocketCan ()
 Initialises socketcan.
 
virtual void uninitialiseSocketCan ()
 Uninitialises socketcan.
 

Private Member Functions

virtual CanMessage readMessageLock (bool const lock=true)
 readMessage deadlock guard
 

Private Attributes

CanId _defaultSenderId
 The ID to send messages with if no other ID was set.
 
filtermap_t _canFilterMask
 The bit mask used to filter CAN messages.
 
int32_t _canProtocol
 The protocol used when communicating via CAN.
 
int32_t _socketFd {-1}
 The CAN socket file descriptor.
 
int32_t _queueSize {0}
 
bool _canReadQueueSize {true}
 !< The size of the message queue read by waitForMessages()
 
mutex _lock {}
 !< Is the queue size available
 
mutex _lockSend {}
 
string _canInterface
 The CAN interface used for communication (e.g. can0, can1, ...)
 

Detailed Description

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.

Definition at line 68 of file CanDriver.hpp.

Constructor & Destructor Documentation

◆ CanDriver() [1/4]

sockcanpp::CanDriver::CanDriver ( const string &  canInterface,
const int32_t  canProtocol,
const CanId  defaultSenderId = 0 
)

Constructor.

Definition at line 79 of file CanDriver.cpp.

79 :
80 CanDriver(canInterface, canProtocol, 0 /* match all */, defaultSenderId) { }

References CanDriver().

◆ CanDriver() [2/4]

sockcanpp::CanDriver::CanDriver ( const string &  canInterface,
const int32_t  canProtocol,
const int32_t  filterMask,
const CanId  defaultSenderId = 0 
)

Definition at line 82 of file CanDriver.cpp.

82 :
83 CanDriver(canInterface, canProtocol, filtermap_t{{0, filterMask}}, defaultSenderId) { }
unordered_map< CanId, uint32_t, CanIdHasher > filtermap_t
Definition CanDriver.hpp:58

References CanDriver().

Referenced by CanDriver().

◆ CanDriver() [3/4]

sockcanpp::CanDriver::CanDriver ( const string &  canInterface,
const int32_t  canProtocol,
const filtermap_t filters,
const CanId  defaultSenderId = 0 
)

Definition at line 85 of file CanDriver.cpp.

85 :
86 _defaultSenderId(defaultSenderId), _canFilterMask(filters), _canProtocol(canProtocol), _canInterface(canInterface) {
88 }
string _canInterface
The CAN interface used for communication (e.g. can0, can1, ...)
CanId _defaultSenderId
The ID to send messages with if no other ID was set.
int32_t _canProtocol
The protocol used when communicating via CAN.
filtermap_t _canFilterMask
The bit mask used to filter CAN messages.
virtual void initialiseSocketCan()
Initialises socketcan.

References _canFilterMask, _canInterface, _canProtocol, _defaultSenderId, and initialiseSocketCan().

Referenced by CanDriver().

◆ CanDriver() [4/4]

sockcanpp::CanDriver::CanDriver ( )
default

◆ ~CanDriver()

virtual sockcanpp::CanDriver::~CanDriver ( )
inlinevirtual

Destructor.

Definition at line 79 of file CanDriver.hpp.

References uninitialiseSocketCan().

Member Function Documentation

◆ allowCanFdFrames()

void sockcanpp::CanDriver::allowCanFdFrames ( const bool  enabled = true) const
virtual

Sets the CAN FD frame option for the interface.

This option allows the current driver instance to receive CAN FD frames.

Parameters
enabledWhether or not to enable the CAN FD frame option.

Definition at line 297 of file CanDriver.cpp.

297 {
298 if (_socketFd < 0) { throw InvalidSocketException("Invalid socket!", _socketFd); }
299
300 int32_t canFdFrames = enabled ? 1 : 0;
301
302 if (setsockopt(_socketFd, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &canFdFrames, sizeof(canFdFrames)) == -1) {
303 throw CanInitException(formatString("FAILED to set CAN FD frames on socket %d! Error: %d => %s", _socketFd, errno, strerror(errno)));
304 }
305 }
int32_t _socketFd
The CAN socket file descriptor.
string formatString(const string &format, Args... args)
Formats a std string object.

References _socketFd, sockcanpp::exceptions::CanInitException::CanInitException(), sockcanpp::formatString(), and sockcanpp::exceptions::InvalidSocketException::InvalidSocketException().

◆ getCanInterface()

string sockcanpp::CanDriver::getCanInterface ( ) const
inline

The CAN interface used by this instance.

Definition at line 91 of file CanDriver.hpp.

References _canInterface.

◆ getDefaultSenderId()

CanId sockcanpp::CanDriver::getDefaultSenderId ( ) const
inline

Gets the default sender ID.

Definition at line 84 of file CanDriver.hpp.

References _defaultSenderId.

◆ getFilterMask()

filtermap_t sockcanpp::CanDriver::getFilterMask ( ) const
inline

Gets the filter mask used by this instance.

Definition at line 86 of file CanDriver.hpp.

References _canFilterMask.

◆ getMessageQueueSize()

int32_t sockcanpp::CanDriver::getMessageQueueSize ( ) const
inline

Gets the amount of CAN messages found after last calling waitForMessages()

Definition at line 88 of file CanDriver.hpp.

References _queueSize.

◆ getSocketFd()

int32_t sockcanpp::CanDriver::getSocketFd ( ) const
inline

The socket file descriptor used by this instance.

Definition at line 89 of file CanDriver.hpp.

References _socketFd.

◆ initialiseSocketCan()

void sockcanpp::CanDriver::initialiseSocketCan ( )
protectedvirtual

Initialises socketcan.

Initialises the underlying CAN socket.

Definition at line 420 of file CanDriver.cpp.

420 {
421 struct sockaddr_can address{};
422 struct ifreq ifaceRequest{};
423 int64_t fdOptions{0};
424 int32_t tmpReturn{0};
425
426 _socketFd = socket(PF_CAN, SOCK_RAW, _canProtocol);
427
428 if (_socketFd == -1) {
429 throw CanInitException(formatString("FAILED to initialise socketcan! Error: %d => %s", errno, strerror(errno)));
430 }
431
432 std::copy(_canInterface.begin(), _canInterface.end(), ifaceRequest.ifr_name);
433
434 if ((tmpReturn = ioctl(_socketFd, SIOCGIFINDEX, &ifaceRequest)) == -1) {
435 throw CanInitException(formatString("FAILED to perform IO control operation on socket %s! Error: %d => %s", _canInterface.c_str(), errno,
436 strerror(errno)));
437 }
438
439 fdOptions = fcntl(_socketFd, F_GETFL);
440 fdOptions |= O_NONBLOCK;
441 tmpReturn = fcntl(_socketFd, F_SETFL, fdOptions);
442
443 address.can_family = AF_CAN;
444 address.can_ifindex = ifaceRequest.ifr_ifindex;
445
447
448 if ((tmpReturn = bind(_socketFd, (struct sockaddr*)&address, sizeof(address))) == -1) {
449 throw CanInitException(formatString("FAILED to bind to socket CAN! Error: %d => %s", errno, strerror(errno)));
450 }
451 }
virtual void setCanFilters(const filtermap_t &filters)
Sets the CAN filters for the interface.

References _canFilterMask, _canInterface, _canProtocol, _socketFd, sockcanpp::exceptions::CanInitException::CanInitException(), sockcanpp::formatString(), and setCanFilters().

Referenced by CanDriver().

◆ joinCanFilters()

void sockcanpp::CanDriver::joinCanFilters ( ) const
virtual

Configures the socket to join the CAN filters.

Configures the socket to join the CAN filters. This is especially required, when using inverted CAN filters.

Source: https://stackoverflow.com/a/57680496/2921426

Definition at line 333 of file CanDriver.cpp.

333 {
334 if (_socketFd < 0) { throw InvalidSocketException("Invalid socket!", _socketFd); }
335
336 int32_t joinFilters = 1;
337
338 if (setsockopt(_socketFd, SOL_CAN_RAW, CAN_RAW_JOIN_FILTERS, &joinFilters, sizeof(joinFilters)) == -1) {
339 throw CanInitException(formatString("FAILED to join CAN filters on socket %d! Error: %d => %s", _socketFd, errno, strerror(errno)));
340 }
341 }

References _socketFd, sockcanpp::exceptions::CanInitException::CanInitException(), sockcanpp::formatString(), and sockcanpp::exceptions::InvalidSocketException::InvalidSocketException().

◆ readMessage()

CanMessage sockcanpp::CanDriver::readMessage ( )
virtual

Attempts to read a single message from the bus.

Attempts to read a message from the associated CAN bus.

Returns
CanMessage The message read from the bus.

Definition at line 151 of file CanDriver.cpp.

151{ return readMessageLock(); }
virtual CanMessage readMessageLock(bool const lock=true)
readMessage deadlock guard

References readMessageLock().

◆ readMessageLock()

CanMessage sockcanpp::CanDriver::readMessageLock ( bool const  lock = true)
privatevirtual

readMessage deadlock guard

readMessage deadlock guard, attempts to read a message from the associated CAN bus.

Returns
CanMessage The message read from the bus.

Definition at line 158 of file CanDriver.cpp.

158 {
159 unique_ptr<unique_lock<mutex>> locky{nullptr};
160
161 if (lock) { locky = unique_ptr<unique_lock<mutex>>{new unique_lock<mutex>{_lock}}; }
162
163 if (0 > _socketFd) { throw InvalidSocketException("Invalid socket!", _socketFd); }
164
165 ssize_t readBytes{0};
166 can_frame canFrame{};
167
168 readBytes = read(_socketFd, &canFrame, sizeof(can_frame));
169
170 if (0 > readBytes) { throw CanException(formatString("FAILED to read from CAN! Error: %d => %s", errno, strerror(errno)), _socketFd); }
171
172 return CanMessage{canFrame};
173 }
mutex _lock
!< Is the queue size available

References _lock, _socketFd, sockcanpp::exceptions::CanException::CanException(), sockcanpp::CanMessage::CanMessage(), sockcanpp::formatString(), and sockcanpp::exceptions::InvalidSocketException::InvalidSocketException().

Referenced by readMessage(), and readQueuedMessages().

◆ readQueuedMessages()

queue< CanMessage > sockcanpp::CanDriver::readQueuedMessages ( )
virtual

Attempts to read all queued messages from the bus.

Attempts to read all messages stored in the buffer for the associated CAN bus.

Returns
queue<CanMessage> A queue containing the messages read from the bus buffer.

Definition at line 258 of file CanDriver.cpp.

258 {
259 if (_socketFd < 0) { throw InvalidSocketException("Invalid socket!", _socketFd); }
260
261 unique_lock<mutex> locky{_lock};
262 queue<CanMessage> messages{};
263
264 if (_canReadQueueSize) {
265 for (int32_t i = _queueSize; 0 < i; --i) {
266 messages.emplace(readMessageLock(false));
267 }
268 } else {
269 // If the interface doesn't support FIONREAD, fall back
270 // to reading until data exhausted.
271 bool more{true};
272
273 do {
274 ssize_t readBytes;
275 can_frame canFrame{};
276 readBytes = read(_socketFd, &canFrame, sizeof(can_frame));
277 if (readBytes >= 0) {
278 messages.emplace(canFrame);
279 } else if (errno == EAGAIN) {
280 more = false;
281 } else {
282 throw CanException(formatString("FAILED to read from CAN! Error: %d => %s", errno, strerror(errno)), _socketFd);
283 }
284 } while (more);
285 }
286
287 return messages;
288 }
bool _canReadQueueSize
!< The size of the message queue read by waitForMessages()

References _canReadQueueSize, _lock, _queueSize, _socketFd, sockcanpp::exceptions::CanException::CanException(), sockcanpp::formatString(), sockcanpp::exceptions::InvalidSocketException::InvalidSocketException(), and readMessageLock().

◆ sendMessage()

ssize_t sockcanpp::CanDriver::sendMessage ( const CanMessage message,
bool  forceExtended = false 
)
virtual

Attempts to send a single CAN message.

Attempts to send a CAN message on the associated bus.

Parameters
messageThe message to be sent.
forceExtendedWhether or not to force use of an extended ID.
Returns
ssize_t The amount of bytes sent on the bus.

Definition at line 183 of file CanDriver.cpp.

183 {
184 if (_socketFd < 0) { throw InvalidSocketException("Invalid socket!", _socketFd); }
185
186 unique_lock<mutex> locky(_lockSend);
187
188 ssize_t bytesWritten = 0;
189
190 if (message.getFrameData().size() > CAN_MAX_DATA_LENGTH) {
191 throw CanException(formatString("INVALID data length! Message must be smaller than %d bytes!", CAN_MAX_DATA_LENGTH), _socketFd);
192 }
193
194 auto canFrame = message.getRawFrame();
195
196 if (forceExtended || ((uint32_t)message.getCanId() > CAN_SFF_MASK)) { canFrame.can_id |= CAN_EFF_FLAG; }
197
198 bytesWritten = write(_socketFd, (const void*)&canFrame, sizeof(canFrame));
199
200 if (bytesWritten == -1) { throw CanException(formatString("FAILED to write data to socket! Error: %d => %s", errno, strerror(errno)), _socketFd); }
201
202 return bytesWritten;
203 }
static constexpr int32_t CAN_MAX_DATA_LENGTH
The maximum amount of bytes allowed in a single CAN frame.
Definition CanDriver.hpp:70

References _lockSend, _socketFd, CAN_MAX_DATA_LENGTH, sockcanpp::exceptions::CanException::CanException(), sockcanpp::formatString(), sockcanpp::CanMessage::getCanId(), sockcanpp::CanMessage::getFrameData(), sockcanpp::CanMessage::getRawFrame(), and sockcanpp::exceptions::InvalidSocketException::InvalidSocketException().

Referenced by sendMessageQueue().

◆ sendMessageQueue() [1/3]

ssize_t sockcanpp::CanDriver::sendMessageQueue ( queue< CanMessage > &  messages,
microseconds  delay = 20us,
bool  forceExtended = false 
)
virtual

Attempts to send a queue of messages.

Attempts to send a queue of messages on the associated CAN bus.

Parameters
messagesA queue containing the messages to be sent.
delayIf greater than 0, will delay the sending of the next message.
forceExtendedWhether or not to force use of an extended ID.
Returns
int32_t The total amount of bytes sent.

Definition at line 214 of file CanDriver.cpp.

214{ return sendMessageQueue(messages, std::chrono::duration_cast<nanoseconds>(delay), forceExtended); }
virtual ssize_t sendMessageQueue(queue< CanMessage > &messages, microseconds delay=20us, bool forceExtended=false)
Attempts to send a queue of messages.

References sendMessageQueue().

◆ sendMessageQueue() [2/3]

ssize_t sockcanpp::CanDriver::sendMessageQueue ( queue< CanMessage > &  messages,
milliseconds  delay = 20ms,
bool  forceExtended = false 
)
virtual

Attempts to send a queue of messages.

Attempts to send a queue of messages on the associated CAN bus.

Parameters
messagesA queue containing the messages to be sent.
delayIf greater than 0, will delay the sending of the next message.
forceExtendedWhether or not to force use of an extended ID.
Returns
int32_t The total amount of bytes sent.

Definition at line 225 of file CanDriver.cpp.

225{ return sendMessageQueue(messages, std::chrono::duration_cast<nanoseconds>(delay), forceExtended); }

References sendMessageQueue().

◆ sendMessageQueue() [3/3]

ssize_t sockcanpp::CanDriver::sendMessageQueue ( queue< CanMessage > &  messages,
nanoseconds  delay = 20ns,
bool  forceExtended = false 
)
virtual

Attempts to send a queue of messages.

Attempts to send a queue of messages on the associated CAN bus.

Parameters
messagesA queue containing the messages to be sent.
delayIf greater than 0, will delay the sending of the next message.
forceExtendedWhether or not to force use of an extended ID.
Returns
int32_t The total amount of bytes sent.

Definition at line 236 of file CanDriver.cpp.

236 {
237 if (_socketFd < 0) { throw InvalidSocketException("Invalid socket!", _socketFd); }
238
239 ssize_t totalBytesWritten = 0;
240
241 while (!messages.empty()) {
242 totalBytesWritten += sendMessage(messages.front(), forceExtended);
243 messages.pop();
244
245 if (delay.count() > 0) {
246 sleep_for(delay);
247 }
248 }
249
250 return totalBytesWritten;
251 }
virtual ssize_t sendMessage(const CanMessage &message, bool forceExtended=false)
Attempts to send a single CAN message.

References _socketFd, sockcanpp::exceptions::InvalidSocketException::InvalidSocketException(), and sendMessage().

Referenced by sendMessageQueue(), and sendMessageQueue().

◆ setCanFilterMask()

void sockcanpp::CanDriver::setCanFilterMask ( const int32_t  mask,
const CanId filterId 
)
virtual

Attempts to set a new CAN filter mask to the interface.

Attempts to set the filter mask for the associated CAN bus.

Parameters
maskThe bit mask to apply.
filterIdThe ID to filter on.

Definition at line 349 of file CanDriver.cpp.

349{ setCanFilters({{filterId, static_cast<uint32_t>(mask)}}); }

References setCanFilters().

◆ setCanFilters()

void sockcanpp::CanDriver::setCanFilters ( const filtermap_t filters)
virtual

Sets the CAN filters for the interface.

Sets multiple CAN filters for the associated CAN bus.

Parameters
filtersA map containing the filters to apply.

Definition at line 356 of file CanDriver.cpp.

356 {
357 if (_socketFd < 0) { throw InvalidSocketException("Invalid socket!", _socketFd); }
358
359 unique_lock<mutex> locky(_lock);
360 vector<can_filter> canFilters{};
361
362 // Structured bindings only available with C++17
363 #if __cplusplus >= 201703L
364 for (const auto [id, filter] : filters) {
365 canFilters.push_back({*id, filter});
366 }
367 #else
368 for (const auto& filterPair : filters) {
369 canFilters.push_back({*filterPair.first, filterPair.second});
370 }
371 #endif
372
373 if (setsockopt(_socketFd, SOL_CAN_RAW, CAN_RAW_FILTER, canFilters.data(), canFilters.size() * sizeof(can_filter)) == -1) {
374 throw CanInitException(formatString("FAILED to set CAN filters on socket %d! Error: %d => %s", _socketFd, errno, strerror(errno)));
375 }
376 }

References _lock, _socketFd, sockcanpp::exceptions::CanInitException::CanInitException(), sockcanpp::formatString(), sockcanpp::exceptions::InvalidSocketException::InvalidSocketException(), and sockcanpp::CanId::operator*().

Referenced by initialiseSocketCan(), and setCanFilterMask().

◆ setDefaultSenderId()

CanDriver & sockcanpp::CanDriver::setDefaultSenderId ( const CanId id)
inline

Sets the default sender ID.

Definition at line 82 of file CanDriver.hpp.

References _defaultSenderId.

◆ setErrorFilter()

void sockcanpp::CanDriver::setErrorFilter ( const bool  enabled = true) const
virtual

Sets the error filter for the interface.

Sets the error filter for the associated CAN bus.

Parameters
enabledWhether or not to enable the error filter.

Definition at line 383 of file CanDriver.cpp.

383 {
384 if (_socketFd < 0) { throw InvalidSocketException("Invalid socket!", _socketFd); }
385
386 int32_t errorFilter = enabled ? 1 : 0;
387
388 if (setsockopt(_socketFd, SOL_CAN_RAW, CAN_RAW_ERR_FILTER, &errorFilter, sizeof(errorFilter)) == -1) {
389 throw CanInitException(formatString("FAILED to set CAN error filter on socket %d! Error: %d => %s", _socketFd, errno, strerror(errno)));
390 }
391 }

References _socketFd, sockcanpp::exceptions::CanInitException::CanInitException(), sockcanpp::formatString(), and sockcanpp::exceptions::InvalidSocketException::InvalidSocketException().

◆ setReceiveOwnMessages()

void sockcanpp::CanDriver::setReceiveOwnMessages ( const bool  enabled = true) const
virtual

Sets the receive own messages option for the interface.

Sets the receive own messages option for the associated CAN bus.

This option allows the socket to receive its own messages.

Parameters
enabledWhether or not to enable the receive own messages option.

Definition at line 400 of file CanDriver.cpp.

400 {
401 if (_socketFd < 0) { throw InvalidSocketException("Invalid socket!", _socketFd); }
402
403 int32_t receiveOwnMessages = enabled ? 1 : 0;
404
405 if (setsockopt(_socketFd, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS, &receiveOwnMessages, sizeof(receiveOwnMessages)) == -1) {
406 throw CanInitException(formatString("FAILED to set CAN error filter on socket %d! Error: %d => %s", _socketFd, errno, strerror(errno)));
407 }
408 }

References _socketFd, sockcanpp::exceptions::CanInitException::CanInitException(), sockcanpp::formatString(), and sockcanpp::exceptions::InvalidSocketException::InvalidSocketException().

◆ uninitialiseSocketCan()

void sockcanpp::CanDriver::uninitialiseSocketCan ( )
protectedvirtual

Uninitialises socketcan.

Closes the underlying CAN socket.

Definition at line 456 of file CanDriver.cpp.

456 {
457 unique_lock<mutex> locky(_lock);
458
459 if (_socketFd <= 0) { throw CanCloseException("Cannot close invalid socket!"); }
460
461 if (close(_socketFd) == -1) { throw CanCloseException(formatString("FAILED to close CAN socket! Error: %d => %s", errno, strerror(errno))); }
462
463 _socketFd = -1;
464 }

References _lock, _socketFd, sockcanpp::exceptions::CanCloseException::CanCloseException(), and sockcanpp::formatString().

Referenced by ~CanDriver().

◆ waitForMessages() [1/3]

bool sockcanpp::CanDriver::waitForMessages ( microseconds  timeout = 3000us)
virtual

Waits for CAN messages to appear.

Blocks until one or more CAN messages appear on the bus, or until the timeout runs out.

Parameters
timeoutThe time (in µsec) to wait before timing out.
Returns
true If messages are available on the bus.
false Otherwise.

Definition at line 100 of file CanDriver.cpp.

100 {
101 if (_socketFd < 0) { throw InvalidSocketException("Invalid socket!", _socketFd); }
102
103 unique_lock<mutex> locky(_lock);
104
105 fd_set readFileDescriptors;
106 timeval waitTime{0, static_cast<suseconds_t>(timeout.count())};
107
108 FD_ZERO(&readFileDescriptors);
109 FD_SET(_socketFd, &readFileDescriptors);
110 const auto fdsAvailable = select(_socketFd + 1, &readFileDescriptors, nullptr, nullptr, &waitTime);
111
112 int32_t bytesAvailable{0};
113 const auto retCode = ioctl(_socketFd, FIONREAD, &bytesAvailable);
114 if (retCode == 0) {
115 _queueSize = static_cast<int32_t>(std::ceil(bytesAvailable / sizeof(can_frame)));
116 } else {
117 _queueSize = 0;
118 // vcan interfaces don't support FIONREAD. So fall back to
119 // using alternate implementation in readQueuedMessages().
120 _canReadQueueSize = false;
121 }
122
123 return fdsAvailable > 0;
124 }

References _canReadQueueSize, _lock, _queueSize, _socketFd, and sockcanpp::exceptions::InvalidSocketException::InvalidSocketException().

Referenced by waitForMessages(), and waitForMessages().

◆ waitForMessages() [2/3]

bool sockcanpp::CanDriver::waitForMessages ( milliseconds  timeout = 3000ms)
virtual

Waits for CAN messages to appear.

Blocks until one or more CAN messages appear on the bus, or until the timeout runs out.

Parameters
timeoutThe time (in millis) to wait before timing out.
Returns
true If messages are available on the bus.
false Otherwise.

Definition at line 134 of file CanDriver.cpp.

134{ return waitForMessages(std::chrono::duration_cast<microseconds>(timeout)); }
virtual bool waitForMessages(microseconds timeout=3000us)
Waits for CAN messages to appear.

References waitForMessages().

◆ waitForMessages() [3/3]

bool sockcanpp::CanDriver::waitForMessages ( nanoseconds  timeout = 3000ns)
virtual

Waits for CAN messages to appear.

Blocks until one or more CAN messages appear on the bus, or until the timeout runs out.

Parameters
timeoutThe time (in nanoseconds) to wait before timing out.
Returns
true If messages are available on the bus.
false Otherwise.

Definition at line 144 of file CanDriver.cpp.

144{ return waitForMessages(std::chrono::duration_cast<microseconds>(timeout)); }

References waitForMessages().

Field Documentation

◆ _canFilterMask

filtermap_t sockcanpp::CanDriver::_canFilterMask
private

The bit mask used to filter CAN messages.

Definition at line 129 of file CanDriver.hpp.

Referenced by CanDriver(), getFilterMask(), and initialiseSocketCan().

◆ _canInterface

string sockcanpp::CanDriver::_canInterface
private

The CAN interface used for communication (e.g. can0, can1, ...)

Definition at line 140 of file CanDriver.hpp.

Referenced by CanDriver(), getCanInterface(), and initialiseSocketCan().

◆ _canProtocol

int32_t sockcanpp::CanDriver::_canProtocol
private

The protocol used when communicating via CAN.

Definition at line 131 of file CanDriver.hpp.

Referenced by CanDriver(), and initialiseSocketCan().

◆ _canReadQueueSize

bool sockcanpp::CanDriver::_canReadQueueSize {true}
private

!< The size of the message queue read by waitForMessages()

Definition at line 134 of file CanDriver.hpp.

134{true};

Referenced by readQueuedMessages(), and waitForMessages().

◆ _defaultSenderId

CanId sockcanpp::CanDriver::_defaultSenderId
private

The ID to send messages with if no other ID was set.

Definition at line 127 of file CanDriver.hpp.

Referenced by CanDriver(), getDefaultSenderId(), and setDefaultSenderId().

◆ _lock

mutex sockcanpp::CanDriver::_lock {}
private

!< Is the queue size available

< Mutex for thread-safety.

Definition at line 137 of file CanDriver.hpp.

137{};

Referenced by readMessageLock(), readQueuedMessages(), setCanFilters(), uninitialiseSocketCan(), and waitForMessages().

◆ _lockSend

mutex sockcanpp::CanDriver::_lockSend {}
private

Definition at line 138 of file CanDriver.hpp.

138{};

Referenced by sendMessage().

◆ _queueSize

int32_t sockcanpp::CanDriver::_queueSize {0}
private

Definition at line 133 of file CanDriver.hpp.

133{0};

Referenced by getMessageQueueSize(), readQueuedMessages(), and waitForMessages().

◆ _socketFd

int32_t sockcanpp::CanDriver::_socketFd {-1}
private

◆ CAN_MAX_DATA_LENGTH

constexpr int32_t sockcanpp::CanDriver::CAN_MAX_DATA_LENGTH = 8
staticconstexpr

The maximum amount of bytes allowed in a single CAN frame.

Definition at line 70 of file CanDriver.hpp.

Referenced by sendMessage().

◆ CAN_SOCK_RAW

constexpr int32_t sockcanpp::CanDriver::CAN_SOCK_RAW = CAN_RAW
staticconstexpr

The raw CAN protocol.

Definition at line 71 of file CanDriver.hpp.

◆ CAN_SOCK_SEVEN

constexpr int32_t sockcanpp::CanDriver::CAN_SOCK_SEVEN = 7
staticconstexpr

A separate CAN protocol, used by certain embedded device OEMs.

Definition at line 72 of file CanDriver.hpp.


The documentation for this class was generated from the following files: