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