1 /* 2 * Copyright (c) 2019, The OpenThread Authors. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. Neither the name of the copyright holder nor the 13 * names of its contributors may be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /** 30 * @file 31 * @brief 32 * This file defines the mac frame interface for OpenThread platform radio drivers. 33 * 34 */ 35 36 #ifndef OPENTHREAD_UTILS_MAC_FRAME_H 37 #define OPENTHREAD_UTILS_MAC_FRAME_H 38 39 #include <openthread/platform/radio.h> 40 41 #ifdef __cplusplus 42 extern "C" { 43 #endif 44 45 /** 46 * This enumeration specifies the IEEE 802.15.4 Address type. 47 * 48 */ 49 typedef enum 50 { 51 OT_MAC_ADDRESS_TYPE_NONE, ///< No address. 52 OT_MAC_ADDRESS_TYPE_SHORT, ///< IEEE 802.15.4 Short Address. 53 OT_MAC_ADDRESS_TYPE_EXTENDED, ///< IEEE 802.15.4 Extended Address. 54 } otMacAddressType; 55 56 /** 57 * This structure represents an IEEE 802.15.4 short or extended Address. 58 * 59 */ 60 typedef struct otMacAddress 61 { 62 union 63 { 64 otShortAddress mShortAddress; ///< The IEEE 802.15.4 Short Address. 65 otExtAddress mExtAddress; ///< The IEEE 802.15.4 Extended Address. 66 } mAddress; 67 68 otMacAddressType mType; ///< The address type (short, extended, or none). 69 } otMacAddress; 70 71 /** 72 * Check if @p aFrame is an Ack frame. 73 * 74 * @param[in] aFrame A pointer to the frame. 75 * 76 * @retval true It is an ACK frame. 77 * @retval false It is not an ACK frame. 78 * 79 */ 80 bool otMacFrameIsAck(const otRadioFrame *aFrame); 81 82 /** 83 * Check if @p aFrame is a Data frame. 84 * 85 * @param[in] aFrame A pointer to the frame. 86 * 87 * @retval true It is a Data frame. 88 * @retval false It is not a Data frame. 89 * 90 */ 91 bool otMacFrameIsData(const otRadioFrame *aFrame); 92 93 /** 94 * Check if @p aFrame is a Command frame. 95 * 96 * @param[in] aFrame A pointer to the frame. 97 * 98 * @retval true It is a Command frame. 99 * @retval false It is not a Command frame. 100 * 101 */ 102 bool otMacFrameIsCommand(const otRadioFrame *aFrame); 103 104 /** 105 * Check if @p aFrame is a Data Request Command. 106 * 107 * @param[in] aFrame A pointer to the frame. For 802.15.4-2015 and above frame, 108 * the frame should be already decrypted. 109 * 110 * @retval true It is a Data Request Command frame. 111 * @retval false It is not a Data Request Command frame. 112 * 113 */ 114 bool otMacFrameIsDataRequest(const otRadioFrame *aFrame); 115 116 /** 117 * Check if @p aFrame requests ACK. 118 * 119 * @param[in] aFrame A pointer to the frame. 120 * 121 * @retval true It requests ACK. 122 * @retval false It does not request ACK. 123 * 124 */ 125 bool otMacFrameIsAckRequested(const otRadioFrame *aFrame); 126 127 /** 128 * Check if @p aFrame matches the @p aPandId and @p aShortAddress or @p aExtAddress. 129 * 130 * @param[in] aFrame A pointer to the frame. 131 * @param[in] aPanId The PAN id to match with. 132 * @param[in] aShortAddress The short address to match with. 133 * @param[in] aExtAddress The extended address to match with. 134 * 135 * @retval true It is a broadcast or matches with the PAN id and one of the addresses. 136 * @retval false It doesn't match. 137 * 138 */ 139 bool otMacFrameDoesAddrMatch(const otRadioFrame *aFrame, 140 otPanId aPanId, 141 otShortAddress aShortAddress, 142 const otExtAddress *aExtAddress); 143 144 /** 145 * Get source MAC address. 146 * 147 * @param[in] aFrame A pointer to the frame. 148 * @param[out] aMacAddress A pointer to MAC address. 149 * 150 * @retval OT_ERROR_NONE Successfully got the source MAC address. 151 * @retval OT_ERROR_PARSE Failed to parse the source MAC address. 152 * 153 */ 154 otError otMacFrameGetSrcAddr(const otRadioFrame *aFrame, otMacAddress *aMacAddress); 155 156 /** 157 * Get destination MAC address. 158 * 159 * @param[in] aFrame A pointer to the frame. 160 * @param[out] aMacAddress A pointer to MAC address. 161 * 162 * @retval OT_ERROR_NONE Successfully got the destination MAC address. 163 * @retval OT_ERROR_PARSE Failed to parse the destination MAC address. 164 * 165 */ 166 otError otMacFrameGetDstAddr(const otRadioFrame *aFrame, otMacAddress *aMacAddress); 167 168 /** 169 * Get the sequence of @p aFrame. 170 * 171 * @param[in] aFrame A pointer to the frame. 172 * 173 * @returns The sequence of the frame. 174 * 175 */ 176 uint8_t otMacFrameGetSequence(const otRadioFrame *aFrame); 177 178 /** 179 * This function performs AES CCM on the frame which is going to be sent. 180 * 181 * @param[in] aFrame A pointer to the MAC frame buffer that is going to be sent. 182 * @param[in] aExtAddress A pointer to the extended address, which will be used to generate nonce 183 * for AES CCM computation. 184 * 185 */ 186 void otMacFrameProcessTransmitAesCcm(otRadioFrame *aFrame, const otExtAddress *aExtAddress); 187 188 /** 189 * Tell if the version of @p aFrame is 2015. 190 * 191 * @param[in] aFrame A pointer to the frame. 192 * 193 * @retval true It is a version 2015 frame. 194 * @retval false It is not a version 2015 frame. 195 * 196 */ 197 bool otMacFrameIsVersion2015(const otRadioFrame *aFrame); 198 199 /** 200 * Generate Imm-Ack for @p aFrame. 201 * 202 * @param[in] aFrame A pointer to the frame. 203 * @param[in] aIsFramePending Value of the ACK's frame pending bit. 204 * @param[out] aAckFrame A pointer to the ack frame to be generated. 205 * 206 */ 207 void otMacFrameGenerateImmAck(const otRadioFrame *aFrame, bool aIsFramePending, otRadioFrame *aAckFrame); 208 209 /** 210 * Generate Enh-Ack for @p aFrame. 211 * 212 * @param[in] aFrame A pointer to the frame. 213 * @param[in] aIsFramePending Value of the ACK's frame pending bit. 214 * @param[in] aIeData A pointer to the IE data portion of the ACK to be sent. 215 * @param[in] aIeLength The length of IE data portion of the ACK to be sent. 216 * @param[out] aAckFrame A pointer to the ack frame to be generated. 217 * 218 * @retval OT_ERROR_NONE Successfully generated Enh Ack in @p aAckFrame. 219 * @retval OT_ERROR_PARSE @p aFrame has incorrect format. 220 * 221 */ 222 otError otMacFrameGenerateEnhAck(const otRadioFrame *aFrame, 223 bool aIsFramePending, 224 const uint8_t * aIeData, 225 uint8_t aIeLength, 226 otRadioFrame * aAckFrame); 227 228 /** 229 * Set CSL IE content into the frame. 230 * 231 * @param[inout] aFrame A pointer to the frame to be modified. 232 * @param[in] aCslPeriod CSL Period in CSL IE. 233 * @param[in] aCslPhase CSL Phase in CSL IE. 234 * 235 */ 236 void otMacFrameSetCslIe(otRadioFrame *aFrame, uint16_t aCslPeriod, uint16_t aCslPhase); 237 238 /** 239 * Tell if the security of @p aFrame is enabled. 240 * 241 * @param[in] aFrame A pointer to the frame. 242 * 243 * @retval true The frame has security enabled. 244 * @retval false The frame does not have security enabled. 245 * 246 */ 247 bool otMacFrameIsSecurityEnabled(otRadioFrame *aFrame); 248 249 /** 250 * Tell if the key ID mode of @p aFrame is 1. 251 * 252 * @param[in] aFrame A pointer to the frame. 253 * 254 * @retval true The frame key ID mode is 1. 255 * @retval false The frame security is not enabled or key ID mode is not 1. 256 * 257 */ 258 bool otMacFrameIsKeyIdMode1(otRadioFrame *aFrame); 259 260 /** 261 * Get the key ID of @p aFrame. 262 * 263 * @param[in] aFrame A pointer to the frame. 264 * 265 * @returns The key ID of the frame with key ID mode 1. Returns 0 if failed. 266 * 267 */ 268 uint8_t otMacFrameGetKeyId(otRadioFrame *aFrame); 269 270 /** 271 * Set key ID to @p aFrame with key ID mode 1. 272 * 273 * @param[inout] aFrame A pointer to the frame to be modified. 274 * @param[in] aKeyId Key ID to be set to the frame. 275 * 276 */ 277 void otMacFrameSetKeyId(otRadioFrame *aFrame, uint8_t aKeyId); 278 279 /** 280 * Get the frame counter of @p aFrame. 281 * 282 * @param[in] aFrame A pointer to the frame. 283 * 284 * @returns The frame counter of the frame. Returns UINT32_MAX if failed. 285 * 286 */ 287 uint32_t otMacFrameGetFrameCounter(otRadioFrame *aFrame); 288 289 /** 290 * Set frame counter to @p aFrame. 291 * 292 * @param[inout] aFrame A pointer to the frame to be modified. 293 * @param[in] aFrameCounter Frame counter to be set to the frame. 294 * 295 */ 296 void otMacFrameSetFrameCounter(otRadioFrame *aFrame, uint32_t aFrameCounter); 297 298 /** 299 * Write CSL IE to a buffer (without setting IE value). 300 * 301 * @param[out] aDest A pointer to the output buffer. 302 * 303 * @returns The total count of bytes (total length of CSL IE) written to the buffer. 304 * 305 */ 306 uint8_t otMacFrameGenerateCslIeTemplate(uint8_t *aDest); 307 308 /** 309 * Write Enh-ACK Probing IE (Vendor IE with THREAD OUI) to a buffer. 310 * 311 * @p aIeData could be `NULL`. If @p aIeData is `NULL`, this method generates the IE with the data unset. This allows 312 * users to generate the pattern first and update value later. (For example, using `otMacFrameSetEnhAckProbingIe`) 313 * 314 * @param[out] aDest A pointer to the output buffer. 315 * @param[in] aIeData A pointer to the Link Metrics data. 316 * @param[in] aIeDataLength The length of Link Metrics data value. Should be `1` or `2`. (Per spec 4.11.3.4.4.6) 317 * 318 * @returns The total count of bytes (total length of the Vendor IE) written to the buffer. 319 * 320 */ 321 uint8_t otMacFrameGenerateEnhAckProbingIe(uint8_t *aDest, const uint8_t *aIeData, uint8_t aIeDataLength); 322 323 /** 324 * Sets the data value of Enh-ACK Probing IE (Vendor IE with THREAD OUI) in a frame. 325 * 326 * If no Enh-ACK Probing IE is found in @p aFrame, nothing would be done. 327 * 328 * @param[in] aFrame The target frame that contains the IE. MUST NOT be `NULL`. 329 * @param[in] aData A pointer to the data value. MUST NOT be `NULL`. 330 * @param[in] aDataLen The length of @p aData. 331 * 332 */ 333 void otMacFrameSetEnhAckProbingIe(otRadioFrame *aFrame, const uint8_t *aData, uint8_t aDataLen); 334 335 #ifdef __cplusplus 336 } // extern "C" 337 #endif 338 339 #endif // OPENTHREAD_UTILS_MAC_FRAME_H 340