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 #ifndef OPENTHREAD_UTILS_MAC_FRAME_H 36 #define OPENTHREAD_UTILS_MAC_FRAME_H 37 38 #include <openthread/platform/radio.h> 39 40 #ifdef __cplusplus 41 extern "C" { 42 #endif 43 44 /** 45 * Specifies the IEEE 802.15.4 Address type. 46 */ 47 typedef enum 48 { 49 OT_MAC_ADDRESS_TYPE_NONE, ///< No address. 50 OT_MAC_ADDRESS_TYPE_SHORT, ///< IEEE 802.15.4 Short Address. 51 OT_MAC_ADDRESS_TYPE_EXTENDED, ///< IEEE 802.15.4 Extended Address. 52 } otMacAddressType; 53 54 /** 55 * Represents an IEEE 802.15.4 short or extended Address. 56 */ 57 typedef struct otMacAddress 58 { 59 union 60 { 61 otShortAddress mShortAddress; ///< The IEEE 802.15.4 Short Address. 62 otExtAddress mExtAddress; ///< The IEEE 802.15.4 Extended Address. 63 } mAddress; 64 65 otMacAddressType mType; ///< The address type (short, extended, or none). 66 } otMacAddress; 67 68 /** 69 * Check if @p aFrame is an Ack frame. 70 * 71 * @param[in] aFrame A pointer to the frame. 72 * 73 * @retval true It is an ACK frame. 74 * @retval false It is not an ACK frame. 75 */ 76 bool otMacFrameIsAck(const otRadioFrame *aFrame); 77 78 /** 79 * Check if @p aFrame is a Data frame. 80 * 81 * @param[in] aFrame A pointer to the frame. 82 * 83 * @retval true It is a Data frame. 84 * @retval false It is not a Data frame. 85 */ 86 bool otMacFrameIsData(const otRadioFrame *aFrame); 87 88 /** 89 * Check if @p aFrame is a Command frame. 90 * 91 * @param[in] aFrame A pointer to the frame. 92 * 93 * @retval true It is a Command frame. 94 * @retval false It is not a Command frame. 95 */ 96 bool otMacFrameIsCommand(const otRadioFrame *aFrame); 97 98 /** 99 * Check if @p aFrame is a Data Request Command. 100 * 101 * @param[in] aFrame A pointer to the frame. For 802.15.4-2015 and above frame, 102 * the frame should be already decrypted. 103 * 104 * @retval true It is a Data Request Command frame. 105 * @retval false It is not a Data Request Command frame. 106 */ 107 bool otMacFrameIsDataRequest(const otRadioFrame *aFrame); 108 109 /** 110 * Check if @p aFrame requests ACK. 111 * 112 * @param[in] aFrame A pointer to the frame. 113 * 114 * @retval true It requests ACK. 115 * @retval false It does not request ACK. 116 */ 117 bool otMacFrameIsAckRequested(const otRadioFrame *aFrame); 118 119 /** 120 * Check if @p aFrame matches the @p aPandId and @p aShortAddress or @p aExtAddress. 121 * 122 * @param[in] aFrame A pointer to the frame. 123 * @param[in] aPanId The PAN id to match with. 124 * @param[in] aShortAddress The short address to match with. 125 * @param[in] aExtAddress The extended address to match with. 126 * 127 * @retval true It is a broadcast or matches with the PAN id and one of the addresses. 128 * @retval false It doesn't match. 129 */ 130 bool otMacFrameDoesAddrMatch(const otRadioFrame *aFrame, 131 otPanId aPanId, 132 otShortAddress aShortAddress, 133 const otExtAddress *aExtAddress); 134 135 /** 136 * Check if @p aFrame matches the @p aPandId and @p aShortAddress, or @p aAltShortAddress or @p aExtAddress. 137 * 138 * @param[in] aFrame A pointer to the frame. 139 * @param[in] aPanId The PAN id to match with. 140 * @param[in] aShortAddress The short address to match with. 141 * @param[in] aAltShortAddress The alternate short address to match with. Can be `OT_RADIO_INVALID_SHORT_ADDR` if 142 * there is no alternate address. 143 * @param[in] aExtAddress The extended address to match with. 144 * 145 * @retval true It is a broadcast or matches with the PAN id and one of the addresses. 146 * @retval false It doesn't match. 147 */ 148 bool otMacFrameDoesAddrMatchAny(const otRadioFrame *aFrame, 149 otPanId aPanId, 150 otShortAddress aShortAddress, 151 otShortAddress aAltShortAddress, 152 const otExtAddress *aExtAddress); 153 154 /** 155 * Get source MAC address. 156 * 157 * @param[in] aFrame A pointer to the frame. 158 * @param[out] aMacAddress A pointer to MAC address. 159 * 160 * @retval OT_ERROR_NONE Successfully got the source MAC address. 161 * @retval OT_ERROR_PARSE Failed to parse the source MAC address. 162 */ 163 otError otMacFrameGetSrcAddr(const otRadioFrame *aFrame, otMacAddress *aMacAddress); 164 165 /** 166 * Get destination MAC address. 167 * 168 * @param[in] aFrame A pointer to the frame. 169 * @param[out] aMacAddress A pointer to MAC address. 170 * 171 * @retval OT_ERROR_NONE Successfully got the destination MAC address. 172 * @retval OT_ERROR_PARSE Failed to parse the destination MAC address. 173 */ 174 otError otMacFrameGetDstAddr(const otRadioFrame *aFrame, otMacAddress *aMacAddress); 175 176 /** 177 * Get the sequence of @p aFrame. 178 * 179 * @param[in] aFrame A pointer to the frame. 180 * @param[out] aSequence A pointer to the sequence. 181 * 182 * @retval OT_ERROR_NONE Successfully got the sequence. 183 * @retval OT_ERROR_PARSE Failed to parse the sequence. 184 */ 185 otError otMacFrameGetSequence(const otRadioFrame *aFrame, uint8_t *aSequence); 186 187 /** 188 * Performs AES CCM on the frame which is going to be sent. 189 * 190 * @param[in] aFrame A pointer to the MAC frame buffer that is going to be sent. 191 * @param[in] aExtAddress A pointer to the extended address, which will be used to generate nonce 192 * for AES CCM computation. 193 */ 194 void otMacFrameProcessTransmitAesCcm(otRadioFrame *aFrame, const otExtAddress *aExtAddress); 195 196 /** 197 * Tell if the version of @p aFrame is 2015. 198 * 199 * @param[in] aFrame A pointer to the frame. 200 * 201 * @retval true It is a version 2015 frame. 202 * @retval false It is not a version 2015 frame. 203 */ 204 bool otMacFrameIsVersion2015(const otRadioFrame *aFrame); 205 206 /** 207 * Generate Imm-Ack for @p aFrame. 208 * 209 * @param[in] aFrame A pointer to the frame. 210 * @param[in] aIsFramePending Value of the ACK's frame pending bit. 211 * @param[out] aAckFrame A pointer to the ack frame to be generated. 212 */ 213 void otMacFrameGenerateImmAck(const otRadioFrame *aFrame, bool aIsFramePending, otRadioFrame *aAckFrame); 214 215 /** 216 * Generate Enh-Ack for @p aFrame. 217 * 218 * @param[in] aFrame A pointer to the frame. 219 * @param[in] aIsFramePending Value of the ACK's frame pending bit. 220 * @param[in] aIeData A pointer to the IE data portion of the ACK to be sent. 221 * @param[in] aIeLength The length of IE data portion of the ACK to be sent. 222 * @param[out] aAckFrame A pointer to the ack frame to be generated. 223 * 224 * @retval OT_ERROR_NONE Successfully generated Enh Ack in @p aAckFrame. 225 * @retval OT_ERROR_PARSE @p aFrame has incorrect format. 226 */ 227 otError otMacFrameGenerateEnhAck(const otRadioFrame *aFrame, 228 bool aIsFramePending, 229 const uint8_t *aIeData, 230 uint8_t aIeLength, 231 otRadioFrame *aAckFrame); 232 233 /** 234 * Set CSL IE content into the frame. 235 * 236 * @param[in,out] aFrame A pointer to the frame to be modified. 237 * @param[in] aCslPeriod CSL Period in CSL IE. 238 * @param[in] aCslPhase CSL Phase in CSL IE. 239 */ 240 void otMacFrameSetCslIe(otRadioFrame *aFrame, uint16_t aCslPeriod, uint16_t aCslPhase); 241 242 /** 243 * Tell if the security of @p aFrame is enabled. 244 * 245 * @param[in] aFrame A pointer to the frame. 246 * 247 * @retval true The frame has security enabled. 248 * @retval false The frame does not have security enabled. 249 */ 250 bool otMacFrameIsSecurityEnabled(otRadioFrame *aFrame); 251 252 /** 253 * Tell if the key ID mode of @p aFrame is 1. 254 * 255 * @param[in] aFrame A pointer to the frame. 256 * 257 * @retval true The frame key ID mode is 1. 258 * @retval false The frame security is not enabled or key ID mode is not 1. 259 */ 260 bool otMacFrameIsKeyIdMode1(otRadioFrame *aFrame); 261 262 /** 263 * Tell if the key ID mode of @p aFrame is 2. 264 * 265 * @param[in] aFrame A pointer to the frame. 266 * 267 * @retval true The frame key ID mode is 2. 268 * @retval false The frame security is not enabled or key ID mode is not 2. 269 */ 270 bool otMacFrameIsKeyIdMode2(otRadioFrame *aFrame); 271 272 /** 273 * Get the key ID of @p aFrame. 274 * 275 * @param[in] aFrame A pointer to the frame. 276 * 277 * @returns The key ID of the frame with key ID mode 1. Returns 0 if failed. 278 */ 279 uint8_t otMacFrameGetKeyId(otRadioFrame *aFrame); 280 281 /** 282 * Set key ID to @p aFrame with key ID mode 1. 283 * 284 * @param[in,out] aFrame A pointer to the frame to be modified. 285 * @param[in] aKeyId Key ID to be set to the frame. 286 */ 287 void otMacFrameSetKeyId(otRadioFrame *aFrame, uint8_t aKeyId); 288 289 /** 290 * Get the frame counter of @p aFrame. 291 * 292 * @param[in] aFrame A pointer to the frame. 293 * 294 * @returns The frame counter of the frame. Returns UINT32_MAX if failed. 295 */ 296 uint32_t otMacFrameGetFrameCounter(otRadioFrame *aFrame); 297 298 /** 299 * Set frame counter to @p aFrame. 300 * 301 * @param[in,out] aFrame A pointer to the frame to be modified. 302 * @param[in] aFrameCounter Frame counter to be set to the frame. 303 */ 304 void otMacFrameSetFrameCounter(otRadioFrame *aFrame, uint32_t aFrameCounter); 305 306 /** 307 * Write CSL IE to a buffer (without setting IE value). 308 * 309 * @param[out] aDest A pointer to the output buffer. 310 * 311 * @returns The total count of bytes (total length of CSL IE) written to the buffer. 312 */ 313 uint8_t otMacFrameGenerateCslIeTemplate(uint8_t *aDest); 314 315 /** 316 * Write Enh-ACK Probing IE (Vendor IE with THREAD OUI) to a buffer. 317 * 318 * @p aIeData could be `NULL`. If @p aIeData is `NULL`, this method generates the IE with the data unset. This allows 319 * users to generate the pattern first and update value later. (For example, using `otMacFrameSetEnhAckProbingIe`) 320 * 321 * @param[out] aDest A pointer to the output buffer. 322 * @param[in] aIeData A pointer to the Link Metrics data. 323 * @param[in] aIeDataLength The length of Link Metrics data value. Should be `1` or `2`. (Per spec 4.11.3.4.4.6) 324 * 325 * @returns The total count of bytes (total length of the Vendor IE) written to the buffer. 326 */ 327 uint8_t otMacFrameGenerateEnhAckProbingIe(uint8_t *aDest, const uint8_t *aIeData, uint8_t aIeDataLength); 328 329 /** 330 * Sets the data value of Enh-ACK Probing IE (Vendor IE with THREAD OUI) in a frame. 331 * 332 * If no Enh-ACK Probing IE is found in @p aFrame, nothing would be done. 333 * 334 * @param[in] aFrame The target frame that contains the IE. MUST NOT be `NULL`. 335 * @param[in] aData A pointer to the data value. MUST NOT be `NULL`. 336 * @param[in] aDataLen The length of @p aData. 337 */ 338 void otMacFrameSetEnhAckProbingIe(otRadioFrame *aFrame, const uint8_t *aData, uint8_t aDataLen); 339 340 /** 341 * Represents the context for radio layer. 342 */ 343 typedef struct otRadioContext 344 { 345 otExtAddress mExtAddress; ///< In little-endian byte order. 346 uint32_t mMacFrameCounter; 347 uint32_t mPrevMacFrameCounter; 348 uint32_t mCslSampleTime; ///< The sample time based on the microsecond timer. 349 uint16_t mCslPeriod; ///< In unit of 10 symbols. 350 otShortAddress mShortAddress; 351 otShortAddress mAlternateShortAddress; 352 otRadioKeyType mKeyType; 353 uint8_t mKeyId; 354 otMacKeyMaterial mPrevKey; 355 otMacKeyMaterial mCurrKey; 356 otMacKeyMaterial mNextKey; 357 } otRadioContext; 358 359 /** 360 * Perform processing of SFD callback from ISR. 361 * 362 * This function may do multiple tasks as follows. 363 * 364 * - CSL IE will be populated (if present) 365 * - Time IE will be populated (if present) 366 * - Tx timestamp will be populated 367 * - Tx security will be performed (including assignment of security frame counter and key id if not assigned) 368 * 369 * @param[in,out] aFrame The target frame. MUST NOT be `NULL`. 370 * @param[in] aRadioTime The radio time when the SFD was at the antenna. 371 * @param[in,out] aRadioContext The radio context accessible in ISR. 372 * 373 * @returns the error processing the callback. The caller should abort transmission on failures. 374 */ 375 otError otMacFrameProcessTxSfd(otRadioFrame *aFrame, uint64_t aRadioTime, otRadioContext *aRadioContext); 376 377 /** 378 * Process frame tx security. 379 * 380 * @param[in,out] aFrame The target frame. MUST NOT be `NULL`. 381 * @param[in,out] aRadioContext The radio context accessible in ISR. 382 * 383 * @retval OT_ERROR_NONE Successfully processed security. 384 * @retval OT_ERROR_FAILED Failed to processed security. 385 * @retval OT_ERROR_SECURITY Failed to processed security for missing key. 386 */ 387 otError otMacFrameProcessTransmitSecurity(otRadioFrame *aFrame, otRadioContext *aRadioContext); 388 389 #ifdef __cplusplus 390 } // extern "C" 391 #endif 392 393 #endif // OPENTHREAD_UTILS_MAC_FRAME_H 394