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