1 /* 2 * Copyright (c) 2016, 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 radio interface for OpenThread. 33 */ 34 35 #ifndef OPENTHREAD_PLATFORM_RADIO_H_ 36 #define OPENTHREAD_PLATFORM_RADIO_H_ 37 38 #include <stdint.h> 39 40 #include <openthread/error.h> 41 #include <openthread/instance.h> 42 #include <openthread/platform/crypto.h> 43 44 #ifdef __cplusplus 45 extern "C" { 46 #endif 47 48 /** 49 * @addtogroup plat-radio 50 * 51 * @brief 52 * This module includes the platform abstraction for radio communication. 53 * 54 * @{ 55 */ 56 57 /** 58 * @defgroup radio-types Radio Types 59 * 60 * @brief 61 * This module includes the platform abstraction for a radio frame. 62 * 63 * @{ 64 */ 65 66 enum 67 { 68 OT_RADIO_FRAME_MAX_SIZE = 127, ///< aMaxPHYPacketSize (IEEE 802.15.4-2006) 69 OT_RADIO_FRAME_MIN_SIZE = 3, ///< Minimal size of frame FCS + CONTROL 70 71 OT_RADIO_SYMBOLS_PER_OCTET = 2, ///< 2.4 GHz IEEE 802.15.4-2006 72 OT_RADIO_BIT_RATE = 250000, ///< 2.4 GHz IEEE 802.15.4 (bits per second) 73 OT_RADIO_BITS_PER_OCTET = 8, ///< Number of bits per octet 74 75 // Per IEEE 802.15.4-2015, 12.3.3 Symbol rate: 76 // The O-QPSK PHY symbol rate shall be 25 ksymbol/s when operating in the 868 MHz band and 62.5 ksymbol/s when 77 // operating in the 780 MHz, 915 MHz, 2380 MHz, or 2450 MHz band 78 OT_RADIO_SYMBOL_RATE = 62500, ///< The O-QPSK PHY symbol rate when operating in the 780MHz, 915MHz, 2380MHz, 2450MHz 79 OT_RADIO_SYMBOL_TIME = 1000000 * 1 / OT_RADIO_SYMBOL_RATE, ///< Symbol duration time in unit of microseconds 80 OT_RADIO_TEN_SYMBOLS_TIME = 10 * OT_RADIO_SYMBOL_TIME, ///< Time for 10 symbols in unit of microseconds 81 82 OT_RADIO_LQI_NONE = 0, ///< LQI measurement not supported 83 OT_RADIO_RSSI_INVALID = 127, ///< Invalid or unknown RSSI value 84 OT_RADIO_POWER_INVALID = 127, ///< Invalid or unknown power value 85 86 OT_RADIO_INVALID_SHORT_ADDR = 0xfffe, ///< Invalid short address. 87 OT_RADIO_BROADCAST_SHORT_ADDR = 0xffff, ///< Broadcast short address. 88 }; 89 90 /** 91 * Defines the channel page. 92 */ 93 enum 94 { 95 OT_RADIO_CHANNEL_PAGE_0 = 0, ///< 2.4 GHz IEEE 802.15.4-2006 96 OT_RADIO_CHANNEL_PAGE_0_MASK = (1U << OT_RADIO_CHANNEL_PAGE_0), ///< 2.4 GHz IEEE 802.15.4-2006 97 OT_RADIO_CHANNEL_PAGE_2 = 2, ///< 915 MHz IEEE 802.15.4-2006 98 OT_RADIO_CHANNEL_PAGE_2_MASK = (1U << OT_RADIO_CHANNEL_PAGE_2), ///< 915 MHz IEEE 802.15.4-2006 99 }; 100 101 /** 102 * Defines the frequency band channel range. 103 */ 104 enum 105 { 106 OT_RADIO_915MHZ_OQPSK_CHANNEL_MIN = 1, ///< 915 MHz IEEE 802.15.4-2006 107 OT_RADIO_915MHZ_OQPSK_CHANNEL_MAX = 10, ///< 915 MHz IEEE 802.15.4-2006 108 OT_RADIO_915MHZ_OQPSK_CHANNEL_MASK = 0x3ff << OT_RADIO_915MHZ_OQPSK_CHANNEL_MIN, ///< 915 MHz IEEE 802.15.4-2006 109 OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN = 11, ///< 2.4 GHz IEEE 802.15.4-2006 110 OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX = 26, ///< 2.4 GHz IEEE 802.15.4-2006 111 OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MASK = 0xffff << OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN, ///< 2.4 GHz IEEE 802.15.4-2006 112 }; 113 114 /** 115 * Represents radio capabilities. 116 * 117 * The value is a bit-field indicating the capabilities supported by the radio. See `OT_RADIO_CAPS_*` definitions. 118 */ 119 typedef uint16_t otRadioCaps; 120 121 /** 122 * Defines constants that are used to indicate different radio capabilities. See `otRadioCaps`. 123 */ 124 enum 125 { 126 OT_RADIO_CAPS_NONE = 0, ///< Radio supports no capability. 127 OT_RADIO_CAPS_ACK_TIMEOUT = 1 << 0, ///< Radio supports AckTime event. 128 OT_RADIO_CAPS_ENERGY_SCAN = 1 << 1, ///< Radio supports Energy Scans. 129 OT_RADIO_CAPS_TRANSMIT_RETRIES = 1 << 2, ///< Radio supports tx retry logic with collision avoidance (CSMA). 130 OT_RADIO_CAPS_CSMA_BACKOFF = 1 << 3, ///< Radio supports CSMA backoff for frame tx (but no retry). 131 OT_RADIO_CAPS_SLEEP_TO_TX = 1 << 4, ///< Radio supports direct transition from sleep to TX with CSMA. 132 OT_RADIO_CAPS_TRANSMIT_SEC = 1 << 5, ///< Radio supports tx security. 133 OT_RADIO_CAPS_TRANSMIT_TIMING = 1 << 6, ///< Radio supports tx at specific time. 134 OT_RADIO_CAPS_RECEIVE_TIMING = 1 << 7, ///< Radio supports rx at specific time. 135 OT_RADIO_CAPS_RX_ON_WHEN_IDLE = 1 << 8, ///< Radio supports RxOnWhenIdle handling. 136 OT_RADIO_CAPS_TRANSMIT_FRAME_POWER = 1 << 9, ///< Radio supports setting per-frame transmit power. 137 OT_RADIO_CAPS_ALT_SHORT_ADDR = 1 << 10, ///< Radio supports setting alternate short address. 138 }; 139 140 #define OT_PANID_BROADCAST 0xffff ///< IEEE 802.15.4 Broadcast PAN ID 141 142 /** 143 * Represents the IEEE 802.15.4 PAN ID. 144 */ 145 typedef uint16_t otPanId; 146 147 /** 148 * Represents the IEEE 802.15.4 Short Address. 149 */ 150 typedef uint16_t otShortAddress; 151 152 #define OT_EXT_ADDRESS_SIZE 8 ///< Size of an IEEE 802.15.4 Extended Address (bytes) 153 154 /** 155 * Defines constants about size of header IE in ACK. 156 */ 157 enum 158 { 159 OT_IE_HEADER_SIZE = 2, ///< Size of IE header in bytes. 160 OT_CSL_IE_SIZE = 4, ///< Size of CSL IE content in bytes. 161 OT_ACK_IE_MAX_SIZE = 16, ///< Max length for header IE in ACK. 162 OT_ENH_PROBING_IE_DATA_MAX_SIZE = 2, ///< Max length of Link Metrics data in Vendor-Specific IE. 163 }; 164 165 #define CSL_IE_HEADER_BYTES_LO 0x04 ///< Fixed CSL IE header first byte 166 #define CSL_IE_HEADER_BYTES_HI 0x0d ///< Fixed CSL IE header second byte 167 168 /** 169 * @struct otExtAddress 170 * 171 * Represents the IEEE 802.15.4 Extended Address. 172 */ 173 OT_TOOL_PACKED_BEGIN 174 struct otExtAddress 175 { 176 uint8_t m8[OT_EXT_ADDRESS_SIZE]; ///< IEEE 802.15.4 Extended Address bytes 177 } OT_TOOL_PACKED_END; 178 179 /** 180 * Represents the IEEE 802.15.4 Extended Address. 181 */ 182 typedef struct otExtAddress otExtAddress; 183 184 #define OT_MAC_KEY_SIZE 16 ///< Size of the MAC Key in bytes. 185 186 /** 187 * @struct otMacKey 188 * 189 * Represents a MAC Key. 190 */ 191 OT_TOOL_PACKED_BEGIN 192 struct otMacKey 193 { 194 uint8_t m8[OT_MAC_KEY_SIZE]; ///< MAC Key bytes. 195 } OT_TOOL_PACKED_END; 196 197 /** 198 * Represents a MAC Key. 199 */ 200 typedef struct otMacKey otMacKey; 201 202 /** 203 * Represents a MAC Key Ref used by PSA. 204 */ 205 typedef otCryptoKeyRef otMacKeyRef; 206 207 /** 208 * @struct otMacKeyMaterial 209 * 210 * Represents a MAC Key. 211 */ 212 typedef struct otMacKeyMaterial 213 { 214 union 215 { 216 otMacKeyRef mKeyRef; ///< Reference to the key stored. 217 otMacKey mKey; ///< Key stored as literal. 218 } mKeyMaterial; 219 } otMacKeyMaterial; 220 221 /** 222 * Defines constants about key types. 223 */ 224 typedef enum 225 { 226 OT_KEY_TYPE_LITERAL_KEY = 0, ///< Use Literal Keys. 227 OT_KEY_TYPE_KEY_REF = 1, ///< Use Reference to Key. 228 } otRadioKeyType; 229 230 /** 231 * Represents the IEEE 802.15.4 Header IE (Information Element) related information of a radio frame. 232 */ 233 typedef struct otRadioIeInfo 234 { 235 int64_t mNetworkTimeOffset; ///< The time offset to the Thread network time. 236 uint8_t mTimeIeOffset; ///< The Time IE offset from the start of PSDU. 237 uint8_t mTimeSyncSeq; ///< The Time sync sequence. 238 } otRadioIeInfo; 239 240 /** 241 * Represents an IEEE 802.15.4 radio frame. 242 */ 243 typedef struct otRadioFrame 244 { 245 uint8_t *mPsdu; ///< The PSDU. 246 247 uint16_t mLength; ///< Length of the PSDU. 248 uint8_t mChannel; ///< Channel used to transmit/receive the frame. 249 250 uint8_t mRadioType; ///< Radio link type - should be ignored by radio driver. 251 252 /** 253 * The union of transmit and receive information for a radio frame. 254 */ 255 union 256 { 257 /** 258 * Structure representing radio frame transmit information. 259 */ 260 struct 261 { 262 const otMacKeyMaterial *mAesKey; ///< The key material used for AES-CCM frame security. 263 otRadioIeInfo *mIeInfo; ///< The pointer to the Header IE(s) related information. 264 265 /** 266 * The base time in microseconds for scheduled transmissions 267 * relative to the local radio clock, see `otPlatRadioGetNow` and 268 * `mTxDelay`. 269 * 270 * If this field is non-zero, `mMaxCsmaBackoffs` should be ignored. 271 * 272 * This field does not affect CCA behavior which is controlled by `mCsmaCaEnabled`. 273 */ 274 uint32_t mTxDelayBaseTime; 275 276 /** 277 * The delay time in microseconds for this transmission referenced 278 * to `mTxDelayBaseTime`. 279 * 280 * Note: `mTxDelayBaseTime` + `mTxDelay` SHALL point to the point in 281 * time when the end of the SFD will be present at the local 282 * antenna, relative to the local radio clock. 283 * 284 * If this field is non-zero, `mMaxCsmaBackoffs` should be ignored. 285 * 286 * This field does not affect CCA behavior which is controlled by `mCsmaCaEnabled`. 287 */ 288 uint32_t mTxDelay; 289 290 /** 291 * Maximum number of CSMA backoff attempts before declaring channel access failure. 292 * 293 * This is applicable and MUST be used when radio platform provides the `OT_RADIO_CAPS_CSMA_BACKOFF` and/or 294 * `OT_RADIO_CAPS_TRANSMIT_RETRIES`. 295 * 296 * This field MUST be ignored if `mCsmaCaEnabled` is set to `false` (CCA is disabled) or 297 * either `mTxDelayBaseTime` or `mTxDelay` is non-zero (frame transmission is expected at a specific time). 298 * 299 * It can be set to `0` to skip backoff mechanism (note that CCA MUST still be performed assuming 300 * `mCsmaCaEnabled` is `true`). 301 */ 302 uint8_t mMaxCsmaBackoffs; 303 304 uint8_t mMaxFrameRetries; ///< Maximum number of retries allowed after a transmission failure. 305 306 /** 307 * The RX channel after frame TX is done (after all frame retries - ack received, or timeout, or abort). 308 * 309 * Radio platforms can choose to fully ignore this. OT stack will make sure to call `otPlatRadioReceive()` 310 * with the desired RX channel after a frame TX is done and signaled in `otPlatRadioTxDone()` callback. 311 * Radio platforms that don't provide `OT_RADIO_CAPS_TRANSMIT_RETRIES` must always ignore this. 312 * 313 * This is intended for situations where there may be delay in interactions between OT stack and radio, as 314 * an example this is used in RCP/host architecture to make sure RCP switches to PAN channel more quickly. 315 * In particular, this can help with CSL tx to a sleepy child, where the child may use a different channel 316 * for CSL than the PAN channel. After frame tx, we want the radio/RCP to go back to the PAN channel 317 * quickly to ensure that parent does not miss tx from child afterwards, e.g., child responding to the 318 * earlier CSL transmitted frame from parent using PAN channel while radio still staying on CSL channel. 319 * 320 * The switch to the RX channel MUST happen after the frame TX is fully done, i.e., after all retries and 321 * when ack is received (when "Ack Request" flag is set on the TX frame) or ack timeout. Note that ack is 322 * expected on the same channel that frame is sent on. 323 */ 324 uint8_t mRxChannelAfterTxDone; 325 326 /** 327 * The transmit power in dBm. 328 * 329 * If the platform layer does not provide `OT_RADIO_CAPS_TRANSMIT_FRAME_POWER` capability, it can ignore 330 * this value. 331 * 332 * If the value is OT_RADIO_POWER_INVALID, then the platform should ignore this value and transmit the frame 333 * with its default transmit power. 334 * 335 * Otherwise, the platform should transmit this frame with the maximum power no larger than minimal of the 336 * following values: 337 * 1. mTxPower, 338 * 2. The power limit set by otPlatRadioSetChannelTargetPower(), 339 * 3. The power limit set by otPlatRadioSetChannelMaxTransmitPower(), 340 * 4. The power limit set by otPlatRadioSetRegion(). 341 */ 342 int8_t mTxPower; 343 344 /** 345 * Indicates whether frame counter and CSL IEs are properly updated in the header. 346 * 347 * If the platform layer does not provide `OT_RADIO_CAPS_TRANSMIT_SEC` capability, it can ignore this flag. 348 * 349 * If the platform provides `OT_RADIO_CAPS_TRANSMIT_SEC` capability, then platform is expected to handle tx 350 * security processing and assignment of frame counter. In this case the following behavior is expected: 351 * 352 * When `mIsHeaderUpdated` is set, it indicates that OpenThread core has already set the frame counter and 353 * CSL IEs (if security is enabled) in the prepared frame. The counter is ensured to match the counter value 354 * from the previous attempts of the same frame. The platform should not assign or change the frame counter 355 * (but may still need to perform security processing depending on `mIsSecurityProcessed` flag). 356 * 357 * If `mIsHeaderUpdated` is not set, then the frame counter and key CSL IE not set in the frame by 358 * OpenThread core and it is the responsibility of the radio platform to assign them. The platform 359 * must update the frame header (assign counter and CSL IE values) before sending the frame over the air, 360 * however if the the transmission gets aborted and the frame is never sent over the air (e.g., channel 361 * access error) the platform may choose to not update the header. If the platform updates the header, 362 * it must also set this flag before passing the frame back from the `otPlatRadioTxDone()` callback. 363 */ 364 bool mIsHeaderUpdated : 1; 365 bool mIsARetx : 1; ///< Indicates whether the frame is a retransmission or not. 366 /** 367 * Set to true to enable CSMA-CA for this packet, false to disable both CSMA backoff and CCA. 368 * 369 * When it is set to `false`, the frame MUST be sent without performing CCA. In this case `mMaxCsmaBackoffs` 370 * MUST also be ignored. 371 */ 372 bool mCsmaCaEnabled : 1; 373 bool mCslPresent : 1; ///< Set to true if CSL header IE is present. 374 bool mIsSecurityProcessed : 1; ///< True if SubMac should skip the AES processing of this frame. 375 376 /** 377 * The time of the local radio clock in microseconds when the end of 378 * the SFD was present at the local antenna. 379 * 380 * The platform should update this field before otPlatRadioTxStarted() is fired for each transmit attempt. 381 */ 382 uint64_t mTimestamp; 383 } mTxInfo; 384 385 /** 386 * Structure representing radio frame receive information. 387 */ 388 struct 389 { 390 /** 391 * The time of the local radio clock in microseconds when the end of 392 * the SFD was present at the local antenna. 393 */ 394 uint64_t mTimestamp; 395 396 uint32_t mAckFrameCounter; ///< ACK security frame counter (applicable when `mAckedWithSecEnhAck` is set). 397 uint8_t mAckKeyId; ///< ACK security key index (applicable when `mAckedWithSecEnhAck` is set). 398 int8_t mRssi; ///< Received signal strength indicator in dBm for received frames. 399 uint8_t mLqi; ///< Link Quality Indicator for received frames. 400 401 // Flags 402 bool mAckedWithFramePending : 1; ///< This indicates if this frame was acknowledged with frame pending set. 403 bool mAckedWithSecEnhAck : 1; ///< This indicates if this frame was acknowledged with secured enhance ACK. 404 } mRxInfo; 405 } mInfo; 406 } otRadioFrame; 407 408 /** 409 * Represents the state of a radio. 410 * Initially, a radio is in the Disabled state. 411 */ 412 typedef enum otRadioState 413 { 414 OT_RADIO_STATE_DISABLED = 0, 415 OT_RADIO_STATE_SLEEP = 1, 416 OT_RADIO_STATE_RECEIVE = 2, 417 OT_RADIO_STATE_TRANSMIT = 3, 418 OT_RADIO_STATE_INVALID = 255, 419 } otRadioState; 420 421 /** 422 * The following are valid radio state transitions: 423 * 424 * (Radio ON) 425 * +----------+ Enable() +-------+ Receive() +---------+ Transmit() +----------+ 426 * | |----------->| |----------->| |-------------->| | 427 * | Disabled | | Sleep | | Receive | | Transmit | 428 * | |<-----------| |<-----------| |<--------------| | 429 * +----------+ Disable() +-------+ Sleep() +---------+ Receive() +----------+ 430 * (Radio OFF) or 431 * signal TransmitDone 432 * 433 * During the IEEE 802.15.4 data request command the transition Sleep->Receive->Transmit 434 * can be shortened to direct transition from Sleep to Transmit if the platform supports 435 * the OT_RADIO_CAPS_SLEEP_TO_TX capability. 436 */ 437 438 /** 439 * Represents radio coexistence metrics. 440 */ 441 typedef struct otRadioCoexMetrics 442 { 443 uint32_t mNumGrantGlitch; ///< Number of grant glitches. 444 uint32_t mNumTxRequest; ///< Number of tx requests. 445 uint32_t mNumTxGrantImmediate; ///< Number of tx requests while grant was active. 446 uint32_t mNumTxGrantWait; ///< Number of tx requests while grant was inactive. 447 uint32_t mNumTxGrantWaitActivated; ///< Number of tx requests while grant was inactive that were ultimately granted. 448 uint32_t mNumTxGrantWaitTimeout; ///< Number of tx requests while grant was inactive that timed out. 449 uint32_t mNumTxGrantDeactivatedDuringRequest; ///< Number of tx that were in progress when grant was deactivated. 450 uint32_t mNumTxDelayedGrant; ///< Number of tx requests that were not granted within 50us. 451 uint32_t mAvgTxRequestToGrantTime; ///< Average time in usec from tx request to grant. 452 uint32_t mNumRxRequest; ///< Number of rx requests. 453 uint32_t mNumRxGrantImmediate; ///< Number of rx requests while grant was active. 454 uint32_t mNumRxGrantWait; ///< Number of rx requests while grant was inactive. 455 uint32_t mNumRxGrantWaitActivated; ///< Number of rx requests while grant was inactive that were ultimately granted. 456 uint32_t mNumRxGrantWaitTimeout; ///< Number of rx requests while grant was inactive that timed out. 457 uint32_t mNumRxGrantDeactivatedDuringRequest; ///< Number of rx that were in progress when grant was deactivated. 458 uint32_t mNumRxDelayedGrant; ///< Number of rx requests that were not granted within 50us. 459 uint32_t mAvgRxRequestToGrantTime; ///< Average time in usec from rx request to grant. 460 uint32_t mNumRxGrantNone; ///< Number of rx requests that completed without receiving grant. 461 bool mStopped; ///< Stats collection stopped due to saturation. 462 } otRadioCoexMetrics; 463 464 /** 465 * Represents what metrics are specified to query. 466 */ 467 typedef struct otLinkMetrics 468 { 469 bool mPduCount : 1; ///< Pdu count. 470 bool mLqi : 1; ///< Link Quality Indicator. 471 bool mLinkMargin : 1; ///< Link Margin. 472 bool mRssi : 1; ///< Received Signal Strength Indicator. 473 bool mReserved : 1; ///< Reserved, this is for reference device. 474 } otLinkMetrics; 475 476 /** 477 * @} 478 */ 479 480 /** 481 * @defgroup radio-config Radio Configuration 482 * 483 * @brief 484 * This module includes the platform abstraction for radio configuration. 485 * 486 * @{ 487 */ 488 489 /** 490 * Get the radio capabilities. 491 * 492 * @param[in] aInstance The OpenThread instance structure. 493 * 494 * @returns The radio capability bit vector (see `OT_RADIO_CAP_*` definitions). 495 */ 496 otRadioCaps otPlatRadioGetCaps(otInstance *aInstance); 497 498 /** 499 * Get the radio version string. 500 * 501 * This is an optional radio driver platform function. If not provided by platform radio driver, OpenThread uses 502 * the OpenThread version instead (@sa otGetVersionString()). 503 * 504 * @param[in] aInstance The OpenThread instance structure. 505 * 506 * @returns A pointer to the OpenThread radio version. 507 */ 508 const char *otPlatRadioGetVersionString(otInstance *aInstance); 509 510 /** 511 * Get the radio receive sensitivity value. 512 * 513 * @param[in] aInstance The OpenThread instance structure. 514 * 515 * @returns The radio receive sensitivity value in dBm. 516 */ 517 int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance); 518 519 /** 520 * Gets the factory-assigned IEEE EUI-64 for this interface. 521 * 522 * @param[in] aInstance The OpenThread instance structure. 523 * @param[out] aIeeeEui64 A pointer to the factory-assigned IEEE EUI-64. 524 */ 525 void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64); 526 527 /** 528 * Set the PAN ID for address filtering. 529 * 530 * @param[in] aInstance The OpenThread instance structure. 531 * @param[in] aPanId The IEEE 802.15.4 PAN ID. 532 */ 533 void otPlatRadioSetPanId(otInstance *aInstance, otPanId aPanId); 534 535 /** 536 * Set the Extended Address for address filtering. 537 * 538 * @param[in] aInstance The OpenThread instance structure. 539 * @param[in] aExtAddress A pointer to the IEEE 802.15.4 Extended Address stored in little-endian byte order. 540 */ 541 void otPlatRadioSetExtendedAddress(otInstance *aInstance, const otExtAddress *aExtAddress); 542 543 /** 544 * Set the Short Address for address filtering. 545 * 546 * @param[in] aInstance The OpenThread instance structure. 547 * @param[in] aShortAddress The IEEE 802.15.4 Short Address. 548 */ 549 void otPlatRadioSetShortAddress(otInstance *aInstance, otShortAddress aShortAddress); 550 551 /** 552 * Set the alternate short address. 553 * 554 * This is an optional radio platform API. The radio platform MUST indicate support for this API by including the 555 * capability `OT_RADIO_CAPS_ALT_SHORT_ADDR` in `otPlatRadioGetCaps()`. 556 * 557 * When supported, the radio should accept received frames destined to the specified alternate short address in 558 * addition to the short address provided in `otPlatRadioSetShortAddress()`. 559 * 560 * The @p aShortAddress can be set to `OT_RADIO_INVALID_SHORT_ADDR` (0xfffe) to clear any previously set alternate 561 * short address. 562 * 563 * This function is used by OpenThread stack during child-to-router role transitions, allowing the device to continue 564 * receiving frames addressed to its previous short address for a short period. 565 * 566 * @param[in] aInstance The OpenThread instance structure. 567 * @param[in] aShortAddress The alternate IEEE 802.15.4 short address. `OT_RADIO_INVALID_SHORT_ADDR` to clear. 568 */ 569 void otPlatRadioSetAlternateShortAddress(otInstance *aInstance, otShortAddress aShortAddress); 570 571 /** 572 * Get the radio's transmit power in dBm. 573 * 574 * @note The transmit power returned will be no larger than the power specified in the max power table for 575 * the current channel. 576 * 577 * @param[in] aInstance The OpenThread instance structure. 578 * @param[out] aPower The transmit power in dBm. 579 * 580 * @retval OT_ERROR_NONE Successfully retrieved the transmit power. 581 * @retval OT_ERROR_INVALID_ARGS @p aPower was NULL. 582 * @retval OT_ERROR_NOT_IMPLEMENTED Transmit power configuration via dBm is not implemented. 583 */ 584 otError otPlatRadioGetTransmitPower(otInstance *aInstance, int8_t *aPower); 585 586 /** 587 * Set the radio's transmit power in dBm for all channels. 588 * 589 * @note The real transmit power will be no larger than the power specified in the max power table for 590 * the current channel that was configured by `otPlatRadioSetChannelMaxTransmitPower()`. 591 * 592 * @param[in] aInstance The OpenThread instance structure. 593 * @param[in] aPower The transmit power in dBm. 594 * 595 * @retval OT_ERROR_NONE Successfully set the transmit power. 596 * @retval OT_ERROR_NOT_IMPLEMENTED Transmit power configuration via dBm is not implemented. 597 */ 598 otError otPlatRadioSetTransmitPower(otInstance *aInstance, int8_t aPower); 599 600 /** 601 * Get the radio's CCA ED threshold in dBm measured at antenna connector per IEEE 802.15.4 - 2015 section 10.1.4. 602 * 603 * @param[in] aInstance The OpenThread instance structure. 604 * @param[out] aThreshold The CCA ED threshold in dBm. 605 * 606 * @retval OT_ERROR_NONE Successfully retrieved the CCA ED threshold. 607 * @retval OT_ERROR_INVALID_ARGS @p aThreshold was NULL. 608 * @retval OT_ERROR_NOT_IMPLEMENTED CCA ED threshold configuration via dBm is not implemented. 609 */ 610 otError otPlatRadioGetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t *aThreshold); 611 612 /** 613 * Set the radio's CCA ED threshold in dBm measured at antenna connector per IEEE 802.15.4 - 2015 section 10.1.4. 614 * 615 * @param[in] aInstance The OpenThread instance structure. 616 * @param[in] aThreshold The CCA ED threshold in dBm. 617 * 618 * @retval OT_ERROR_NONE Successfully set the transmit power. 619 * @retval OT_ERROR_INVALID_ARGS Given threshold is out of range. 620 * @retval OT_ERROR_NOT_IMPLEMENTED CCA ED threshold configuration via dBm is not implemented. 621 */ 622 otError otPlatRadioSetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t aThreshold); 623 624 /** 625 * Gets the external FEM's Rx LNA gain in dBm. 626 * 627 * @param[in] aInstance The OpenThread instance structure. 628 * @param[out] aGain The external FEM's Rx LNA gain in dBm. 629 * 630 * @retval OT_ERROR_NONE Successfully retrieved the external FEM's LNA gain. 631 * @retval OT_ERROR_INVALID_ARGS @p aGain was NULL. 632 * @retval OT_ERROR_NOT_IMPLEMENTED External FEM's LNA setting is not implemented. 633 */ 634 otError otPlatRadioGetFemLnaGain(otInstance *aInstance, int8_t *aGain); 635 636 /** 637 * Sets the external FEM's Rx LNA gain in dBm. 638 * 639 * @param[in] aInstance The OpenThread instance structure. 640 * @param[in] aGain The external FEM's Rx LNA gain in dBm. 641 * 642 * @retval OT_ERROR_NONE Successfully set the external FEM's LNA gain. 643 * @retval OT_ERROR_NOT_IMPLEMENTED External FEM's LNA gain setting is not implemented. 644 */ 645 otError otPlatRadioSetFemLnaGain(otInstance *aInstance, int8_t aGain); 646 647 /** 648 * Get the status of promiscuous mode. 649 * 650 * @param[in] aInstance The OpenThread instance structure. 651 * 652 * @retval TRUE Promiscuous mode is enabled. 653 * @retval FALSE Promiscuous mode is disabled. 654 */ 655 bool otPlatRadioGetPromiscuous(otInstance *aInstance); 656 657 /** 658 * Enable or disable promiscuous mode. 659 * 660 * @param[in] aInstance The OpenThread instance structure. 661 * @param[in] aEnable TRUE to enable or FALSE to disable promiscuous mode. 662 */ 663 void otPlatRadioSetPromiscuous(otInstance *aInstance, bool aEnable); 664 665 /** 666 * Sets the rx-on-when-idle state to the radio platform. 667 * 668 * There are a few situations that the radio can enter sleep state if the device is in rx-off-when-idle state but 669 * it's hard and costly for the SubMac to identify these situations and instruct the radio to enter sleep: 670 * 671 * - Finalization of a regular frame reception task, provided that: 672 * - The frame is received without errors and passes the filtering and it's not an spurious ACK. 673 * - ACK is not requested or transmission of ACK is not possible due to internal conditions. 674 * - Finalization of a frame transmission or transmission of an ACK frame, when ACK is not requested in the transmitted 675 * frame. 676 * - Finalization of the reception operation of a requested ACK due to: 677 * - ACK timeout expiration. 678 * - Reception of an invalid ACK or not an ACK frame. 679 * - Reception of the proper ACK, unless the transmitted frame was a Data Request Command and the frame pending bit 680 * on the received ACK is set to true. In this case the radio platform implementation SHOULD keep the receiver on 681 * until a determined timeout which triggers an idle period start.`OPENTHREAD_CONFIG_MAC_DATA_POLL_TIMEOUT` can be 682 * taken as a reference for this. 683 * - Finalization of a stand alone CCA task. 684 * - Finalization of a CCA operation with busy result during CSMA/CA procedure. 685 * - Finalization of an Energy Detection task. 686 * - Finalization of a radio reception window scheduled with `otPlatRadioReceiveAt`. 687 * 688 * If a platform supports `OT_RADIO_CAPS_RX_ON_WHEN_IDLE` it must also support `OT_RADIO_CAPS_CSMA_BACKOFF` and handle 689 * idle periods after CCA as described above. 690 * 691 * Upon the transition of the "RxOnWhenIdle" flag from TRUE to FALSE, the radio platform should enter sleep mode. 692 * If the radio is currently in receive mode, it should enter sleep mode immediately. Otherwise, it should enter sleep 693 * mode after the current operation is completed. 694 * 695 * @param[in] aInstance The OpenThread instance structure. 696 * @param[in] aEnable TRUE to keep radio in Receive state, FALSE to put to Sleep state during idle periods. 697 */ 698 void otPlatRadioSetRxOnWhenIdle(otInstance *aInstance, bool aEnable); 699 700 /** 701 * Update MAC keys and key index 702 * 703 * Is used when radio provides OT_RADIO_CAPS_TRANSMIT_SEC capability. 704 * 705 * The radio platform should reset the current security MAC frame counter tracked by the radio on this call. While this 706 * is highly recommended, the OpenThread stack, as a safeguard, will also reset the frame counter using the 707 * `otPlatRadioSetMacFrameCounter()` before calling this API. 708 * 709 * @param[in] aInstance A pointer to an OpenThread instance. 710 * @param[in] aKeyIdMode The key ID mode. 711 * @param[in] aKeyId Current MAC key index. 712 * @param[in] aPrevKey A pointer to the previous MAC key. 713 * @param[in] aCurrKey A pointer to the current MAC key. 714 * @param[in] aNextKey A pointer to the next MAC key. 715 * @param[in] aKeyType Key Type used. 716 */ 717 void otPlatRadioSetMacKey(otInstance *aInstance, 718 uint8_t aKeyIdMode, 719 uint8_t aKeyId, 720 const otMacKeyMaterial *aPrevKey, 721 const otMacKeyMaterial *aCurrKey, 722 const otMacKeyMaterial *aNextKey, 723 otRadioKeyType aKeyType); 724 725 /** 726 * Sets the current MAC frame counter value. 727 * 728 * Is used when radio provides `OT_RADIO_CAPS_TRANSMIT_SEC` capability. 729 * 730 * @param[in] aInstance A pointer to an OpenThread instance. 731 * @param[in] aMacFrameCounter The MAC frame counter value. 732 */ 733 void otPlatRadioSetMacFrameCounter(otInstance *aInstance, uint32_t aMacFrameCounter); 734 735 /** 736 * Sets the current MAC frame counter value only if the new given value is larger than the current value. 737 * 738 * Is used when radio provides `OT_RADIO_CAPS_TRANSMIT_SEC` capability. 739 * 740 * @param[in] aInstance A pointer to an OpenThread instance. 741 * @param[in] aMacFrameCounter The MAC frame counter value. 742 */ 743 void otPlatRadioSetMacFrameCounterIfLarger(otInstance *aInstance, uint32_t aMacFrameCounter); 744 745 /** 746 * Get the current time in microseconds referenced to a continuous monotonic 747 * local radio clock (64 bits width). 748 * 749 * The radio clock SHALL NOT wrap during the device's uptime. Implementations 750 * SHALL therefore identify and compensate for internal counter overflows. The 751 * clock does not have a defined epoch and it SHALL NOT introduce any continuous 752 * or discontinuous adjustments (e.g. leap seconds). Implementations SHALL 753 * compensate for any sleep times of the device. 754 * 755 * Implementations MAY choose to discipline the radio clock and compensate for 756 * sleep times by any means (e.g. by combining a high precision/low power RTC 757 * with a high resolution counter) as long as the exposed combined clock 758 * provides continuous monotonic microsecond resolution ticks within the 759 * accuracy limits announced by @ref otPlatRadioGetCslAccuracy. 760 * 761 * @param[in] aInstance A pointer to an OpenThread instance. 762 * 763 * @returns The current time in microseconds. UINT64_MAX when platform does not 764 * support or radio time is not ready. 765 */ 766 uint64_t otPlatRadioGetNow(otInstance *aInstance); 767 768 /** 769 * Get the bus speed in bits/second between the host and the radio chip. 770 * 771 * @param[in] aInstance A pointer to an OpenThread instance. 772 * 773 * @returns The bus speed in bits/second between the host and the radio chip. 774 * Return 0 when the MAC and above layer and Radio layer resides on the same chip. 775 */ 776 uint32_t otPlatRadioGetBusSpeed(otInstance *aInstance); 777 778 /** 779 * Get the bus latency in microseconds between the host and the radio chip. 780 * 781 * @param[in] aInstance A pointer to an OpenThread instance. 782 * 783 * @returns The bus latency in microseconds between the host and the radio chip. 784 * Return 0 when the MAC and above layer and Radio layer resides on the same chip. 785 */ 786 uint32_t otPlatRadioGetBusLatency(otInstance *aInstance); 787 788 /** 789 * @} 790 */ 791 792 /** 793 * @defgroup radio-operation Radio Operation 794 * 795 * @brief 796 * This module includes the platform abstraction for radio operations. 797 * 798 * @{ 799 */ 800 801 /** 802 * Get current state of the radio. 803 * 804 * Is not required by OpenThread. It may be used for debugging and/or application-specific purposes. 805 * 806 * @note This function may be not implemented. It does not affect OpenThread. 807 * 808 * @param[in] aInstance The OpenThread instance structure. 809 * 810 * @return Current state of the radio. 811 */ 812 otRadioState otPlatRadioGetState(otInstance *aInstance); 813 814 /** 815 * Enable the radio. 816 * 817 * @param[in] aInstance The OpenThread instance structure. 818 * 819 * @retval OT_ERROR_NONE Successfully enabled. 820 * @retval OT_ERROR_FAILED The radio could not be enabled. 821 */ 822 otError otPlatRadioEnable(otInstance *aInstance); 823 824 /** 825 * Disable the radio. 826 * 827 * @param[in] aInstance The OpenThread instance structure. 828 * 829 * @retval OT_ERROR_NONE Successfully transitioned to Disabled. 830 * @retval OT_ERROR_INVALID_STATE The radio was not in sleep state. 831 */ 832 otError otPlatRadioDisable(otInstance *aInstance); 833 834 /** 835 * Check whether radio is enabled or not. 836 * 837 * @param[in] aInstance The OpenThread instance structure. 838 * 839 * @returns TRUE if the radio is enabled, FALSE otherwise. 840 */ 841 bool otPlatRadioIsEnabled(otInstance *aInstance); 842 843 /** 844 * Transition the radio from Receive to Sleep (turn off the radio). 845 * 846 * @param[in] aInstance The OpenThread instance structure. 847 * 848 * @retval OT_ERROR_NONE Successfully transitioned to Sleep. 849 * @retval OT_ERROR_BUSY The radio was transmitting. 850 * @retval OT_ERROR_INVALID_STATE The radio was disabled. 851 */ 852 otError otPlatRadioSleep(otInstance *aInstance); 853 854 /** 855 * Transition the radio from Sleep to Receive (turn on the radio). 856 * 857 * @param[in] aInstance The OpenThread instance structure. 858 * @param[in] aChannel The channel to use for receiving. 859 * 860 * @retval OT_ERROR_NONE Successfully transitioned to Receive. 861 * @retval OT_ERROR_INVALID_STATE The radio was disabled or transmitting. 862 */ 863 otError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel); 864 865 /** 866 * Schedule a radio reception window at a specific time and duration. 867 * 868 * After a radio reception is successfully scheduled for a future time and duration, a subsequent call to this 869 * function MUST be handled as follows: 870 * 871 * - If the start time of the previously scheduled reception window has not yet been reached, the new call to 872 * `otPlatRadioReceiveAt()` MUST cancel the previous schedule, effectively replacing it. 873 * 874 * - If the start of the previous window has already passed, the previous receive schedule is already being executed 875 * by the radio and MUST NOT be replaced or impacted. The new call to `otPlatRadioReceiveAt()` would then schedule 876 * a new future receive window. In particular, if the new `otPlatRadioReceiveAt()` call occurs after the start 877 * but while still within the previous reception window, the ongoing reception window MUST NOT be impacted. 878 * 879 * @param[in] aChannel The radio channel on which to receive. 880 * @param[in] aStart The receive window start time relative to the local 881 * radio clock, see `otPlatRadioGetNow`. The radio 882 * receiver SHALL be on and ready to receive the first 883 * symbol of a frame's SHR at the window start time. 884 * @param[in] aDuration The receive window duration, in microseconds, as 885 * measured by the local radio clock. The radio SHOULD be 886 * turned off (or switched to TX mode if an ACK frame 887 * needs to be sent) after that duration unless it is 888 * still actively receiving a frame. In the latter case 889 * the radio SHALL be kept in reception mode until frame 890 * reception has either succeeded or failed. 891 * 892 * @retval OT_ERROR_NONE Successfully scheduled receive window. 893 * @retval OT_ERROR_FAILED The receive window could not be scheduled. For example, if @p aStart is in the past. 894 */ 895 otError otPlatRadioReceiveAt(otInstance *aInstance, uint8_t aChannel, uint32_t aStart, uint32_t aDuration); 896 897 /** 898 * The radio driver calls this method to notify OpenThread of a received frame. 899 * 900 * @param[in] aInstance The OpenThread instance structure. 901 * @param[in] aFrame A pointer to the received frame or NULL if the receive operation failed. 902 * @param[in] aError OT_ERROR_NONE when successfully received a frame, 903 * OT_ERROR_ABORT when reception was aborted and a frame was not received, 904 * OT_ERROR_NO_BUFS when a frame could not be received due to lack of rx buffer space. 905 */ 906 extern void otPlatRadioReceiveDone(otInstance *aInstance, otRadioFrame *aFrame, otError aError); 907 908 /** 909 * The radio driver calls this method to notify OpenThread diagnostics module of a received frame. 910 * 911 * Is used when diagnostics is enabled. 912 * 913 * @param[in] aInstance The OpenThread instance structure. 914 * @param[in] aFrame A pointer to the received frame or NULL if the receive operation failed. 915 * @param[in] aError OT_ERROR_NONE when successfully received a frame, 916 * OT_ERROR_ABORT when reception was aborted and a frame was not received, 917 * OT_ERROR_NO_BUFS when a frame could not be received due to lack of rx buffer space. 918 */ 919 extern void otPlatDiagRadioReceiveDone(otInstance *aInstance, otRadioFrame *aFrame, otError aError); 920 921 /** 922 * Get the radio transmit frame buffer. 923 * 924 * OpenThread forms the IEEE 802.15.4 frame in this buffer then calls `otPlatRadioTransmit()` to request transmission. 925 * 926 * @param[in] aInstance The OpenThread instance structure. 927 * 928 * @returns A pointer to the transmit frame buffer. 929 */ 930 otRadioFrame *otPlatRadioGetTransmitBuffer(otInstance *aInstance); 931 932 /** 933 * Begin the transmit sequence on the radio. 934 * 935 * The caller must form the IEEE 802.15.4 frame in the buffer provided by `otPlatRadioGetTransmitBuffer()` before 936 * requesting transmission. The channel and transmit power are also included in the otRadioFrame structure. 937 * 938 * The transmit sequence consists of: 939 * 1. Transitioning the radio to Transmit from one of the following states: 940 * - Receive if RX is on when the device is idle or OT_RADIO_CAPS_SLEEP_TO_TX is not supported 941 * - Sleep if RX is off when the device is idle and OT_RADIO_CAPS_SLEEP_TO_TX is supported. 942 * 2. Transmits the psdu on the given channel and at the given transmit power. 943 * 944 * @param[in] aInstance The OpenThread instance structure. 945 * @param[in] aFrame A pointer to the frame to be transmitted. 946 * 947 * @retval OT_ERROR_NONE Successfully transitioned to Transmit. 948 * @retval OT_ERROR_INVALID_STATE The radio was not in the Receive state. 949 */ 950 otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aFrame); 951 952 /** 953 * The radio driver calls this method to notify OpenThread that the transmission has started. 954 * 955 * @note This function should be called by the same thread that executes all of the other OpenThread code. It should 956 * not be called by ISR or any other task. 957 * 958 * @param[in] aInstance A pointer to the OpenThread instance structure. 959 * @param[in] aFrame A pointer to the frame that is being transmitted. 960 */ 961 extern void otPlatRadioTxStarted(otInstance *aInstance, otRadioFrame *aFrame); 962 963 /** 964 * The radio driver calls this function to notify OpenThread that the transmit operation has completed, 965 * providing both the transmitted frame and, if applicable, the received ack frame. 966 * 967 * When radio provides `OT_RADIO_CAPS_TRANSMIT_SEC` capability, radio platform layer updates @p aFrame 968 * with the security frame counter and key index values maintained by the radio. 969 * 970 * @param[in] aInstance The OpenThread instance structure. 971 * @param[in] aFrame A pointer to the frame that was transmitted. 972 * @param[in] aAckFrame A pointer to the ACK frame, NULL if no ACK was received. 973 * @param[in] aError OT_ERROR_NONE when the frame was transmitted, 974 * OT_ERROR_NO_ACK when the frame was transmitted but no ACK was received, 975 * OT_ERROR_CHANNEL_ACCESS_FAILURE tx could not take place due to activity on the channel, 976 * OT_ERROR_ABORT when transmission was aborted for other reasons. 977 */ 978 extern void otPlatRadioTxDone(otInstance *aInstance, otRadioFrame *aFrame, otRadioFrame *aAckFrame, otError aError); 979 980 /** 981 * The radio driver calls this method to notify OpenThread diagnostics module that the transmission has completed. 982 * 983 * Is used when diagnostics is enabled. 984 * 985 * @param[in] aInstance The OpenThread instance structure. 986 * @param[in] aFrame A pointer to the frame that was transmitted. 987 * @param[in] aError OT_ERROR_NONE when the frame was transmitted, 988 * OT_ERROR_CHANNEL_ACCESS_FAILURE tx could not take place due to activity on the channel, 989 * OT_ERROR_ABORT when transmission was aborted for other reasons. 990 */ 991 extern void otPlatDiagRadioTransmitDone(otInstance *aInstance, otRadioFrame *aFrame, otError aError); 992 993 /** 994 * Get the most recent RSSI measurement. 995 * 996 * @param[in] aInstance The OpenThread instance structure. 997 * 998 * @returns The RSSI in dBm when it is valid. 127 when RSSI is invalid. 999 */ 1000 int8_t otPlatRadioGetRssi(otInstance *aInstance); 1001 1002 /** 1003 * Begin the energy scan sequence on the radio. 1004 * 1005 * Is used when radio provides OT_RADIO_CAPS_ENERGY_SCAN capability. 1006 * 1007 * @param[in] aInstance The OpenThread instance structure. 1008 * @param[in] aScanChannel The channel to perform the energy scan on. 1009 * @param[in] aScanDuration The duration, in milliseconds, for the channel to be scanned. 1010 * 1011 * @retval OT_ERROR_NONE Successfully started scanning the channel. 1012 * @retval OT_ERROR_BUSY The radio is performing energy scanning. 1013 * @retval OT_ERROR_NOT_IMPLEMENTED The radio doesn't support energy scanning. 1014 */ 1015 otError otPlatRadioEnergyScan(otInstance *aInstance, uint8_t aScanChannel, uint16_t aScanDuration); 1016 1017 /** 1018 * The radio driver calls this method to notify OpenThread that the energy scan is complete. 1019 * 1020 * Is used when radio provides OT_RADIO_CAPS_ENERGY_SCAN capability. 1021 * 1022 * @param[in] aInstance The OpenThread instance structure. 1023 * @param[in] aEnergyScanMaxRssi The maximum RSSI encountered on the scanned channel. 1024 */ 1025 extern void otPlatRadioEnergyScanDone(otInstance *aInstance, int8_t aEnergyScanMaxRssi); 1026 1027 /** 1028 * The radio driver calls this method to notify OpenThread that the spinel bus latency has been changed. 1029 * 1030 * @param[in] aInstance The OpenThread instance structure. 1031 */ 1032 extern void otPlatRadioBusLatencyChanged(otInstance *aInstance); 1033 1034 /** 1035 * Enable/Disable source address match feature. 1036 * 1037 * The source address match feature controls how the radio layer decides the "frame pending" bit for acks sent in 1038 * response to data request commands from children. 1039 * 1040 * If disabled, the radio layer must set the "frame pending" on all acks to data request commands. 1041 * 1042 * If enabled, the radio layer uses the source address match table to determine whether to set or clear the "frame 1043 * pending" bit in an ack to a data request command. 1044 * 1045 * The source address match table provides the list of children for which there is a pending frame. Either a short 1046 * address or an extended/long address can be added to the source address match table. 1047 * 1048 * @param[in] aInstance The OpenThread instance structure. 1049 * @param[in] aEnable Enable/disable source address match feature. 1050 */ 1051 void otPlatRadioEnableSrcMatch(otInstance *aInstance, bool aEnable); 1052 1053 /** 1054 * Add a short address to the source address match table. 1055 * 1056 * @param[in] aInstance The OpenThread instance structure. 1057 * @param[in] aShortAddress The short address to be added. 1058 * 1059 * @retval OT_ERROR_NONE Successfully added short address to the source match table. 1060 * @retval OT_ERROR_NO_BUFS No available entry in the source match table. 1061 */ 1062 otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, otShortAddress aShortAddress); 1063 1064 /** 1065 * Add an extended address to the source address match table. 1066 * 1067 * @param[in] aInstance The OpenThread instance structure. 1068 * @param[in] aExtAddress The extended address to be added stored in little-endian byte order. 1069 * 1070 * @retval OT_ERROR_NONE Successfully added extended address to the source match table. 1071 * @retval OT_ERROR_NO_BUFS No available entry in the source match table. 1072 */ 1073 otError otPlatRadioAddSrcMatchExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress); 1074 1075 /** 1076 * Remove a short address from the source address match table. 1077 * 1078 * @param[in] aInstance The OpenThread instance structure. 1079 * @param[in] aShortAddress The short address to be removed. 1080 * 1081 * @retval OT_ERROR_NONE Successfully removed short address from the source match table. 1082 * @retval OT_ERROR_NO_ADDRESS The short address is not in source address match table. 1083 */ 1084 otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, otShortAddress aShortAddress); 1085 1086 /** 1087 * Remove an extended address from the source address match table. 1088 * 1089 * @param[in] aInstance The OpenThread instance structure. 1090 * @param[in] aExtAddress The extended address to be removed stored in little-endian byte order. 1091 * 1092 * @retval OT_ERROR_NONE Successfully removed the extended address from the source match table. 1093 * @retval OT_ERROR_NO_ADDRESS The extended address is not in source address match table. 1094 */ 1095 otError otPlatRadioClearSrcMatchExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress); 1096 1097 /** 1098 * Clear all short addresses from the source address match table. 1099 * 1100 * @param[in] aInstance The OpenThread instance structure. 1101 */ 1102 void otPlatRadioClearSrcMatchShortEntries(otInstance *aInstance); 1103 1104 /** 1105 * Clear all the extended/long addresses from source address match table. 1106 * 1107 * @param[in] aInstance The OpenThread instance structure. 1108 */ 1109 void otPlatRadioClearSrcMatchExtEntries(otInstance *aInstance); 1110 1111 /** 1112 * Get the radio supported channel mask that the device is allowed to be on. 1113 * 1114 * @param[in] aInstance The OpenThread instance structure. 1115 * 1116 * @returns The radio supported channel mask. 1117 */ 1118 uint32_t otPlatRadioGetSupportedChannelMask(otInstance *aInstance); 1119 1120 /** 1121 * Gets the radio preferred channel mask that the device prefers to form on. 1122 * 1123 * @param[in] aInstance The OpenThread instance structure. 1124 * 1125 * @returns The radio preferred channel mask. 1126 */ 1127 uint32_t otPlatRadioGetPreferredChannelMask(otInstance *aInstance); 1128 1129 /** 1130 * Enable the radio coex. 1131 * 1132 * Is used when feature OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE is enabled. 1133 * 1134 * @param[in] aInstance The OpenThread instance structure. 1135 * @param[in] aEnabled TRUE to enable the radio coex, FALSE otherwise. 1136 * 1137 * @retval OT_ERROR_NONE Successfully enabled. 1138 * @retval OT_ERROR_FAILED The radio coex could not be enabled. 1139 */ 1140 otError otPlatRadioSetCoexEnabled(otInstance *aInstance, bool aEnabled); 1141 1142 /** 1143 * Check whether radio coex is enabled or not. 1144 * 1145 * Is used when feature OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE is enabled. 1146 * 1147 * @param[in] aInstance The OpenThread instance structure. 1148 * 1149 * @returns TRUE if the radio coex is enabled, FALSE otherwise. 1150 */ 1151 bool otPlatRadioIsCoexEnabled(otInstance *aInstance); 1152 1153 /** 1154 * Get the radio coexistence metrics. 1155 * 1156 * Is used when feature OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE is enabled. 1157 * 1158 * @param[in] aInstance The OpenThread instance structure. 1159 * @param[out] aCoexMetrics A pointer to the coexistence metrics structure. 1160 * 1161 * @retval OT_ERROR_NONE Successfully retrieved the coex metrics. 1162 * @retval OT_ERROR_INVALID_ARGS @p aCoexMetrics was NULL. 1163 */ 1164 otError otPlatRadioGetCoexMetrics(otInstance *aInstance, otRadioCoexMetrics *aCoexMetrics); 1165 1166 /** 1167 * Enable or disable CSL receiver. 1168 * 1169 * @param[in] aInstance The OpenThread instance structure. 1170 * @param[in] aCslPeriod CSL period, 0 for disabling CSL. CSL period is in unit of 10 symbols. 1171 * @param[in] aShortAddr The short source address of CSL receiver's peer. 1172 * @param[in] aExtAddr The extended source address of CSL receiver's peer. 1173 * 1174 * @note Platforms should use CSL peer addresses to include CSL IE when generating enhanced acks. 1175 * 1176 * @retval OT_ERROR_NOT_IMPLEMENTED Radio driver doesn't support CSL. 1177 * @retval OT_ERROR_FAILED Other platform specific errors. 1178 * @retval OT_ERROR_NONE Successfully enabled or disabled CSL. 1179 */ 1180 otError otPlatRadioEnableCsl(otInstance *aInstance, 1181 uint32_t aCslPeriod, 1182 otShortAddress aShortAddr, 1183 const otExtAddress *aExtAddr); 1184 1185 /** 1186 * Reset CSL receiver in the platform. 1187 * 1188 * @note Defaults to `otPlatRadioEnableCsl(aInstance,0, Mac::kShortAddrInvalid, nullptr);` 1189 * 1190 * @param[in] aInstance The OpenThread instance structure. 1191 * 1192 * @retval OT_ERROR_NOT_IMPLEMENTED Radio driver doesn't support CSL. 1193 * @retval OT_ERROR_FAILED Other platform specific errors. 1194 * @retval OT_ERROR_NONE Successfully disabled CSL. 1195 */ 1196 otError otPlatRadioResetCsl(otInstance *aInstance); 1197 1198 /** 1199 * Update CSL sample time in radio driver. 1200 * 1201 * Sample time is stored in radio driver as a copy to calculate phase when 1202 * sending ACK with CSL IE. The CSL sample (window) of the CSL receiver extends 1203 * before and after the sample time. The CSL sample time marks a timestamp in 1204 * the CSL sample window when a frame should be received in "ideal conditions" 1205 * if there would be no inaccuracy/clock-drift. 1206 * 1207 * @param[in] aInstance The OpenThread instance structure. 1208 * @param[in] aCslSampleTime The next sample time, in microseconds. It is 1209 * the time when the first symbol of the MHR of 1210 * the frame is expected. 1211 */ 1212 void otPlatRadioUpdateCslSampleTime(otInstance *aInstance, uint32_t aCslSampleTime); 1213 1214 /** 1215 * Get the current estimated worst case accuracy (maximum ± deviation from the 1216 * nominal frequency) of the local radio clock in units of PPM. This is the 1217 * clock used to schedule CSL operations. 1218 * 1219 * @note Implementations MAY estimate this value based on current operating 1220 * conditions (e.g. temperature). 1221 * 1222 * In case the implementation does not estimate the current value but returns a 1223 * fixed value, this value MUST be the worst-case accuracy over all possible 1224 * foreseen operating conditions (temperature, pressure, etc) of the 1225 * implementation. 1226 * 1227 * @param[in] aInstance A pointer to an OpenThread instance. 1228 * 1229 * @returns The current CSL rx/tx scheduling drift, in PPM. 1230 */ 1231 uint8_t otPlatRadioGetCslAccuracy(otInstance *aInstance); 1232 1233 /** 1234 * The fixed uncertainty (i.e. random jitter) of the arrival time of CSL 1235 * transmissions received by this device in units of 10 microseconds. 1236 * 1237 * This designates the worst case constant positive or negative deviation of 1238 * the actual arrival time of a transmission from the transmission time 1239 * calculated relative to the local radio clock independent of elapsed time. In 1240 * addition to uncertainty accumulated over elapsed time, the CSL channel sample 1241 * ("RX window") must be extended by twice this deviation such that an actual 1242 * transmission is guaranteed to be detected by the local receiver in the 1243 * presence of random arrival time jitter. 1244 * 1245 * @param[in] aInstance A pointer to an OpenThread instance. 1246 * 1247 * @returns The CSL Uncertainty in units of 10 us. 1248 */ 1249 uint8_t otPlatRadioGetCslUncertainty(otInstance *aInstance); 1250 1251 /** 1252 * Set the max transmit power for a specific channel. 1253 * 1254 * @note This function will be deprecated in October 2027. It is recommended to use the function 1255 * `otPlatRadioSetChannelTargetPower()`. 1256 * 1257 * @param[in] aInstance The OpenThread instance structure. 1258 * @param[in] aChannel The radio channel. 1259 * @param[in] aMaxPower The max power in dBm, passing OT_RADIO_RSSI_INVALID will disable this channel. 1260 * 1261 * @retval OT_ERROR_NOT_IMPLEMENTED The feature is not implemented 1262 * @retval OT_ERROR_INVALID_ARGS The specified channel is not valid. 1263 * @retval OT_ERROR_FAILED Other platform specific errors. 1264 * @retval OT_ERROR_NONE Successfully set max transmit power. 1265 */ 1266 otError otPlatRadioSetChannelMaxTransmitPower(otInstance *aInstance, uint8_t aChannel, int8_t aMaxPower); 1267 1268 /** 1269 * Set the region code. 1270 * 1271 * The radio region format is the 2-bytes ascii representation of the 1272 * ISO 3166 alpha-2 code. 1273 * 1274 * @param[in] aInstance The OpenThread instance structure. 1275 * @param[in] aRegionCode The radio region code. The `aRegionCode >> 8` is first ascii char 1276 * and the `aRegionCode & 0xff` is the second ascii char. 1277 * 1278 * @retval OT_ERROR_FAILED Other platform specific errors. 1279 * @retval OT_ERROR_NONE Successfully set region code. 1280 * @retval OT_ERROR_NOT_IMPLEMENTED The feature is not implemented. 1281 */ 1282 otError otPlatRadioSetRegion(otInstance *aInstance, uint16_t aRegionCode); 1283 1284 /** 1285 * Get the region code. 1286 * 1287 * The radio region format is the 2-bytes ascii representation of the 1288 * ISO 3166 alpha-2 code. 1289 1290 * @param[in] aInstance The OpenThread instance structure. 1291 * @param[out] aRegionCode The radio region. 1292 * 1293 * @retval OT_ERROR_INVALID_ARGS @p aRegionCode is nullptr. 1294 * @retval OT_ERROR_FAILED Other platform specific errors. 1295 * @retval OT_ERROR_NONE Successfully got region code. 1296 * @retval OT_ERROR_NOT_IMPLEMENTED The feature is not implemented. 1297 */ 1298 otError otPlatRadioGetRegion(otInstance *aInstance, uint16_t *aRegionCode); 1299 1300 /** 1301 * Enable/disable or update Enhanced-ACK Based Probing in radio for a specific Initiator. 1302 * 1303 * After Enhanced-ACK Based Probing is configured by a specific Probing Initiator, the Enhanced-ACK sent to that 1304 * node should include Vendor-Specific IE containing Link Metrics data. This method informs the radio to start/stop to 1305 * collect Link Metrics data and include Vendor-Specific IE that containing the data in Enhanced-ACK sent to that 1306 * Probing Initiator. 1307 * 1308 * @param[in] aInstance The OpenThread instance structure. 1309 * @param[in] aLinkMetrics This parameter specifies what metrics to query. Per spec 4.11.3.4.4.6, at most 2 metrics 1310 * can be specified. The probing would be disabled if @p `aLinkMetrics` is bitwise 0. 1311 * @param[in] aShortAddress The short address of the Probing Initiator. 1312 * @param[in] aExtAddress The extended source address of the Probing Initiator. @p aExtAddr MUST NOT be `NULL`. 1313 * 1314 * @retval OT_ERROR_NONE Successfully configured the Enhanced-ACK Based Probing. 1315 * @retval OT_ERROR_INVALID_ARGS @p aExtAddress is `NULL`. 1316 * @retval OT_ERROR_NOT_FOUND The Initiator indicated by @p aShortAddress is not found when trying to clear. 1317 * @retval OT_ERROR_NO_BUFS No more Initiator can be supported. 1318 * @retval OT_ERROR_NOT_IMPLEMENTED The feature is not implemented. 1319 */ 1320 otError otPlatRadioConfigureEnhAckProbing(otInstance *aInstance, 1321 otLinkMetrics aLinkMetrics, 1322 otShortAddress aShortAddress, 1323 const otExtAddress *aExtAddress); 1324 1325 /** 1326 * Add a calibrated power of the specified channel to the power calibration table. 1327 * 1328 * @note This API is an optional radio platform API. It's up to the platform layer to implement it. 1329 * 1330 * The @p aActualPower is the actual measured output power when the parameters of the radio hardware modules 1331 * are set to the @p aRawPowerSetting. 1332 * 1333 * The raw power setting is an opaque byte array. OpenThread doesn't define the format of the raw power setting. 1334 * Its format is radio hardware related and it should be defined by the developers in the platform radio driver. 1335 * For example, if the radio hardware contains both the radio chip and the FEM chip, the raw power setting can be 1336 * a combination of the radio power register and the FEM gain value. 1337 * 1338 * @param[in] aInstance The OpenThread instance structure. 1339 * @param[in] aChannel The radio channel. 1340 * @param[in] aActualPower The actual power in 0.01dBm. 1341 * @param[in] aRawPowerSetting A pointer to the raw power setting byte array. 1342 * @param[in] aRawPowerSettingLength The length of the @p aRawPowerSetting. 1343 * 1344 * @retval OT_ERROR_NONE Successfully added the calibrated power to the power calibration table. 1345 * @retval OT_ERROR_NO_BUFS No available entry in the power calibration table. 1346 * @retval OT_ERROR_INVALID_ARGS The @p aChannel, @p aActualPower or @p aRawPowerSetting is invalid or the 1347 * @p aActualPower already exists in the power calibration table. 1348 * @retval OT_ERROR_NOT_IMPLEMENTED This feature is not implemented. 1349 */ 1350 otError otPlatRadioAddCalibratedPower(otInstance *aInstance, 1351 uint8_t aChannel, 1352 int16_t aActualPower, 1353 const uint8_t *aRawPowerSetting, 1354 uint16_t aRawPowerSettingLength); 1355 1356 /** 1357 * Clear all calibrated powers from the power calibration table. 1358 * 1359 * @note This API is an optional radio platform API. It's up to the platform layer to implement it. 1360 * 1361 * @param[in] aInstance The OpenThread instance structure. 1362 * 1363 * @retval OT_ERROR_NONE Successfully cleared all calibrated powers from the power calibration table. 1364 * @retval OT_ERROR_NOT_IMPLEMENTED This feature is not implemented. 1365 */ 1366 otError otPlatRadioClearCalibratedPowers(otInstance *aInstance); 1367 1368 /** 1369 * Set the target power for the given channel. 1370 * 1371 * @note This API is an optional radio platform API. It's up to the platform layer to implement it. 1372 * If this function and `otPlatRadioSetTransmitPower()` are implemented at the same time: 1373 * - If neither of these two functions is called, the radio outputs the platform-defined default power. 1374 * - If both functions are called, the last one to be called takes effect. 1375 * 1376 * The radio driver should set the actual output power to be less than or equal to the @p aTargetPower and as close 1377 * as possible to the @p aTargetPower. If the @p aTargetPower is lower than the minimum output power supported 1378 * by the platform, the output power should be set to the minimum output power supported by the platform. If the 1379 * @p aTargetPower is higher than the maximum output power supported by the platform, the output power should be 1380 * set to the maximum output power supported by the platform. If the @p aTargetPower is set to `INT16_MAX`, the 1381 * corresponding channel is disabled. 1382 * 1383 * @param[in] aInstance The OpenThread instance structure. 1384 * @param[in] aChannel The radio channel. 1385 * @param[in] aTargetPower The target power in 0.01dBm. 1386 * 1387 * @retval OT_ERROR_NONE Successfully set the target power. 1388 * @retval OT_ERROR_INVALID_ARGS The @p aChannel is invalid. 1389 * @retval OT_ERROR_NOT_IMPLEMENTED The feature is not implemented. 1390 */ 1391 otError otPlatRadioSetChannelTargetPower(otInstance *aInstance, uint8_t aChannel, int16_t aTargetPower); 1392 1393 /** 1394 * Get the raw power setting for the given channel. 1395 * 1396 * @note OpenThread `src/core/utils` implements a default implementation of the API `otPlatRadioAddCalibratedPower()`, 1397 * `otPlatRadioClearCalibratedPowers()` and `otPlatRadioSetChannelTargetPower()`. This API is provided by 1398 * the default implementation to get the raw power setting for the given channel. If the platform doesn't 1399 * use the default implementation, it can ignore this API. 1400 * 1401 * Platform radio layer should parse the raw power setting based on the radio layer defined format and set the 1402 * parameters of each radio hardware module. 1403 * 1404 * @param[in] aInstance The OpenThread instance structure. 1405 * @param[in] aChannel The radio channel. 1406 * @param[out] aRawPowerSetting A pointer to the raw power setting byte array. 1407 * @param[in,out] aRawPowerSettingLength On input, a pointer to the size of @p aRawPowerSetting. 1408 * On output, a pointer to the length of the raw power setting data. 1409 * 1410 * @retval OT_ERROR_NONE Successfully got the target power. 1411 * @retval OT_ERROR_INVALID_ARGS The @p aChannel is invalid, @p aRawPowerSetting or @p aRawPowerSettingLength is NULL 1412 * or @aRawPowerSettingLength is too short. 1413 * @retval OT_ERROR_NOT_FOUND The raw power setting for the @p aChannel was not found. 1414 */ 1415 extern otError otPlatRadioGetRawPowerSetting(otInstance *aInstance, 1416 uint8_t aChannel, 1417 uint8_t *aRawPowerSetting, 1418 uint16_t *aRawPowerSettingLength); 1419 1420 /** 1421 * @} 1422 */ 1423 1424 /** 1425 * @} 1426 */ 1427 1428 #ifdef __cplusplus 1429 } // end of extern "C" 1430 #endif 1431 1432 #endif // OPENTHREAD_PLATFORM_RADIO_H_ 1433