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