Lely core libraries  1.9.2
socket.c
Go to the documentation of this file.
1 
24 #include "can.h"
25 
26 #ifdef LELY_HAVE_SOCKET_CAN
27 
28 #include <lely/can/socket.h>
29 #include <lely/util/errnum.h>
30 #include <lely/util/util.h>
31 
32 #include <assert.h>
33 #include <string.h>
34 
35 #ifdef HAVE_LINUX_CAN_H
36 #include <linux/can.h>
37 #endif
38 #ifdef HAVE_LINUX_CAN_ERROR_H
39 #include <linux/can/error.h>
40 #endif
41 
42 int
43 can_frame_is_error(const struct can_frame *frame, enum can_state *pstate,
44  enum can_error *perror)
45 {
46  assert(frame);
47 
48  if (!(frame->can_id & CAN_ERR_FLAG))
49  return 0;
50 
51  enum can_state state = pstate ? *pstate : CAN_STATE_ACTIVE;
52  enum can_error error = perror ? *perror : 0;
53 
54 #ifdef HAVE_LINUX_CAN_ERROR_H
55  if (frame->can_dlc != CAN_ERR_DLC) {
57  return -1;
58  }
59 
60  if (frame->can_id & CAN_ERR_RESTARTED)
61  state = CAN_STATE_ACTIVE;
62 
63  if (frame->can_id & CAN_ERR_TX_TIMEOUT)
64  error |= CAN_ERROR_OTHER;
65 
66  if (frame->can_id & CAN_ERR_CRTL) {
67 #ifdef CAN_ERR_CRTL_ACTIVE
68  if (frame->data[1] & CAN_ERR_CRTL_ACTIVE)
69  state = CAN_STATE_ACTIVE;
70 #endif
71  // clang-format off
72  if (frame->data[1] & (CAN_ERR_CRTL_RX_PASSIVE
73  | CAN_ERR_CRTL_TX_PASSIVE))
74  // clang-format on
75  state = CAN_STATE_PASSIVE;
76  }
77 
78  if (frame->can_id & CAN_ERR_PROT) {
79  if (frame->data[2] & CAN_ERR_PROT_BIT)
80  error |= CAN_ERROR_BIT;
81  if (frame->data[2] & CAN_ERR_PROT_FORM)
82  error |= CAN_ERROR_FORM;
83  if (frame->data[2] & CAN_ERR_PROT_STUFF)
84  error |= CAN_ERROR_STUFF;
85  // clang-format off
86  if (frame->data[2] & (CAN_ERR_PROT_BIT0 | CAN_ERR_PROT_BIT1
87  | CAN_ERR_PROT_OVERLOAD))
88  // clang-format on
89  error |= CAN_ERROR_OTHER;
90  if (frame->data[2] & CAN_ERR_PROT_ACTIVE)
91  state = CAN_STATE_ACTIVE;
92  if (frame->data[3] & CAN_ERR_PROT_LOC_CRC_SEQ)
93  error |= CAN_ERROR_CRC;
94  }
95 
96  if ((frame->can_id & CAN_ERR_TRX) && frame->data[4])
97  error |= CAN_ERROR_OTHER;
98 
99  if (frame->can_id & CAN_ERR_ACK)
100  error |= CAN_ERROR_ACK;
101 
102  if (frame->can_id & CAN_ERR_BUSOFF)
103  state = CAN_STATE_BUSOFF;
104 #endif // HAVE_LINUX_CAN_ERROR_H
105 
106  if (pstate)
107  *pstate = state;
108 
109  if (perror)
110  *perror = error;
111 
112  return 1;
113 }
114 
115 int
116 can_frame2can_msg(const struct can_frame *src, struct can_msg *dst)
117 {
118  assert(src);
119  assert(dst);
120 
121  if (src->can_id & CAN_ERR_FLAG) {
123  return -1;
124  }
125 
126  memset(dst, 0, sizeof(*dst));
127  dst->flags = 0;
128  if (src->can_id & CAN_EFF_FLAG) {
129  dst->id = src->can_id & CAN_EFF_MASK;
130  dst->flags |= CAN_FLAG_IDE;
131  } else {
132  dst->id = src->can_id & CAN_SFF_MASK;
133  }
134  if (src->can_id & CAN_RTR_FLAG)
135  dst->flags |= CAN_FLAG_RTR;
136  dst->len = MIN(src->can_dlc, CAN_MAX_LEN);
137  if (!(dst->flags & CAN_FLAG_RTR))
138  memcpy(dst->data, src->data, dst->len);
139 
140  return 0;
141 }
142 
143 int
144 can_msg2can_frame(const struct can_msg *src, struct can_frame *dst)
145 {
146  assert(src);
147  assert(dst);
148 
149 #ifndef LELY_NO_CANFD
150  if (src->flags & CAN_FLAG_EDL) {
152  return -1;
153  }
154 #endif
155 
156  memset(dst, 0, sizeof(*dst));
157  dst->can_id = src->id;
158  if (src->flags & CAN_FLAG_IDE) {
159  dst->can_id &= CAN_EFF_MASK;
160  dst->can_id |= CAN_EFF_FLAG;
161  } else {
162  dst->can_id &= CAN_SFF_MASK;
163  }
164  dst->can_dlc = MIN(src->len, CAN_MAX_LEN);
165  if (src->flags & CAN_FLAG_RTR)
166  dst->can_id |= CAN_RTR_FLAG;
167  else
168  memcpy(dst->data, src->data, dst->can_dlc);
169 
170  return 0;
171 }
172 
173 #if !defined(LELY_NO_CANFD) && defined(CANFD_MTU)
174 
175 int
176 canfd_frame2can_msg(const struct canfd_frame *src, struct can_msg *dst)
177 {
178  assert(src);
179  assert(dst);
180 
181  if (src->can_id & CAN_ERR_FLAG) {
183  return -1;
184  }
185 
186  memset(dst, 0, sizeof(*dst));
187  dst->flags = CAN_FLAG_EDL;
188  if (src->can_id & CAN_EFF_FLAG) {
189  dst->id = src->can_id & CAN_EFF_MASK;
190  dst->flags |= CAN_FLAG_IDE;
191  } else {
192  dst->id = src->can_id & CAN_SFF_MASK;
193  }
194  if (src->flags & CANFD_BRS)
195  dst->flags |= CAN_FLAG_BRS;
196  if (src->flags & CANFD_ESI)
197  dst->flags |= CAN_FLAG_ESI;
198  dst->len = MIN(src->len, CANFD_MAX_LEN);
199  memcpy(dst->data, src->data, dst->len);
200 
201  return 0;
202 }
203 
204 int
205 can_msg2canfd_frame(const struct can_msg *src, struct canfd_frame *dst)
206 {
207  assert(src);
208  assert(dst);
209 
210  if (!(src->flags & CAN_FLAG_EDL)) {
212  return -1;
213  }
214 
215  memset(dst, 0, sizeof(*dst));
216  dst->can_id = src->id;
217  if (src->flags & CAN_FLAG_IDE) {
218  dst->can_id &= CAN_EFF_MASK;
219  dst->can_id |= CAN_EFF_FLAG;
220  } else {
221  dst->can_id &= CAN_SFF_MASK;
222  }
223  dst->flags = 0;
224  if (src->flags & CAN_FLAG_BRS)
225  dst->flags |= CANFD_BRS;
226  if (src->flags & CAN_FLAG_ESI)
227  dst->flags |= CANFD_ESI;
228  dst->len = MIN(src->len, CANFD_MAX_LEN);
229  memcpy(dst->data, src->data, dst->len);
230 
231  return 0;
232 }
233 
234 #endif // !LELY_NO_CANFD && CANFD_MTU
235 
236 #endif // LELY_HAVE_SOCKET_CAN
int can_msg2can_frame(const struct can_msg *src, struct can_frame *dst)
Converts a can_msg frame to a SocketCAN CAN frame.
Definition: socket.c:144
A CAN or CAN FD format frame.
Definition: msg.h:88
uint_least32_t id
The identifier (11 or 29 bits, depending on the CAN_FLAG_IDE flag).
Definition: msg.h:90
#define CAN_FLAG_ESI
The Error State Indicator (ESI) flag (only available in CAN FD format frames).
Definition: msg.h:68
A bit stuffing error.
Definition: can.h:41
uint_least8_t len
The number of bytes in data (or the requested number of bytes in case of a remote frame)...
Definition: msg.h:101
This header file is part of the C11 and POSIX compatibility library; it includes <string.h> and defines any missing functionality.
int canfd_frame2can_msg(const struct canfd_frame *src, struct can_msg *dst)
Converts a SocketCAN CAN FD frame to a can_msg frame.
A form error.
Definition: can.h:45
void set_errnum(errnum_t errnum)
Sets the current (thread-specific) platform-independent error number to errnum.
Definition: errnum.h:375
can_state
The states of a CAN node, depending on the TX/RX error count.
Definition: can.h:27
The error passive state (TX/RX error count < 256).
Definition: can.h:31
#define MIN(a, b)
Returns the minimum of a and b.
Definition: util.h:57
#define CANFD_MAX_LEN
The maximum number of bytes in the payload of a CAN FD format frame.
Definition: msg.h:77
int can_frame_is_error(const struct can_frame *frame, enum can_state *pstate, enum can_error *perror)
Checks if a SocketCAN CAN frame is an error frame and parses the bus state and error flags if it is...
Definition: socket.c:43
uint_least8_t data[CAN_MSG_MAX_LEN]
The frame payload (in case of a data frame).
Definition: msg.h:103
This is the internal header file of the CAN library.
This header file is part of the utilities library; it contains the native and platform-independent er...
#define CAN_FLAG_IDE
The Identifier Extension (IDE) flag.
Definition: msg.h:41
#define CAN_FLAG_EDL
The Extended Data Length (EDL) flag.
Definition: msg.h:55
The bus off state (TX/RX error count >= 256).
Definition: can.h:33
int can_msg2canfd_frame(const struct can_msg *src, struct canfd_frame *dst)
Converts a can_msg frame to a SocketCAN CAN FD frame.
The error active state (TX/RX error count < 128).
Definition: can.h:29
int can_frame2can_msg(const struct can_frame *src, struct can_msg *dst)
Converts a SocketCAN CAN frame to a can_msg frame.
Definition: socket.c:116
Invalid argument.
Definition: errnum.h:129
uint_least8_t flags
The flags (any combination of CAN_FLAG_IDE, CAN_FLAG_RTR, CAN_FLAG_EDL, CAN_FLAG_BRS and CAN_FLAG_ESI...
Definition: msg.h:95
#define CAN_FLAG_BRS
The Bit Rate Switch (BRS) flag (only available in CAN FD format frames).
Definition: msg.h:62
An acknowledgment error.
Definition: can.h:47
#define CAN_FLAG_RTR
The Remote Transmission Request (RTR) flag (unavailable in CAN FD format frames). ...
Definition: msg.h:47
One or more other errors.
Definition: can.h:49
A CRC sequence error.
Definition: can.h:43
#define CAN_MAX_LEN
The maximum number of bytes in the payload of a CAN format frame.
Definition: msg.h:73
This header file is part of the CAN library; it contains the SocketCAN interface declarations.
A single bit error.
Definition: can.h:39
can_error
The error flags of a CAN bus, which are not mutually exclusive.
Definition: can.h:37
This is the public header file of the utilities library.