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 * @addtogroup socket_can
26 * @{
27 */
28
29 /**
30 * @brief Translate a @a socketcan_frame struct to a @a can_frame struct.
31 *
32 * @param sframe Pointer to sockecan_frame struct.
33 * @param zframe Pointer to can_frame struct.
34 */
socketcan_to_can_frame(const struct socketcan_frame * sframe,struct can_frame * zframe)35 static inline void socketcan_to_can_frame(const struct socketcan_frame *sframe,
36 struct can_frame *zframe)
37 {
38 memset(zframe, 0, sizeof(*zframe));
39
40 zframe->flags |= (sframe->can_id & BIT(31)) != 0 ? CAN_FRAME_IDE : 0;
41 zframe->flags |= (sframe->can_id & BIT(30)) != 0 ? CAN_FRAME_RTR : 0;
42 zframe->flags |= (sframe->flags & CANFD_FDF) != 0 ? CAN_FRAME_FDF : 0;
43 zframe->flags |= (sframe->flags & CANFD_BRS) != 0 ? CAN_FRAME_BRS : 0;
44 zframe->id = sframe->can_id & BIT_MASK(29);
45 zframe->dlc = can_bytes_to_dlc(sframe->len);
46
47 if ((zframe->flags & CAN_FRAME_RTR) == 0U) {
48 memcpy(zframe->data, sframe->data,
49 MIN(sframe->len, MIN(sizeof(sframe->data), sizeof(zframe->data))));
50 }
51 }
52
53 /**
54 * @brief Translate a @a can_frame struct to a @a socketcan_frame struct.
55 *
56 * @param zframe Pointer to can_frame struct.
57 * @param sframe Pointer to socketcan_frame struct.
58 */
socketcan_from_can_frame(const struct can_frame * zframe,struct socketcan_frame * sframe)59 static inline void socketcan_from_can_frame(const struct can_frame *zframe,
60 struct socketcan_frame *sframe)
61 {
62 memset(sframe, 0, sizeof(*sframe));
63
64 sframe->can_id = zframe->id;
65 sframe->can_id |= (zframe->flags & CAN_FRAME_IDE) != 0 ? BIT(31) : 0;
66 sframe->can_id |= (zframe->flags & CAN_FRAME_RTR) != 0 ? BIT(30) : 0;
67 sframe->len = can_dlc_to_bytes(zframe->dlc);
68
69 if ((zframe->flags & CAN_FRAME_FDF) != 0) {
70 sframe->flags |= CANFD_FDF;
71 }
72
73 if ((zframe->flags & CAN_FRAME_BRS) != 0) {
74 sframe->flags |= CANFD_BRS;
75 }
76
77 if ((zframe->flags & CAN_FRAME_RTR) == 0U) {
78 memcpy(sframe->data, zframe->data,
79 MIN(sframe->len, MIN(sizeof(zframe->data), sizeof(sframe->data))));
80 }
81 }
82
83 /**
84 * @brief Translate a @a socketcan_filter struct to a @a can_filter struct.
85 *
86 * @param sfilter Pointer to socketcan_filter struct.
87 * @param zfilter Pointer to can_filter struct.
88 */
socketcan_to_can_filter(const struct socketcan_filter * sfilter,struct can_filter * zfilter)89 static inline void socketcan_to_can_filter(const struct socketcan_filter *sfilter,
90 struct can_filter *zfilter)
91 {
92 memset(zfilter, 0, sizeof(*zfilter));
93
94 zfilter->flags |= (sfilter->can_id & BIT(31)) != 0 ? CAN_FILTER_IDE : 0;
95 zfilter->id = sfilter->can_id & BIT_MASK(29);
96 zfilter->mask = sfilter->can_mask & BIT_MASK(29);
97 }
98
99 /**
100 * @brief Translate a @a can_filter struct to a @a socketcan_filter struct.
101 *
102 * @param zfilter Pointer to can_filter struct.
103 * @param sfilter Pointer to socketcan_filter struct.
104 */
socketcan_from_can_filter(const struct can_filter * zfilter,struct socketcan_filter * sfilter)105 static inline void socketcan_from_can_filter(const struct can_filter *zfilter,
106 struct socketcan_filter *sfilter)
107 {
108 memset(sfilter, 0, sizeof(*sfilter));
109
110 sfilter->can_id = zfilter->id;
111 sfilter->can_id |= (zfilter->flags & CAN_FILTER_IDE) != 0 ? BIT(31) : 0;
112
113 sfilter->can_mask = zfilter->mask;
114 sfilter->can_mask |= (zfilter->flags & CAN_FILTER_IDE) != 0 ? BIT(31) : 0;
115
116 if (!IS_ENABLED(CONFIG_CAN_ACCEPT_RTR)) {
117 sfilter->can_mask |= BIT(30);
118 }
119 }
120
121 /**
122 * @}
123 */
124
125 #ifdef __cplusplus
126 }
127 #endif
128
129 #endif /* ZEPHYR_INCLUDE_NET_SOCKETCAN_H_ */
130