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.