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_ */