Line data Source code
1 1 : /*
2 : * Copyright (c) 2016 Intel Corporation.
3 : * Copyright (c) 2022 Florian Grandel.
4 : *
5 : * SPDX-License-Identifier: Apache-2.0
6 : */
7 :
8 : /**
9 : * @file
10 : * @brief Packet data common to all IEEE 802.15.4 L2 layers
11 : *
12 : * All references to the spec refer to IEEE 802.15.4-2020.
13 : */
14 :
15 : #ifndef ZEPHYR_INCLUDE_NET_IEEE802154_PKT_H_
16 : #define ZEPHYR_INCLUDE_NET_IEEE802154_PKT_H_
17 :
18 : #include <string.h>
19 :
20 : #include <zephyr/types.h>
21 :
22 : #ifdef __cplusplus
23 : extern "C" {
24 : #endif
25 :
26 : /** @cond ignore */
27 :
28 : #ifndef NET_PKT_HAS_CONTROL_BLOCK
29 : #define NET_PKT_HAS_CONTROL_BLOCK
30 : #endif
31 :
32 : /* See section 6.16.2.8 - Received Signal Strength Indicator (RSSI) */
33 : #define IEEE802154_MAC_RSSI_MIN 0U /* corresponds to -174 dBm */
34 : #define IEEE802154_MAC_RSSI_MAX 254U /* corresponds to 80 dBm */
35 : #define IEEE802154_MAC_RSSI_UNDEFINED 255U /* used by us to indicate an undefined RSSI value */
36 :
37 : #define IEEE802154_MAC_RSSI_DBM_MIN -174 /* in dBm */
38 : #define IEEE802154_MAC_RSSI_DBM_MAX 80 /* in dBm */
39 : #define IEEE802154_MAC_RSSI_DBM_UNDEFINED INT16_MIN /* represents an undefined RSSI value */
40 :
41 : struct net_pkt_cb_ieee802154 {
42 : #if defined(CONFIG_NET_L2_OPENTHREAD)
43 : uint32_t ack_fc; /* Frame counter set in the ACK */
44 : uint8_t ack_keyid; /* Key index set in the ACK */
45 : #endif
46 : union {
47 : /* RX packets */
48 : struct {
49 : uint8_t lqi; /* Link Quality Indicator */
50 : /* See section 6.16.2.8 - Received Signal Strength Indicator (RSSI)
51 : * "RSSI is represented as one octet of integer [...]; therefore,
52 : * the minimum and maximum values are 0 (–174 dBm) and 254 (80 dBm),
53 : * respectively. 255 is reserved." (MAC PIB attribute macRssi, see
54 : * section 8.4.3.10, table 8-108)
55 : *
56 : * TX packets will show zero for this value. Drivers may set the
57 : * field to the reserved value 255 (0xff) to indicate that an RSSI
58 : * value is not available for this packet.
59 : */
60 : uint8_t rssi;
61 : };
62 : struct {
63 : #if defined(CONFIG_IEEE802154_SELECTIVE_TXCHANNEL)
64 : /* The channel used for timed transmissions.
65 : *
66 : * Please refer to `ieee802154_radio_api::tx` documentation for
67 : * details.
68 : */
69 : uint8_t txchannel;
70 : #endif /* CONFIG_IEEE802154_SELECTIVE_TXCHANNEL */
71 : };
72 : };
73 :
74 : /* Flags */
75 : uint8_t ack_fpb : 1; /* Frame Pending Bit was set in the ACK */
76 : uint8_t frame_secured : 1; /* Frame is authenticated and
77 : * encrypted according to its
78 : * Auxiliary Security Header
79 : */
80 : uint8_t mac_hdr_rdy : 1; /* Indicates if frame's MAC header
81 : * is ready to be transmitted or if
82 : * it requires further modifications,
83 : * e.g. Frame Counter injection.
84 : */
85 : #if defined(CONFIG_NET_L2_OPENTHREAD)
86 : uint8_t ack_seb : 1; /* Security Enabled Bit was set in the ACK */
87 : #endif
88 : };
89 :
90 : struct net_pkt;
91 : static inline void *net_pkt_cb(struct net_pkt *pkt);
92 :
93 : static inline struct net_pkt_cb_ieee802154 *net_pkt_cb_ieee802154(struct net_pkt *pkt)
94 : {
95 : return (struct net_pkt_cb_ieee802154 *)net_pkt_cb(pkt);
96 : };
97 :
98 : static inline uint8_t net_pkt_ieee802154_lqi(struct net_pkt *pkt)
99 : {
100 : return net_pkt_cb_ieee802154(pkt)->lqi;
101 : }
102 :
103 : static inline void net_pkt_set_ieee802154_lqi(struct net_pkt *pkt, uint8_t lqi)
104 : {
105 : net_pkt_cb_ieee802154(pkt)->lqi = lqi;
106 : }
107 :
108 : /**
109 : * @brief Get the unsigned RSSI value as defined in section 6.16.2.8,
110 : * Received Signal Strength Indicator (RSSI)
111 : *
112 : * @param pkt Pointer to the packet.
113 : *
114 : * @returns RSSI represented as unsigned byte value, ranging from
115 : * 0 (–174 dBm) to 254 (80 dBm).
116 : * The special value 255 (IEEE802154_MAC_RSSI_UNDEFINED)
117 : * indicates that an RSSI value is not available for this
118 : * packet. Will return zero for packets on the TX path.
119 : */
120 : static inline uint8_t net_pkt_ieee802154_rssi(struct net_pkt *pkt)
121 : {
122 : return net_pkt_cb_ieee802154(pkt)->rssi;
123 : }
124 :
125 : /**
126 : * @brief Set the unsigned RSSI value as defined in section 6.16.2.8,
127 : * Received Signal Strength Indicator (RSSI).
128 : *
129 : * @param pkt Pointer to the packet that was received with the given
130 : * RSSI.
131 : * @param rssi RSSI represented as unsigned byte value, ranging from
132 : * 0 (–174 dBm) to 254 (80 dBm).
133 : * The special value 255 (IEEE802154_MAC_RSSI_UNDEFINED)
134 : * indicates that an RSSI value is not available for this
135 : * packet.
136 : */
137 : static inline void net_pkt_set_ieee802154_rssi(struct net_pkt *pkt, uint8_t rssi)
138 : {
139 : net_pkt_cb_ieee802154(pkt)->rssi = rssi;
140 : }
141 :
142 : /**
143 : * @brief Get a signed RSSI value measured in dBm.
144 : *
145 : * @param pkt Pointer to the packet.
146 : *
147 : * @returns RSSI represented in dBm. Returns the special value
148 : * IEEE802154_MAC_RSSI_DBM_UNDEFINED if an RSSI value
149 : * is not available for this packet. Packets on the TX
150 : * path will always show -174 dBm (which corresponds to
151 : * an internal value of unsigned zero).
152 : */
153 : static inline int16_t net_pkt_ieee802154_rssi_dbm(struct net_pkt *pkt)
154 : {
155 : int16_t rssi = net_pkt_cb_ieee802154(pkt)->rssi;
156 : return rssi == IEEE802154_MAC_RSSI_UNDEFINED ? IEEE802154_MAC_RSSI_DBM_UNDEFINED
157 : : rssi + IEEE802154_MAC_RSSI_DBM_MIN;
158 : }
159 :
160 : /**
161 : * @brief Set the RSSI value as a signed integer measured in dBm.
162 : *
163 : * @param pkt Pointer to the packet that was received with the given
164 : * RSSI.
165 : * @param rssi represented in dBm. Set to the special value
166 : * IEEE802154_MAC_RSSI_DBM_UNDEFINED if an RSSI value is
167 : * not available for this packet. Values above 80 dBm will
168 : * be mapped to 80 dBm, values below -174 dBm will be mapped
169 : * to -174 dBm.
170 : */
171 : static inline void net_pkt_set_ieee802154_rssi_dbm(struct net_pkt *pkt, int16_t rssi)
172 : {
173 : if (likely(rssi >= IEEE802154_MAC_RSSI_DBM_MIN && rssi <= IEEE802154_MAC_RSSI_DBM_MAX)) {
174 : int16_t unsigned_rssi = rssi - IEEE802154_MAC_RSSI_DBM_MIN;
175 :
176 : net_pkt_cb_ieee802154(pkt)->rssi = unsigned_rssi;
177 : return;
178 : } else if (rssi == IEEE802154_MAC_RSSI_DBM_UNDEFINED) {
179 : net_pkt_cb_ieee802154(pkt)->rssi = IEEE802154_MAC_RSSI_UNDEFINED;
180 : return;
181 : } else if (rssi < IEEE802154_MAC_RSSI_DBM_MIN) {
182 : net_pkt_cb_ieee802154(pkt)->rssi = IEEE802154_MAC_RSSI_MIN;
183 : return;
184 : } else if (rssi > IEEE802154_MAC_RSSI_DBM_MAX) {
185 : net_pkt_cb_ieee802154(pkt)->rssi = IEEE802154_MAC_RSSI_MAX;
186 : return;
187 : }
188 :
189 : CODE_UNREACHABLE;
190 : }
191 :
192 : #if defined(CONFIG_IEEE802154_SELECTIVE_TXCHANNEL)
193 : static inline uint8_t net_pkt_ieee802154_txchannel(struct net_pkt *pkt)
194 : {
195 : return net_pkt_cb_ieee802154(pkt)->txchannel;
196 : }
197 :
198 : static inline void net_pkt_set_ieee802154_txchannel(struct net_pkt *pkt, uint8_t channel)
199 : {
200 : net_pkt_cb_ieee802154(pkt)->txchannel = channel;
201 : }
202 : #endif /* CONFIG_IEEE802154_SELECTIVE_TXCHANNEL */
203 :
204 : static inline bool net_pkt_ieee802154_ack_fpb(struct net_pkt *pkt)
205 : {
206 : return net_pkt_cb_ieee802154(pkt)->ack_fpb;
207 : }
208 :
209 : static inline void net_pkt_set_ieee802154_ack_fpb(struct net_pkt *pkt, bool fpb)
210 : {
211 : net_pkt_cb_ieee802154(pkt)->ack_fpb = fpb;
212 : }
213 :
214 : static inline bool net_pkt_ieee802154_frame_secured(struct net_pkt *pkt)
215 : {
216 : return net_pkt_cb_ieee802154(pkt)->frame_secured;
217 : }
218 :
219 : static inline void net_pkt_set_ieee802154_frame_secured(struct net_pkt *pkt, bool secured)
220 : {
221 : net_pkt_cb_ieee802154(pkt)->frame_secured = secured;
222 : }
223 :
224 : static inline bool net_pkt_ieee802154_mac_hdr_rdy(struct net_pkt *pkt)
225 : {
226 : return net_pkt_cb_ieee802154(pkt)->mac_hdr_rdy;
227 : }
228 :
229 : static inline void net_pkt_set_ieee802154_mac_hdr_rdy(struct net_pkt *pkt, bool rdy)
230 : {
231 : net_pkt_cb_ieee802154(pkt)->mac_hdr_rdy = rdy;
232 : }
233 :
234 : #if defined(CONFIG_NET_L2_OPENTHREAD)
235 : static inline uint32_t net_pkt_ieee802154_ack_fc(struct net_pkt *pkt)
236 : {
237 : return net_pkt_cb_ieee802154(pkt)->ack_fc;
238 : }
239 :
240 : static inline void net_pkt_set_ieee802154_ack_fc(struct net_pkt *pkt, uint32_t fc)
241 : {
242 : net_pkt_cb_ieee802154(pkt)->ack_fc = fc;
243 : }
244 :
245 : static inline uint8_t net_pkt_ieee802154_ack_keyid(struct net_pkt *pkt)
246 : {
247 : return net_pkt_cb_ieee802154(pkt)->ack_keyid;
248 : }
249 :
250 : static inline void net_pkt_set_ieee802154_ack_keyid(struct net_pkt *pkt, uint8_t keyid)
251 : {
252 : net_pkt_cb_ieee802154(pkt)->ack_keyid = keyid;
253 : }
254 :
255 : static inline bool net_pkt_ieee802154_ack_seb(struct net_pkt *pkt)
256 : {
257 : return net_pkt_cb_ieee802154(pkt)->ack_seb;
258 : }
259 :
260 : static inline void net_pkt_set_ieee802154_ack_seb(struct net_pkt *pkt, bool seb)
261 : {
262 : net_pkt_cb_ieee802154(pkt)->ack_seb = seb;
263 : }
264 : #endif /* CONFIG_NET_L2_OPENTHREAD */
265 :
266 : /** @endcond */
267 :
268 : #ifdef __cplusplus
269 : }
270 : #endif
271 :
272 : #endif /* ZEPHYR_INCLUDE_NET_IEEE802154_PKT_H_ */
|