1 /** @file
2 * @brief SocketCAN utilities.
3 *
4 * Utilities for SocketCAN support.
5 */
6
7 /*
8 * Copyright (c) 2019 Intel Corporation
9 *
10 * SPDX-License-Identifier: Apache-2.0
11 */
12
13 #ifndef ZEPHYR_INCLUDE_NET_SOCKETCAN_UTILS_H_
14 #define ZEPHYR_INCLUDE_NET_SOCKETCAN_UTILS_H_
15
16 #include <zephyr/drivers/can.h>
17 #include <zephyr/net/socketcan.h>
18
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
22
23 /**
24 * @brief SocketCAN utilities
25 * @defgroup socket_can Network Core Library
26 * @ingroup networking
27 * @{
28 */
29
30 /**
31 * @brief Translate a @a socketcan_frame struct to a @a can_frame struct.
32 *
33 * @param sframe Pointer to sockecan_frame struct.
34 * @param zframe Pointer to can_frame struct.
35 */
socketcan_to_can_frame(const struct socketcan_frame * sframe,struct can_frame * zframe)36 static inline void socketcan_to_can_frame(const struct socketcan_frame *sframe,
37 struct can_frame *zframe)
38 {
39 memset(zframe, 0, sizeof(*zframe));
40
41 zframe->flags |= (sframe->can_id & BIT(31)) != 0 ? CAN_FRAME_IDE : 0;
42 zframe->flags |= (sframe->can_id & BIT(30)) != 0 ? CAN_FRAME_RTR : 0;
43 zframe->flags |= (sframe->flags & CANFD_FDF) != 0 ? CAN_FRAME_FDF : 0;
44 zframe->flags |= (sframe->flags & CANFD_BRS) != 0 ? CAN_FRAME_BRS : 0;
45 zframe->id = sframe->can_id & BIT_MASK(29);
46 zframe->dlc = can_bytes_to_dlc(sframe->len);
47
48 if ((zframe->flags & CAN_FRAME_RTR) == 0U) {
49 memcpy(zframe->data, sframe->data,
50 MIN(sframe->len, MIN(sizeof(sframe->data), sizeof(zframe->data))));
51 }
52 }
53
54 /**
55 * @brief Translate a @a can_frame struct to a @a socketcan_frame struct.
56 *
57 * @param zframe Pointer to can_frame struct.
58 * @param sframe Pointer to socketcan_frame struct.
59 */
socketcan_from_can_frame(const struct can_frame * zframe,struct socketcan_frame * sframe)60 static inline void socketcan_from_can_frame(const struct can_frame *zframe,
61 struct socketcan_frame *sframe)
62 {
63 memset(sframe, 0, sizeof(*sframe));
64
65 sframe->can_id = zframe->id;
66 sframe->can_id |= (zframe->flags & CAN_FRAME_IDE) != 0 ? BIT(31) : 0;
67 sframe->can_id |= (zframe->flags & CAN_FRAME_RTR) != 0 ? BIT(30) : 0;
68 sframe->len = can_dlc_to_bytes(zframe->dlc);
69
70 if ((zframe->flags & CAN_FRAME_FDF) != 0) {
71 sframe->flags |= CANFD_FDF;
72 }
73
74 if ((zframe->flags & CAN_FRAME_BRS) != 0) {
75 sframe->flags |= CANFD_BRS;
76 }
77
78 if ((zframe->flags & CAN_FRAME_RTR) == 0U) {
79 memcpy(sframe->data, zframe->data,
80 MIN(sframe->len, MIN(sizeof(zframe->data), sizeof(sframe->data))));
81 }
82 }
83
84 /**
85 * @brief Translate a @a socketcan_filter struct to a @a can_filter struct.
86 *
87 * @param sfilter Pointer to socketcan_filter struct.
88 * @param zfilter Pointer to can_filter struct.
89 */
socketcan_to_can_filter(const struct socketcan_filter * sfilter,struct can_filter * zfilter)90 static inline void socketcan_to_can_filter(const struct socketcan_filter *sfilter,
91 struct can_filter *zfilter)
92 {
93 memset(zfilter, 0, sizeof(*zfilter));
94
95 zfilter->flags |= (sfilter->can_id & BIT(31)) != 0 ? CAN_FILTER_IDE : 0;
96 zfilter->id = sfilter->can_id & BIT_MASK(29);
97 zfilter->mask = sfilter->can_mask & BIT_MASK(29);
98 zfilter->flags |= (sfilter->flags & CANFD_FDF) != 0 ? CAN_FILTER_FDF : 0;
99
100 if ((sfilter->can_mask & BIT(30)) == 0) {
101 zfilter->flags |= CAN_FILTER_DATA | CAN_FILTER_RTR;
102 } else if ((sfilter->can_id & BIT(30)) == 0) {
103 zfilter->flags |= CAN_FILTER_DATA;
104 } else {
105 zfilter->flags |= CAN_FILTER_RTR;
106 }
107 }
108
109 /**
110 * @brief Translate a @a can_filter struct to a @a socketcan_filter struct.
111 *
112 * @param zfilter Pointer to can_filter struct.
113 * @param sfilter Pointer to socketcan_filter struct.
114 */
socketcan_from_can_filter(const struct can_filter * zfilter,struct socketcan_filter * sfilter)115 static inline void socketcan_from_can_filter(const struct can_filter *zfilter,
116 struct socketcan_filter *sfilter)
117 {
118 memset(sfilter, 0, sizeof(*sfilter));
119
120 sfilter->can_id = zfilter->id;
121 sfilter->can_id |= (zfilter->flags & CAN_FILTER_IDE) != 0 ? BIT(31) : 0;
122 sfilter->can_id |= (zfilter->flags & CAN_FILTER_RTR) != 0 ? BIT(30) : 0;
123
124 sfilter->can_mask = zfilter->mask;
125 sfilter->can_mask |= (zfilter->flags & CAN_FILTER_IDE) != 0 ? BIT(31) : 0;
126
127 if ((zfilter->flags & (CAN_FILTER_DATA | CAN_FILTER_RTR)) !=
128 (CAN_FILTER_DATA | CAN_FILTER_RTR)) {
129 sfilter->can_mask |= BIT(30);
130 }
131
132 if ((zfilter->flags & CAN_FILTER_FDF) != 0) {
133 sfilter->flags |= CANFD_FDF;
134 }
135 }
136
137 /**
138 * @}
139 */
140
141 #ifdef __cplusplus
142 }
143 #endif
144
145 #endif /* ZEPHYR_INCLUDE_NET_SOCKETCAN_H_ */
146