Lely core libraries  2.2.5
can_msg.h
Go to the documentation of this file.
1 
22 #ifndef LELY_IO2_INTERN_LINUX_CAN_MSG_H_
23 #define LELY_IO2_INTERN_LINUX_CAN_MSG_H_
24 
25 #include "io.h"
26 
27 #ifdef __linux__
28 
29 #include <lely/io2/can/msg.h>
30 
31 #include <assert.h>
32 #include <errno.h>
33 #include <string.h>
34 
35 #include <linux/can.h>
36 
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40 
41 static int can_frame2can_msg(const struct can_frame *src, struct can_msg *dst);
42 static int can_msg2can_frame(const struct can_msg *src, struct can_frame *dst);
43 #if !LELY_NO_CANFD
44 static int canfd_frame2can_msg(
45  const struct canfd_frame *src, struct can_msg *dst);
46 static int can_msg2canfd_frame(
47  const struct can_msg *src, struct canfd_frame *dst);
48 #endif
49 
50 static inline int
51 can_frame2can_msg(const struct can_frame *src, struct can_msg *dst)
52 {
53  assert(src);
54  assert(dst);
55 
56  if (src->can_id & CAN_ERR_FLAG) {
57  errno = EINVAL;
58  return -1;
59  }
60 
61  memset(dst, 0, sizeof(*dst));
62  dst->flags = 0;
63  if (src->can_id & CAN_EFF_FLAG) {
64  dst->id = src->can_id & CAN_EFF_MASK;
65  dst->flags |= CAN_FLAG_IDE;
66  } else {
67  dst->id = src->can_id & CAN_SFF_MASK;
68  }
69  if (src->can_id & CAN_RTR_FLAG)
70  dst->flags |= CAN_FLAG_RTR;
71  dst->len = MIN(src->can_dlc, CAN_MAX_LEN);
72  // cppcheck-suppress knownConditionTrueFalse
73  if (!(dst->flags & CAN_FLAG_RTR))
74  memcpy(dst->data, src->data, dst->len);
75 
76  return 0;
77 }
78 
79 static inline int
80 can_msg2can_frame(const struct can_msg *src, struct can_frame *dst)
81 {
82  assert(src);
83  assert(dst);
84 
85 #if !LELY_NO_CANFD
86  if (src->flags & CAN_FLAG_FDF) {
87  errno = EINVAL;
88  return -1;
89  }
90 #endif
91 
92  memset(dst, 0, sizeof(*dst));
93  dst->can_id = src->id;
94  if (src->flags & CAN_FLAG_IDE) {
95  dst->can_id &= CAN_EFF_MASK;
96  dst->can_id |= CAN_EFF_FLAG;
97  } else {
98  dst->can_id &= CAN_SFF_MASK;
99  }
100  dst->can_dlc = MIN(src->len, CAN_MAX_LEN);
101  if (src->flags & CAN_FLAG_RTR)
102  dst->can_id |= CAN_RTR_FLAG;
103  else
104  memcpy(dst->data, src->data, dst->can_dlc);
105 
106  return 0;
107 }
108 
109 #if !LELY_NO_CANFD
110 
111 static inline int
112 canfd_frame2can_msg(const struct canfd_frame *src, struct can_msg *dst)
113 {
114  assert(src);
115  assert(dst);
116 
117  if (src->can_id & CAN_ERR_FLAG) {
118  errno = EINVAL;
119  return -1;
120  }
121 
122  memset(dst, 0, sizeof(*dst));
123  dst->flags = CAN_FLAG_FDF;
124  if (src->can_id & CAN_EFF_FLAG) {
125  dst->id = src->can_id & CAN_EFF_MASK;
126  dst->flags |= CAN_FLAG_IDE;
127  } else {
128  dst->id = src->can_id & CAN_SFF_MASK;
129  }
130  if (src->flags & CANFD_BRS)
131  dst->flags |= CAN_FLAG_BRS;
132  if (src->flags & CANFD_ESI)
133  dst->flags |= CAN_FLAG_ESI;
134  dst->len = MIN(src->len, CANFD_MAX_LEN);
135  memcpy(dst->data, src->data, dst->len);
136 
137  return 0;
138 }
139 
140 static inline int
141 can_msg2canfd_frame(const struct can_msg *src, struct canfd_frame *dst)
142 {
143  assert(src);
144  assert(dst);
145 
146  if (!(src->flags & CAN_FLAG_FDF)) {
147  errno = EINVAL;
148  return -1;
149  }
150 
151  memset(dst, 0, sizeof(*dst));
152  dst->can_id = src->id;
153  if (src->flags & CAN_FLAG_IDE) {
154  dst->can_id &= CAN_EFF_MASK;
155  dst->can_id |= CAN_EFF_FLAG;
156  } else {
157  dst->can_id &= CAN_SFF_MASK;
158  }
159  dst->flags = 0;
160  if (src->flags & CAN_FLAG_BRS)
161  dst->flags |= CANFD_BRS;
162  if (src->flags & CAN_FLAG_ESI)
163  dst->flags |= CANFD_ESI;
164  dst->len = MIN(src->len, CANFD_MAX_LEN);
165  memcpy(dst->data, src->data, dst->len);
166 
167  return 0;
168 }
169 
170 #endif // !LELY_NO_CANFD
171 
172 #ifdef __cplusplus
173 }
174 #endif
175 
176 #endif // __linux__
177 
178 #endif // !LELY_IO2_INTERN_LINUX_CAN_MSG_H_
@ CAN_FLAG_IDE
The Identifier Extension (IDE) flag.
Definition: msg.h:43
@ CAN_FLAG_RTR
The Remote Transmission Request (RTR) flag (unavailable in CAN FD format frames).
Definition: msg.h:48
@ CAN_FLAG_FDF
The FD Format (FDF) flag, formerly known as Extended Data Length (EDL).
Definition: msg.h:54
@ CAN_FLAG_BRS
The Bit Rate Switch (BRS) flag (only available in CAN FD format frames).
Definition: msg.h:62
@ CAN_FLAG_ESI
The Error State Indicator (ESI) flag (only available in CAN FD format frames).
Definition: msg.h:67
#define CAN_MAX_LEN
The maximum number of bytes in the payload of a CAN format frame.
Definition: msg.h:72
#define CANFD_MAX_LEN
The maximum number of bytes in the payload of a CAN FD format frame.
Definition: msg.h:76
This header file is part of the I/O library; it contains the CAN bus declarations for Linux.
#define MIN(a, b)
Returns the minimum of a and b.
Definition: util.h:57
This header file is part of the I/O library; it contains the CAN frame declarations.
int can_msg2canfd_frame(const struct can_msg *src, struct canfd_frame *dst)
Converts a can_msg frame to a SocketCAN CAN FD frame.
Definition: can_msg.h:141
int can_frame2can_msg(const struct can_frame *src, struct can_msg *dst)
Converts a SocketCAN CAN frame to a can_msg frame.
Definition: can_msg.h:51
int canfd_frame2can_msg(const struct canfd_frame *src, struct can_msg *dst)
Converts a SocketCAN CAN FD frame to a can_msg frame.
Definition: can_msg.h:112
int can_msg2can_frame(const struct can_msg *src, struct can_frame *dst)
Converts a can_msg frame to a SocketCAN CAN frame.
Definition: can_msg.h:80
This is the internal header file of the Windows-specific I/O declarations.
This header file is part of the C11 and POSIX compatibility library; it includes <string....
A CAN or CAN FD format frame.
Definition: msg.h:87
uint_least8_t data[CAN_MSG_MAX_LEN]
The frame payload (in case of a data frame).
Definition: msg.h:102
uint_least32_t id
The identifier (11 or 29 bits, depending on the CAN_FLAG_IDE flag).
Definition: msg.h:89
uint_least8_t flags
The flags (any combination of CAN_FLAG_IDE, CAN_FLAG_RTR, CAN_FLAG_FDF, CAN_FLAG_BRS and CAN_FLAG_ESI...
Definition: msg.h:94
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:100