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 * 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 * 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 * @param[out] aSequence A pointer to the sequence. 173 * 174 * @retval OT_ERROR_NONE Successfully got the sequence. 175 * @retval OT_ERROR_PARSE Failed to parse the sequence. 176 * 177 */ 178 otError otMacFrameGetSequence(const otRadioFrame *aFrame, uint8_t *aSequence); 179 180 /** 181 * Performs AES CCM on the frame which is going to be sent. 182 * 183 * @param[in] aFrame A pointer to the MAC frame buffer that is going to be sent. 184 * @param[in] aExtAddress A pointer to the extended address, which will be used to generate nonce 185 * for AES CCM computation. 186 * 187 */ 188 void otMacFrameProcessTransmitAesCcm(otRadioFrame *aFrame, const otExtAddress *aExtAddress); 189 190 /** 191 * Tell if the version of @p aFrame is 2015. 192 * 193 * @param[in] aFrame A pointer to the frame. 194 * 195 * @retval true It is a version 2015 frame. 196 * @retval false It is not a version 2015 frame. 197 * 198 */ 199 bool otMacFrameIsVersion2015(const otRadioFrame *aFrame); 200 201 /** 202 * Generate Imm-Ack for @p aFrame. 203 * 204 * @param[in] aFrame A pointer to the frame. 205 * @param[in] aIsFramePending Value of the ACK's frame pending bit. 206 * @param[out] aAckFrame A pointer to the ack frame to be generated. 207 * 208 */ 209 void otMacFrameGenerateImmAck(const otRadioFrame *aFrame, bool aIsFramePending, otRadioFrame *aAckFrame); 210 211 /** 212 * Generate Enh-Ack for @p aFrame. 213 * 214 * @param[in] aFrame A pointer to the frame. 215 * @param[in] aIsFramePending Value of the ACK's frame pending bit. 216 * @param[in] aIeData A pointer to the IE data portion of the ACK to be sent. 217 * @param[in] aIeLength The length of IE data portion of the ACK to be sent. 218 * @param[out] aAckFrame A pointer to the ack frame to be generated. 219 * 220 * @retval OT_ERROR_NONE Successfully generated Enh Ack in @p aAckFrame. 221 * @retval OT_ERROR_PARSE @p aFrame has incorrect format. 222 * 223 */ 224 otError otMacFrameGenerateEnhAck(const otRadioFrame *aFrame, 225 bool aIsFramePending, 226 const uint8_t *aIeData, 227 uint8_t aIeLength, 228 otRadioFrame *aAckFrame); 229 230 /** 231 * Set CSL IE content into the frame. 232 * 233 * @param[in,out] aFrame A pointer to the frame to be modified. 234 * @param[in] aCslPeriod CSL Period in CSL IE. 235 * @param[in] aCslPhase CSL Phase in CSL IE. 236 * 237 */ 238 void otMacFrameSetCslIe(otRadioFrame *aFrame, uint16_t aCslPeriod, uint16_t aCslPhase); 239 240 /** 241 * Tell if the security of @p aFrame is enabled. 242 * 243 * @param[in] aFrame A pointer to the frame. 244 * 245 * @retval true The frame has security enabled. 246 * @retval false The frame does not have security enabled. 247 * 248 */ 249 bool otMacFrameIsSecurityEnabled(otRadioFrame *aFrame); 250 251 /** 252 * Tell if the key ID mode of @p aFrame is 1. 253 * 254 * @param[in] aFrame A pointer to the frame. 255 * 256 * @retval true The frame key ID mode is 1. 257 * @retval false The frame security is not enabled or key ID mode is not 1. 258 * 259 */ 260 bool otMacFrameIsKeyIdMode1(otRadioFrame *aFrame); 261 262 /** 263 * Get the key ID of @p aFrame. 264 * 265 * @param[in] aFrame A pointer to the frame. 266 * 267 * @returns The key ID of the frame with key ID mode 1. Returns 0 if failed. 268 * 269 */ 270 uint8_t otMacFrameGetKeyId(otRadioFrame *aFrame); 271 272 /** 273 * Set key ID to @p aFrame with key ID mode 1. 274 * 275 * @param[in,out] aFrame A pointer to the frame to be modified. 276 * @param[in] aKeyId Key ID to be set to the frame. 277 * 278 */ 279 void otMacFrameSetKeyId(otRadioFrame *aFrame, uint8_t aKeyId); 280 281 /** 282 * Get the frame counter of @p aFrame. 283 * 284 * @param[in] aFrame A pointer to the frame. 285 * 286 * @returns The frame counter of the frame. Returns UINT32_MAX if failed. 287 * 288 */ 289 uint32_t otMacFrameGetFrameCounter(otRadioFrame *aFrame); 290 291 /** 292 * Set frame counter to @p aFrame. 293 * 294 * @param[in,out] aFrame A pointer to the frame to be modified. 295 * @param[in] aFrameCounter Frame counter to be set to the frame. 296 * 297 */ 298 void otMacFrameSetFrameCounter(otRadioFrame *aFrame, uint32_t aFrameCounter); 299 300 /** 301 * Write CSL IE to a buffer (without setting IE value). 302 * 303 * @param[out] aDest A pointer to the output buffer. 304 * 305 * @returns The total count of bytes (total length of CSL IE) written to the buffer. 306 * 307 */ 308 uint8_t otMacFrameGenerateCslIeTemplate(uint8_t *aDest); 309 310 /** 311 * Write Enh-ACK Probing IE (Vendor IE with THREAD OUI) to a buffer. 312 * 313 * @p aIeData could be `NULL`. If @p aIeData is `NULL`, this method generates the IE with the data unset. This allows 314 * users to generate the pattern first and update value later. (For example, using `otMacFrameSetEnhAckProbingIe`) 315 * 316 * @param[out] aDest A pointer to the output buffer. 317 * @param[in] aIeData A pointer to the Link Metrics data. 318 * @param[in] aIeDataLength The length of Link Metrics data value. Should be `1` or `2`. (Per spec 4.11.3.4.4.6) 319 * 320 * @returns The total count of bytes (total length of the Vendor IE) written to the buffer. 321 * 322 */ 323 uint8_t otMacFrameGenerateEnhAckProbingIe(uint8_t *aDest, const uint8_t *aIeData, uint8_t aIeDataLength); 324 325 /** 326 * Sets the data value of Enh-ACK Probing IE (Vendor IE with THREAD OUI) in a frame. 327 * 328 * If no Enh-ACK Probing IE is found in @p aFrame, nothing would be done. 329 * 330 * @param[in] aFrame The target frame that contains the IE. MUST NOT be `NULL`. 331 * @param[in] aData A pointer to the data value. MUST NOT be `NULL`. 332 * @param[in] aDataLen The length of @p aData. 333 * 334 */ 335 void otMacFrameSetEnhAckProbingIe(otRadioFrame *aFrame, const uint8_t *aData, uint8_t aDataLen); 336 337 #ifdef __cplusplus 338 } // extern "C" 339 #endif 340 341 #endif // OPENTHREAD_UTILS_MAC_FRAME_H 342