Libsockcanpp
A complete C++ wrapper around socketcan.
CanId.hpp
Go to the documentation of this file.
1/**
2 * @file CanId.hpp
3 * @author Simon Cahill (simonc@online.de)
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 Simon Cahill
9 *
10 * Copyright 2020 Simon Cahill
11 *
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 * http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 */
24
25#ifndef LIBSOCKPP_INCLUDE_CANID_HPP
26#define LIBSOCKPP_INCLUDE_CANID_HPP
27
28//////////////////////////////
29// SYSTEM INCLUDES //
30//////////////////////////////
31#include <bitset>
32#include <cmath>
33#include <exception>
34#include <linux/can.h>
35#include <system_error>
36
37namespace sockcanpp {
38
39 using std::bitset;
40 using std::error_code;
41 using std::exception;
42 using std::generic_category;
43 using std::system_error;
44
45 /**
46 * @brief Represents a CAN ID in a simple and easy-to-use manner.
47 */
48 struct CanId {
49 public: // +++ Constructors +++
52 _isExtendedFrameId(orig._isExtendedFrameId) { /* copy */ }
53
54 CanId(const uint32_t identifier): _identifier(identifier) {
55 // TODO: Switch to using bitmasks!
56
57 if (isValidIdentifier(identifier)) {
58 if (((int32_t)log2(identifier) + 1) < 11) {
59 _isStandardFrameId = true;
60 } else { _isExtendedFrameId = true; }
61 } else if (isErrorFrame(identifier)) {
62 _isErrorFrame = true;
63 } else if (isRemoteTransmissionRequest(identifier)) {
65 }
66 }
67
69
70 public: // +++ Operators +++
71
72#pragma region "Implicit Cast Operators"
73 operator int16_t() const { return isStandardFrameId() ? (int16_t)_identifier : throw system_error(error_code(0xbad1d, generic_category()), "INVALID CAST: ID is extended or invalid!"); }
74 operator uint16_t() const { return isStandardFrameId() ? (uint16_t)_identifier : throw system_error(error_code(0xbad1d, generic_category()), "INVALID CAST: ID is extended or invalid!"); }
75 operator int32_t() const { return _identifier; }
76 operator uint32_t() const { return _identifier; }
77#pragma endregion
78
79#pragma region "Bitwise Operators"
80 CanId operator &(CanId& x) const { return _identifier & x._identifier; }
81 CanId operator &(const CanId x) const { return _identifier & x._identifier; }
82 CanId operator &(const int16_t x) const { return _identifier & x; }
83 CanId operator &(const uint16_t x) const { return _identifier & x; }
84 CanId operator &(const int32_t x) const { return _identifier & x; }
85 CanId operator &(const uint32_t x) const { return _identifier & x; }
86 CanId operator &(const int64_t x) const { return _identifier & x; }
87 CanId operator &(const uint64_t x) const { return _identifier & x; }
88
89 CanId operator |(CanId& x) const { return _identifier | x._identifier; }
90 CanId operator |(const CanId x) const { return _identifier | x._identifier; }
91 CanId operator |(const int16_t x) const { return _identifier | x; }
92 CanId operator |(const uint16_t x) const { return _identifier | x; }
93 CanId operator |(const int32_t x) const { return _identifier | x; }
94 CanId operator |(const uint32_t x) const { return _identifier | x; }
95 CanId operator |(const int64_t x) const { return _identifier | x; }
96 CanId operator |(const uint64_t x) const { return _identifier | x; }
97#pragma endregion
98
99#pragma region "Comparison Operators"
100 bool operator ==(CanId& x) const { return _identifier == x._identifier; }
101 bool operator ==(const CanId& x) const { return _identifier == x._identifier; }
102 bool operator ==(const int16_t x) const { return _identifier == x; }
103 bool operator ==(const uint16_t x) const { return _identifier == x; }
104 bool operator ==(const int32_t x) const { return _identifier == x; }
105 bool operator ==(const uint32_t x) const { return _identifier == x; }
106 bool operator ==(const int64_t x) const { return (x > UINT32_MAX || x < INT32_MIN) ? false : x == _identifier; }
107 bool operator ==(const uint64_t x) const { return x > UINT32_MAX ? false : x == _identifier; }
108 bool operator !=(CanId& x) const { return _identifier != x._identifier; }
109 bool operator !=(const CanId& x) const { return _identifier != x._identifier; }
110 bool operator !=(const int16_t x) const { return _identifier != x; }
111 bool operator !=(const uint16_t x) const { return _identifier != x; }
112 bool operator !=(const int32_t x) const { return _identifier != x; }
113 bool operator !=(const uint32_t x) const { return _identifier != x; }
114 bool operator !=(const int64_t x) const { return (x > UINT32_MAX || x < INT32_MIN) ? false : x != _identifier; }
115 bool operator !=(const uint64_t x) const { return x > UINT32_MAX ? false : x != _identifier; }
116
117 bool operator <(CanId& x) const { return x._identifier < _identifier; }
118 bool operator <(int32_t x) const { return x < _identifier; }
119 bool operator <(uint32_t x) const { return x < _identifier; }
120 bool operator <(int16_t x) const { return x < _identifier; }
121 bool operator <(uint16_t x) const { return x < _identifier; }
122 bool operator <=(CanId& x) const { return x._identifier <= _identifier; }
123 bool operator >(CanId& x) const { return x._identifier > _identifier; }
124 bool operator >(int32_t x) const { return x > _identifier; }
125 bool operator >(uint32_t x) const { return x > _identifier; }
126 bool operator >(int16_t x) const { return x > _identifier; }
127 bool operator >(uint16_t x) const { return x > _identifier; }
128 bool operator >=(CanId& x) const { return x._identifier >= _identifier; }
129 bool operator <(const CanId& x) const { return x._identifier < _identifier; }
130 bool operator <=(const CanId& x) const { return x._identifier <= _identifier; }
131 bool operator >(const CanId& x) const { return x._identifier > _identifier; }
132 bool operator >=(const CanId& x) const { return x._identifier >= _identifier; }
133#pragma endregion
134
135#pragma region "Assignment Operators"
136 CanId operator =(const int32_t val) {
137 uint32_t tmpVal = val;
138 auto tmp = (isValidIdentifier(tmpVal) ? CanId(val) : throw system_error(error_code(0x5421, generic_category()), "INVALID CAST: ID is extended or invalid!"));
139 return tmp;
140 }
141
142 CanId operator =(const uint32_t val) {
143 uint32_t tmp = val;
144 return (isValidIdentifier(tmp) ? CanId(val) : throw system_error(error_code(0x5421, generic_category()), "INVALID CAST: ID is extended or invalid!"));
145 }
146
147 CanId operator =(const int64_t val) { return operator =((int32_t)val); }
148#pragma endregion
149
150#pragma region "Arithmetic Operators"
151 CanId operator +(CanId& x) const { return _identifier + x._identifier; }
152 CanId operator +(const CanId& x) const { return _identifier + x._identifier; }
153 CanId operator +(const int16_t x) const { return _identifier + x; }
154 CanId operator +(const uint16_t x) const { return _identifier + x; }
155 CanId operator +(const int32_t x) const { return _identifier + x; }
156 CanId operator +(const uint32_t x) const { return _identifier + x; }
157 CanId operator +(const int64_t x) const { return _identifier + x; }
158 CanId operator +(const uint64_t x) const { return _identifier + x; }
159
160 CanId operator -(CanId& x) const { return _identifier - x._identifier; }
161 CanId operator -(const CanId& x) const { return _identifier - x._identifier; }
162 CanId operator -(const int16_t x) const { return _identifier - x; }
163 CanId operator -(const uint16_t x) const { return _identifier - x; }
164 CanId operator -(const int32_t x) const { return _identifier - x; }
165 CanId operator -(const uint32_t x) const { return _identifier - x; }
166 CanId operator -(const int64_t x) const { return _identifier - x; }
167 CanId operator -(const uint64_t x) const { return _identifier - x; }
168#pragma endregion
169
170 public: // +++ Validity Checks +++
171 /**
172 * @brief Indicates whether or not a given integer is a valid CAN identifier.
173 *
174 * @param value The integer to check.
175 *
176 * @return true If value is a valid CAN identifier.
177 * @return false Otherwise.
178 */
179 static bool isValidIdentifier(uint32_t value) {
180 int32_t tmpValue = ((int32_t)log2(value) + 2); // Get bit count
181
182 // Check for extended frame flag
183 if (tmpValue >= 29) {
184 value = (value & CAN_EFF_FLAG) ? (value & CAN_EFF_MASK) : (value & CAN_SFF_MASK);
185 tmpValue = ((int32_t)log2(value) + 1); // Get bit count again
186 }
187
188 return (value == 0) /* Default value, also valid ID */ || ((tmpValue <= 29 && tmpValue > 0));
189 }
190
191 /**
192 * @brief Indicates whether or not a given integer contains the error frame flag or not.
193 *
194 * @param value The integer to check.
195 *
196 * @return true If value has the error frame flag (bit) set to 1.
197 * @return false Otherwise.
198 */
199 static bool isErrorFrame(uint32_t value) {
200 try { return bitset<sizeof(int32_t)>(value).test(29); }
201 catch (...) { return false; /* Brute-force, but works. */ }
202 }
203
204 /**
205 * @brief Indicates whether the received frame is a remote transmission request.
206 *
207 * @param value The integer to check.
208 *
209 * @return true If the frame is a remote transmission request.
210 * @return false Otherwise.
211 */
212 static bool isRemoteTransmissionRequest(uint32_t value) {
213 try { return bitset<sizeof(int32_t)>(value).test(30); }
214 catch (...) { return false; /* Brute-force, but works. */ }
215 }
216
217 public: // +++ Getters +++
218 bool hasErrorFrameFlag() const { return _isErrorFrame; }
220 bool isStandardFrameId() const { return _isStandardFrameId; }
221 bool isExtendedFrameId() const { return _isExtendedFrameId; }
222
223 public: // +++ Equality Checks +++
224 bool equals(CanId otherId) const { return *this == otherId; }
225
226 private: // +++ Variables +++
227 bool _isErrorFrame = false;
229 bool _isStandardFrameId = false;
230 bool _isExtendedFrameId = false;
231
232 uint32_t _identifier = 0;
233 };
234
235}
236
237#endif // LIBSOCKPP_INCLUDE_CANID_HPP
CanDriver class; handles communication via CAN.
Definition: CanDriver.hpp:62
CanDriver(const string canInterface, const int32_t canProtocol, const CanId defaultSenderId=0)
!< A separate CAN protocol, used by certain embedded device OEMs.
Definition: CanDriver.cpp:81
virtual CanMessage readMessage()
!< Waits for CAN messages to appear
Definition: CanDriver.cpp:121
const int32_t getFilterMask() const
!< Gets the default sender ID
Definition: CanDriver.hpp:79
static const int32_t CAN_SOCK_RAW
!< The maximum amount of bytes allowed in a single CAN frame
Definition: CanDriver.hpp:65
static const int32_t CAN_SOCK_SEVEN
!< The raw CAN protocol
Definition: CanDriver.hpp:66
const int32_t getMessageQueueSize() const
!< Gets the filter mask used by this instance
Definition: CanDriver.hpp:80
CanId _defaultSenderId
!< readMessage deadlock guard
Definition: CanDriver.hpp:102
int32_t _queueSize
!< The CAN socket file descriptor
Definition: CanDriver.hpp:107
virtual queue< CanMessage > readQueuedMessages()
!< Attempts to send a queue of messages
Definition: CanDriver.cpp:202
int32_t _canProtocol
!< The bit mask used to filter CAN messages
Definition: CanDriver.hpp:105
virtual int32_t sendMessageQueue(queue< CanMessage > messages, milliseconds delay=milliseconds(20), bool forceExtended=false)
!< Attempts to send a single CAN message
Definition: CanDriver.cpp:184
virtual CanMessage readMessageLock(bool const lock=true)
!< Uninitialises socketcan
Definition: CanDriver.cpp:130
const int32_t getSocketFd() const
!< Gets the amount of CAN messages found after last calling waitForMessages()
Definition: CanDriver.hpp:81
CanDriver(const string canInterface, const int32_t canProtocol, const int32_t filterMask, const CanId defaultSenderId=0)
!< Constructor
Definition: CanDriver.cpp:84
int32_t _socketFd
!< The protocol used when communicating via CAN
Definition: CanDriver.hpp:106
int32_t _canFilterMask
!< The ID to send messages with if no other ID was set.
Definition: CanDriver.hpp:104
CanDriver & setDefaultSenderId(const CanId id)
!< Destructor
Definition: CanDriver.hpp:75
virtual bool waitForMessages(milliseconds timeout=milliseconds(3000))
!< The socket file descriptor used by this instance.
Definition: CanDriver.cpp:99
mutex _lock
!< Mutex for thread-safety.
Definition: CanDriver.hpp:110
virtual void initialiseSocketCan()
!< Attempts to set a new CAN filter mask to the BIOS
Definition: CanDriver.cpp:243
virtual ~CanDriver()
Definition: CanDriver.hpp:72
virtual int32_t sendMessage(const CanMessage message, bool forceExtended=false)
!< Attempts to read a single message from the bus
Definition: CanDriver.cpp:153
const CanId getDefaultSenderId() const
!< Sets the default sender ID
Definition: CanDriver.hpp:77
virtual void setCanFilterMask(const int32_t mask)
!< Attempts to read all queued messages from the bus
Definition: CanDriver.cpp:217
virtual void uninitialiseSocketCan()
!< Initialises socketcan
Definition: CanDriver.cpp:284
static const int32_t CAN_MAX_DATA_LENGTH
Definition: CanDriver.hpp:64
Represents a CAN message that was received.
Definition: CanMessage.hpp:55
const string getFrameData() const
Definition: CanMessage.hpp:77
const can_frame getRawFrame() const
Definition: CanMessage.hpp:78
CanMessage(const struct can_frame frame)
Definition: CanMessage.hpp:57
const CanId getCanId() const
Definition: CanMessage.hpp:76
CanException(string message, int32_t socket)
InvalidSocketException(string message, int32_t socket)
Main library namespace.
Definition: CanDriver.cpp:57
string formatString(const string &format, Args... args)
Formats a std string object.
Definition: CanDriver.hpp:131
Represents a CAN ID in a simple and easy-to-use manner.
Definition: CanId.hpp:48
CanId operator+(const uint32_t x) const
Definition: CanId.hpp:156
operator uint16_t() const
Definition: CanId.hpp:74
bool operator!=(const CanId &x) const
Definition: CanId.hpp:109
CanId operator|(const int64_t x) const
Definition: CanId.hpp:95
CanId operator-(const int32_t x) const
Definition: CanId.hpp:164
CanId operator-(CanId &x) const
Definition: CanId.hpp:160
bool operator<(const CanId &x) const
Definition: CanId.hpp:129
CanId operator|(const int16_t x) const
Definition: CanId.hpp:91
bool operator!=(const int32_t x) const
Definition: CanId.hpp:112
bool _isExtendedFrameId
Definition: CanId.hpp:230
CanId operator|(const CanId x) const
Definition: CanId.hpp:90
bool operator>(uint32_t x) const
Definition: CanId.hpp:125
CanId operator&(const uint32_t x) const
Definition: CanId.hpp:85
CanId operator+(const uint64_t x) const
Definition: CanId.hpp:158
bool operator==(const int16_t x) const
Definition: CanId.hpp:102
bool operator==(const CanId &x) const
Definition: CanId.hpp:101
CanId(const CanId &orig)
Definition: CanId.hpp:50
bool operator!=(const int64_t x) const
Definition: CanId.hpp:114
bool operator<(int16_t x) const
Definition: CanId.hpp:120
bool _isRemoteTransmissionRequest
Definition: CanId.hpp:228
CanId operator|(const uint16_t x) const
Definition: CanId.hpp:92
CanId operator&(const int32_t x) const
Definition: CanId.hpp:84
bool operator!=(const uint16_t x) const
Definition: CanId.hpp:111
bool operator>(const CanId &x) const
Definition: CanId.hpp:131
uint32_t _identifier
Definition: CanId.hpp:232
bool operator<=(const CanId &x) const
Definition: CanId.hpp:130
CanId operator&(const uint64_t x) const
Definition: CanId.hpp:87
CanId operator|(const uint64_t x) const
Definition: CanId.hpp:96
CanId operator+(const int64_t x) const
Definition: CanId.hpp:157
CanId(const uint32_t identifier)
Definition: CanId.hpp:54
bool operator==(CanId &x) const
Definition: CanId.hpp:100
CanId operator|(const uint32_t x) const
Definition: CanId.hpp:94
bool hasRtrFrameFlag() const
Definition: CanId.hpp:219
CanId operator-(const CanId &x) const
Definition: CanId.hpp:161
static bool isRemoteTransmissionRequest(uint32_t value)
Indicates whether the received frame is a remote transmission request.
Definition: CanId.hpp:212
static bool isErrorFrame(uint32_t value)
Indicates whether or not a given integer contains the error frame flag or not.
Definition: CanId.hpp:199
CanId operator&(CanId &x) const
Definition: CanId.hpp:80
CanId operator&(const int64_t x) const
Definition: CanId.hpp:86
CanId operator+(const int16_t x) const
Definition: CanId.hpp:153
bool operator<(CanId &x) const
Definition: CanId.hpp:117
CanId operator+(const int32_t x) const
Definition: CanId.hpp:155
operator uint32_t() const
Definition: CanId.hpp:76
CanId operator-(const uint32_t x) const
Definition: CanId.hpp:165
CanId operator&(const uint16_t x) const
Definition: CanId.hpp:83
bool operator==(const uint64_t x) const
Definition: CanId.hpp:107
bool equals(CanId otherId) const
Definition: CanId.hpp:224
CanId operator-(const uint16_t x) const
Definition: CanId.hpp:163
CanId operator+(CanId &x) const
Definition: CanId.hpp:151
CanId operator|(CanId &x) const
Definition: CanId.hpp:89
bool operator==(const uint16_t x) const
Definition: CanId.hpp:103
CanId operator|(const int32_t x) const
Definition: CanId.hpp:93
CanId operator+(const uint16_t x) const
Definition: CanId.hpp:154
bool operator>(CanId &x) const
Definition: CanId.hpp:123
bool operator>=(const CanId &x) const
Definition: CanId.hpp:132
bool operator==(const int32_t x) const
Definition: CanId.hpp:104
bool _isErrorFrame
Definition: CanId.hpp:227
CanId operator+(const CanId &x) const
Definition: CanId.hpp:152
bool _isStandardFrameId
Definition: CanId.hpp:229
bool operator>(int32_t x) const
Definition: CanId.hpp:124
CanId operator&(const int16_t x) const
Definition: CanId.hpp:82
operator int16_t() const
Definition: CanId.hpp:73
CanId operator=(const int32_t val)
Definition: CanId.hpp:136
bool operator<=(CanId &x) const
Definition: CanId.hpp:122
bool operator>=(CanId &x) const
Definition: CanId.hpp:128
CanId operator-(const uint64_t x) const
Definition: CanId.hpp:167
bool operator!=(const int16_t x) const
Definition: CanId.hpp:110
bool operator==(const int64_t x) const
Definition: CanId.hpp:106
CanId operator&(const CanId x) const
Definition: CanId.hpp:81
bool operator!=(const uint32_t x) const
Definition: CanId.hpp:113
bool operator>(uint16_t x) const
Definition: CanId.hpp:127
bool operator<(uint16_t x) const
Definition: CanId.hpp:121
bool hasErrorFrameFlag() const
Definition: CanId.hpp:218
CanId operator=(const uint32_t val)
Definition: CanId.hpp:142
bool operator==(const uint32_t x) const
Definition: CanId.hpp:105
operator int32_t() const
Definition: CanId.hpp:75
CanId operator-(const int64_t x) const
Definition: CanId.hpp:166
bool operator<(int32_t x) const
Definition: CanId.hpp:118
bool operator<(uint32_t x) const
Definition: CanId.hpp:119
CanId operator-(const int16_t x) const
Definition: CanId.hpp:162
static bool isValidIdentifier(uint32_t value)
Indicates whether or not a given integer is a valid CAN identifier.
Definition: CanId.hpp:179
bool operator!=(CanId &x) const
Definition: CanId.hpp:108
bool isStandardFrameId() const
Definition: CanId.hpp:220
bool operator>(int16_t x) const
Definition: CanId.hpp:126
bool operator!=(const uint64_t x) const
Definition: CanId.hpp:115
CanId operator=(const int64_t val)
Definition: CanId.hpp:147
bool isExtendedFrameId() const
Definition: CanId.hpp:221