Lely core libraries 2.3.4
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
38extern "C" {
39#endif
40
41static int can_frame2can_msg(const struct can_frame *src, struct can_msg *dst);
42static int can_msg2can_frame(const struct can_msg *src, struct can_frame *dst);
43#if !LELY_NO_CANFD
44static int canfd_frame2can_msg(
45 const struct canfd_frame *src, struct can_msg *dst);
46static int can_msg2canfd_frame(
47 const struct can_msg *src, struct canfd_frame *dst);
48#endif
49
50static inline int
51can_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
79static inline int
80can_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
111static inline int
112canfd_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
140static inline int
141can_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