Libsockcanpp
A complete C++ wrapper around socketcan.
Loading...
Searching...
No Matches
CanId.hpp
Go to the documentation of this file.
1/**
2 * @file CanId.hpp
3 * @author Simon Cahill (contact@simonc.eu)
4 * @brief Contains the implementation of a value-type representing a CAN identifier.
5 * @version 0.1
6 * @date 2020-07-01
7 *
8 * @copyright Copyright (c) 2020-2025 Simon Cahill
9 *
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 */
22
23#ifndef LIBSOCKPP_INCLUDE_CANID_HPP
24#define LIBSOCKPP_INCLUDE_CANID_HPP
25
26//////////////////////////////
27// SYSTEM INCLUDES //
28//////////////////////////////
29#include <algorithm>
30#include <bitset>
31#include <cmath>
32#include <exception>
33#include <linux/can.h>
34#include <system_error>
35
36#if __cpp_concepts >= 201907
37template<typename Str>
38concept Stringable = requires(Str s) { { s.data() + s.size() } -> std::convertible_to<const char*>; };
39
40template<typename CharArr>
41concept CChar = requires(CharArr c) { std::is_same_v<CharArr, const char*>; };
42
43template<typename Int>
44concept Integral = requires(Int i) { std::is_integral_v<Int>; };
45
46template<typename C>
47concept ConvertibleToCanId = Stringable<C> || Integral<C> || CChar<C>;
48#endif
49
50namespace sockcanpp {
51
52 using std::bitset;
53 using std::error_code;
54 using std::exception;
55 using std::generic_category;
56 using std::system_error;
57
58 /**
59 * @brief Represents a CAN ID in a simple and easy-to-use manner.
60 */
61 struct CanId {
62 public: // +++ Constructors +++
63 constexpr CanId() = default;
64 constexpr CanId(const canid_t id): m_identifier(id) { }
65 constexpr CanId(const int32_t id): m_identifier(id) { }
66
67 #if __cpp_concepts >= 201907
68 template<Stringable T>
69 CanId(const T& id) { m_identifier = std::stoul(id.data(), nullptr, 16); }
70 #endif // __cpp_concepts >= 201907
71
72 CanId(const char* id) { m_identifier = std::stoul(id, nullptr, 16); }
73
74 public: // +++ Operators +++
75 constexpr canid_t operator *() const { return m_identifier; } //!< Returns the raw CAN ID value.
76
77#pragma region "Conversions"
78 constexpr operator int16_t() const { return static_cast<int16_t>(m_identifier) & CAN_ERR_MASK; }
79 constexpr operator uint16_t() const { return static_cast<uint16_t>(m_identifier) & CAN_ERR_MASK; }
80 constexpr operator int32_t() const { return m_identifier & CAN_ERR_MASK; }
81 constexpr operator canid_t() const { return m_identifier & CAN_ERR_MASK; }
82#pragma endregion
83
84#pragma region "Bitwise Operators"
85 template<typename T>
86 constexpr CanId operator &(const T x) const { return m_identifier & x; } //!< Performs a bitwise AND operation on this ID and another.
87 constexpr CanId operator &(const CanId& x) const { return m_identifier & x.m_identifier; } //!< Performs a bitwise AND operation on this ID and another.
88
89 template<typename T>
90 constexpr CanId operator |(const T x) const { return m_identifier | x; } //!< Performs a bitwise OR operation on this ID and a 16-bit integer.
91 constexpr CanId operator |(const CanId& x) const { return m_identifier | x.m_identifier; } //!< Performs a bitwise OR operation on this ID and another.
92
93 template<typename T>
94 constexpr CanId operator ^(const T x) const { return m_identifier ^ x; } //!< Performs a bitwise XOR operation on this ID and a 16-bit integer.
95 constexpr CanId operator ^(const CanId& x) const { return m_identifier ^ x.m_identifier; } //!< Performs a bitwise XOR operation on this ID and another.
96
97 constexpr CanId operator ~() const { return ~m_identifier; } //!< Performs a bitwise NOT operation on this ID.
98
99 template<typename T>
100 constexpr CanId operator <<(const T x) const { return m_identifier << x; } //!< Shifts this ID to the left by a 16-bit integer.
101 constexpr CanId operator <<(const CanId& x) const { return m_identifier << x.m_identifier; } //!< Shifts this ID to the left by another.
102
103 template<typename T>
104 constexpr CanId operator >>(const T x) const { return m_identifier >> x; } //!< Shifts this ID to the right by a 16-bit integer.
105 constexpr CanId operator >>(const CanId& x) const { return m_identifier >> x.m_identifier; } //!< Shifts this ID to the right by another.
106
107 template<typename T>
108 CanId operator <<=(const T x) { return m_identifier <<= x; } //!< Shifts this ID to the left by a 16-bit integer.
109 CanId operator <<=(const CanId& x) { return m_identifier <<= x.m_identifier; } //!< Shifts this ID to the left by another.
110
111 template<typename T>
112 CanId operator >>=(const T x) { return m_identifier >>= x; } //!< Shifts this ID to the right by a 16-bit integer.
113 CanId operator >>=(const CanId& x) { return m_identifier >>= x.m_identifier; } //!< Shifts this ID to the right by another.
114
115#pragma endregion
116
117#pragma region "Comparison Operators"
118 constexpr bool operator ==(const CanId& x) const { return m_identifier == x.m_identifier; } //!< Compares this ID to another.
119
120 template<typename T>
121 constexpr bool operator ==(const T x) const { return m_identifier == static_cast<canid_t>(x); } //!< Compares this ID to another.
122
123 constexpr bool operator !=(const CanId& x) const { return m_identifier != x.m_identifier; } //!< Compares this ID to another.
124
125 template<typename T>
126 constexpr bool operator !=(const T x) const { return m_identifier != static_cast<canid_t>(x); } //!< Compares this ID to another.
127
128 template<typename T>
129 constexpr bool operator <(T x) const { return static_cast<canid_t>(x) < m_identifier; } //!< Compares this ID to another.
130
131 template<typename T>
132 constexpr bool operator >(T x) const { return static_cast<canid_t>(x) > m_identifier; } //!< Compares this ID to a 32-bit integer.
133
134 template<typename T>
135 constexpr bool operator <=(const T x) const { return x.m_identifier <= m_identifier; } //!< Compares this ID to another.
136
137 template<typename T>
138 constexpr bool operator >=(const T x) const { return x.m_identifier >= m_identifier; } //!< Compares this ID to another.
139#pragma endregion
140
141#pragma region "Assignment Operators"
142 template<typename T>
143 constexpr CanId operator =(const T val) { return CanId(val); } //!< Assigns a new integer to this CanID
144
145 #if __cpp_concepts >= 201907
146 template<Stringable T>
147 CanId operator =(const T& val) {
148 return operator=(std::stoul(val.data(), nullptr, 16));
149 }
150 #endif // __cpp_concepts >= 201907
151
152 constexpr CanId operator =(const int64_t val) { return operator =((canid_t)val); } //!< Assigns a 64-bit integer to this ID.
153
154 template<typename T>
155 constexpr CanId operator |=(const T x) { return m_identifier |= x; } //!< Performs a bitwise OR operation on this ID and another.
156
157 template<typename T>
158 constexpr CanId operator &=(const T x) { return m_identifier &= x; } //!< Performs a bitwise AND operation on this ID and another.
159
160 template<typename T>
161 constexpr CanId operator ^=(const T x) { return m_identifier ^= x; } //!< Performs a bitwise XOR operation on this ID and another.
162#pragma endregion
163
164#pragma region "Arithmetic Operators"
165 template<typename T>
166 constexpr CanId operator +(const T x) const { return m_identifier + x; }
167
168 template<typename T>
169 constexpr CanId operator +=(const T x) { return m_identifier += x; }
170
171 template<typename T>
172 constexpr CanId operator -=(const T x) { return m_identifier -= x; }
173
174 template<typename T>
175 constexpr CanId operator -(const T x) const { return m_identifier - x; }
176
177 template<typename T>
178 constexpr CanId operator *(const T x) const { return m_identifier * x; }
179
180 template<typename T>
181 constexpr CanId operator *= (const T x) { return m_identifier *= x; }
182
183 template<typename T>
184 constexpr CanId operator /(const T x) const { return m_identifier / x; }
185
186 template<typename T>
187 constexpr CanId operator /=(const T x) { return m_identifier /= x; }
188
189 template<typename T>
190 constexpr CanId operator %(const T x) const { return m_identifier % x; }
191
192 template<typename T>
193 constexpr CanId operator %=(const T x) { return m_identifier %= x; }
194#pragma endregion
195
196 public: // +++ Validity Checks +++
197 /**
198 * @brief Indicates whether or not a given integer is a valid CAN identifier.
199 *
200 * @param value The integer to check.
201 *
202 * @return true If value is a valid CAN identifier.
203 * @return false Otherwise.
204 */
205 template<typename T>
206 static constexpr bool isValidIdentifier(T value) {
207 return static_cast<canid_t>(value) <= CAN_EFF_MASK;
208 }
209
210 /**
211 * @brief Indicates whether or not a given integer contains the error frame flag or not.
212 *
213 * @param value The integer to check.
214 *
215 * @return true If value has the error frame flag (bit) set to 1.
216 * @return false Otherwise.
217 */
218 template<typename T>
219 static constexpr bool isErrorFrame(T value) {
220 return static_cast<canid_t>(value) & CAN_ERR_FLAG;
221 }
222
223 /**
224 * @brief Indicates whether the received frame is a remote transmission request.
225 *
226 * @param value The integer to check.
227 *
228 * @return true If the frame is a remote transmission request.
229 * @return false Otherwise.
230 */
231 template<typename T>
232 static constexpr bool isRemoteTransmissionRequest(T value) {
233 return static_cast<canid_t>(value) & CAN_RTR_FLAG;
234 }
235
236 /**
237 * @brief Indicates whether or not a given integer is an extended frame ID.
238 *
239 * @param value The integer to check.
240 *
241 * @return true If the frame is in the extended format.
242 * @return false Otherwise.
243 */
244 template<typename T>
245 static constexpr bool isExtendedFrame(T value) {
246 return static_cast<canid_t>(value) & CAN_EFF_FLAG;
247 }
248
249 public: // +++ Getters +++
250 constexpr bool hasErrorFrameFlag() const { return isErrorFrame(m_identifier); } //!< Indicates whether or not this ID is an error frame.
251 constexpr bool hasRtrFrameFlag() const { return isRemoteTransmissionRequest(m_identifier); } //!< Indicates whether or not this ID is a remote transmission request.
252 constexpr bool isStandardFrameId() const { return !isExtendedFrame(m_identifier); } //!< Indicates whether or not this ID is a standard frame ID.
253 constexpr bool isExtendedFrameId() const { return isExtendedFrame(m_identifier); } //!< Indicates whether or not this ID is an extended frame ID.
254
255 public: // +++ Equality Checks +++
256 constexpr bool equals(const CanId& otherId) const { return m_identifier == otherId.m_identifier; } //!< Compares this ID to another.
257
258 private: // +++ Variables +++
259 uint32_t m_identifier = 0;
260 };
261
262 /**
263 * @brief Implements a hash function for the CanId type.
264 */
265 struct CanIdHasher {
266 public:
267 size_t operator()(const CanId& id) const { return std::hash<canid_t>()(*id); }
268 };
269
270}
271
272#endif // LIBSOCKPP_INCLUDE_CANID_HPP
CanDriver class; handles communication via CAN.
Definition CanDriver.hpp:68
virtual void allowCanFdFrames(const bool enabled=true) const
Sets the CAN FD frame option for the interface.
static constexpr int32_t CAN_SOCK_SEVEN
A separate CAN protocol, used by certain embedded device OEMs.
Definition CanDriver.hpp:72
virtual void joinCanFilters() const
Configures the socket to join the CAN filters.
CanDriver(const string &canInterface, const int32_t canProtocol, const filtermap_t &filters, const CanId defaultSenderId=0)
Definition CanDriver.cpp:85
int32_t getMessageQueueSize() const
Gets the amount of CAN messages found after last calling waitForMessages()
Definition CanDriver.hpp:88
bool _canReadQueueSize
!< The size of the message queue read by waitForMessages()
virtual void setReceiveOwnMessages(const bool enabled=true) const
Sets the receive own messages option for the interface.
virtual CanMessage readMessage()
Attempts to read a single message from the bus.
filtermap_t getFilterMask() const
Gets the filter mask used by this instance.
Definition CanDriver.hpp:86
CanDriver(const string &canInterface, const int32_t canProtocol, const CanId defaultSenderId=0)
Constructor.
Definition CanDriver.cpp:79
virtual void setErrorFilter(const bool enabled=true) const
Sets the error filter for the interface.
CanDriver(const string &canInterface, const int32_t canProtocol, const int32_t filterMask, const CanId defaultSenderId=0)
Definition CanDriver.cpp:82
virtual ssize_t sendMessageQueue(queue< CanMessage > &messages, milliseconds delay=20ms, bool forceExtended=false)
Attempts to send a queue of messages.
string getCanInterface() const
The CAN interface used by this instance.
Definition CanDriver.hpp:91
virtual void setCanFilters(const filtermap_t &filters)
Sets the CAN filters for the interface.
string _canInterface
The CAN interface used for communication (e.g. can0, can1, ...)
CanId getDefaultSenderId() const
Gets the default sender ID.
Definition CanDriver.hpp:84
CanId _defaultSenderId
The ID to send messages with if no other ID was set.
virtual queue< CanMessage > readQueuedMessages()
Attempts to read all queued messages from the bus.
int32_t _canProtocol
The protocol used when communicating via CAN.
virtual void setCanFilterMask(const int32_t mask, const CanId &filterId)
Attempts to set a new CAN filter mask to the interface.
virtual CanMessage readMessageLock(bool const lock=true)
readMessage deadlock guard
virtual ssize_t sendMessage(const CanMessage &message, bool forceExtended=false)
Attempts to send a single CAN message.
virtual ssize_t sendMessageQueue(queue< CanMessage > &messages, nanoseconds delay=20ns, bool forceExtended=false)
Attempts to send a queue of messages.
int32_t _socketFd
The CAN socket file descriptor.
static constexpr int32_t CAN_SOCK_RAW
The raw CAN protocol.
Definition CanDriver.hpp:71
virtual bool waitForMessages(milliseconds timeout=3000ms)
Waits for CAN messages to appear.
mutex _lock
!< Is the queue size available
CanDriver & setDefaultSenderId(const CanId &id)
Sets the default sender ID.
Definition CanDriver.hpp:82
filtermap_t _canFilterMask
The bit mask used to filter CAN messages.
int32_t getSocketFd() const
The socket file descriptor used by this instance.
Definition CanDriver.hpp:89
virtual void initialiseSocketCan()
Initialises socketcan.
virtual ~CanDriver()
Destructor.
Definition CanDriver.hpp:79
static constexpr int32_t CAN_MAX_DATA_LENGTH
The maximum amount of bytes allowed in a single CAN frame.
Definition CanDriver.hpp:70
virtual bool waitForMessages(nanoseconds timeout=3000ns)
Waits for CAN messages to appear.
virtual bool waitForMessages(microseconds timeout=3000us)
Waits for CAN messages to appear.
virtual ssize_t sendMessageQueue(queue< CanMessage > &messages, microseconds delay=20us, bool forceExtended=false)
Attempts to send a queue of messages.
virtual void uninitialiseSocketCan()
Uninitialises socketcan.
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
An exception that may be thrown when an error occurs while closing a CAN socket.
An exception that may be thrown when an error occurs while closing a CAN socket.
CanException(const string &message, int32_t socket)
An exception that may be thrown when an error occurred while initialising a CAN socket.
An exception that may be thrown when an error occurs while closing a CAN socket.
InvalidSocketException(const string &message, int32_t socket)
Main library namespace.
Definition CanDriver.cpp:56
string formatString(const string &format, Args... args)
Formats a std string object.
Implements a hash function for the CanId type.
Definition CanId.hpp:265
size_t operator()(const CanId &id) const
Definition CanId.hpp:267
Represents a CAN ID in a simple and easy-to-use manner.
Definition CanId.hpp:61
constexpr CanId()=default
constexpr bool operator!=(const CanId &x) const
Compares this ID to another.
Definition CanId.hpp:123
constexpr bool operator==(const CanId &x) const
Compares this ID to another.
Definition CanId.hpp:118
constexpr bool hasRtrFrameFlag() const
Indicates whether or not this ID is a remote transmission request.
Definition CanId.hpp:251
constexpr bool operator!=(const T x) const
Compares this ID to another.
Definition CanId.hpp:126
constexpr CanId operator&(const T x) const
Performs a bitwise AND operation on this ID and another.
Definition CanId.hpp:86
constexpr CanId operator^=(const T x)
Performs a bitwise XOR operation on this ID and another.
Definition CanId.hpp:161
constexpr CanId operator|(const CanId &x) const
Performs a bitwise OR operation on this ID and another.
Definition CanId.hpp:91
constexpr CanId operator/=(const T x)
Definition CanId.hpp:187
constexpr CanId operator^(const CanId &x) const
Performs a bitwise XOR operation on this ID and another.
Definition CanId.hpp:95
constexpr bool operator<=(const T x) const
Compares this ID to another.
Definition CanId.hpp:135
constexpr CanId operator-=(const T x)
Definition CanId.hpp:172
constexpr CanId operator^(const T x) const
Performs a bitwise XOR operation on this ID and a 16-bit integer.
Definition CanId.hpp:94
constexpr bool operator>(T x) const
Compares this ID to a 32-bit integer.
Definition CanId.hpp:132
constexpr canid_t operator*() const
Returns the raw CAN ID value.
Definition CanId.hpp:75
constexpr operator uint16_t() const
Definition CanId.hpp:79
constexpr CanId operator/(const T x) const
Definition CanId.hpp:184
constexpr CanId operator=(const int64_t val)
Assigns a 64-bit integer to this ID.
Definition CanId.hpp:152
constexpr CanId operator+=(const T x)
Definition CanId.hpp:169
constexpr CanId operator|=(const T x)
Performs a bitwise OR operation on this ID and another.
Definition CanId.hpp:155
constexpr CanId operator+(const T x) const
Definition CanId.hpp:166
constexpr CanId operator&(const CanId &x) const
Performs a bitwise AND operation on this ID and another.
Definition CanId.hpp:87
CanId operator>>=(const CanId &x)
Shifts this ID to the right by another.
Definition CanId.hpp:113
static constexpr bool isErrorFrame(T value)
Indicates whether or not a given integer contains the error frame flag or not.
Definition CanId.hpp:219
CanId operator>>=(const T x)
Shifts this ID to the right by a 16-bit integer.
Definition CanId.hpp:112
constexpr operator int16_t() const
Definition CanId.hpp:78
constexpr CanId(const int32_t id)
Definition CanId.hpp:65
CanId(const char *id)
Definition CanId.hpp:72
constexpr bool isStandardFrameId() const
Indicates whether or not this ID is a standard frame ID.
Definition CanId.hpp:252
constexpr operator int32_t() const
Definition CanId.hpp:80
constexpr CanId operator|(const T x) const
Performs a bitwise OR operation on this ID and a 16-bit integer.
Definition CanId.hpp:90
constexpr CanId operator%(const T x) const
Definition CanId.hpp:190
constexpr operator canid_t() const
Definition CanId.hpp:81
constexpr CanId operator>>(const CanId &x) const
Shifts this ID to the right by another.
Definition CanId.hpp:105
static constexpr bool isRemoteTransmissionRequest(T value)
Indicates whether the received frame is a remote transmission request.
Definition CanId.hpp:232
constexpr bool equals(const CanId &otherId) const
Compares this ID to another.
Definition CanId.hpp:256
constexpr bool operator==(const T x) const
Compares this ID to another.
Definition CanId.hpp:121
static constexpr bool isValidIdentifier(T value)
Indicates whether or not a given integer is a valid CAN identifier.
Definition CanId.hpp:206
constexpr CanId operator*=(const T x)
Definition CanId.hpp:181
constexpr bool operator<(T x) const
Compares this ID to another.
Definition CanId.hpp:129
static constexpr bool isExtendedFrame(T value)
Indicates whether or not a given integer is an extended frame ID.
Definition CanId.hpp:245
constexpr CanId operator=(const T val)
Assigns a new integer to this CanID.
Definition CanId.hpp:143
constexpr CanId operator-(const T x) const
Definition CanId.hpp:175
constexpr CanId(const canid_t id)
Definition CanId.hpp:64
constexpr CanId operator~() const
Performs a bitwise NOT operation on this ID.
Definition CanId.hpp:97
constexpr CanId operator>>(const T x) const
Shifts this ID to the right by a 16-bit integer.
Definition CanId.hpp:104
uint32_t m_identifier
Definition CanId.hpp:259
constexpr bool hasErrorFrameFlag() const
Indicates whether or not this ID is an error frame.
Definition CanId.hpp:250
constexpr CanId operator&=(const T x)
Performs a bitwise AND operation on this ID and another.
Definition CanId.hpp:158
constexpr bool operator>=(const T x) const
Compares this ID to another.
Definition CanId.hpp:138
constexpr CanId operator%=(const T x)
Definition CanId.hpp:193
constexpr CanId operator*(const T x) const
Definition CanId.hpp:178
constexpr bool isExtendedFrameId() const
Indicates whether or not this ID is an extended frame ID.
Definition CanId.hpp:253