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 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 /** 59 * @defgroup radio-types Types 60 * 61 * @brief 62 * This module includes the platform abstraction for a radio frame. 63 * 64 * @{ 65 * 66 */ 67 68 enum 69 { 70 OT_RADIO_FRAME_MAX_SIZE = 127, ///< aMaxPHYPacketSize (IEEE 802.15.4-2006) 71 OT_RADIO_FRAME_MIN_SIZE = 3, ///< Minimal size of frame FCS + CONTROL 72 OT_RADIO_SYMBOLS_PER_OCTET = 2, ///< 2.4 GHz IEEE 802.15.4-2006 73 OT_RADIO_BIT_RATE = 250000, ///< 2.4 GHz IEEE 802.15.4 (bits per second) 74 OT_RADIO_BITS_PER_OCTET = 8, ///< Number of bits per octet 75 76 OT_RADIO_SYMBOL_TIME = ((OT_RADIO_BITS_PER_OCTET / OT_RADIO_SYMBOLS_PER_OCTET) * 1000000) / OT_RADIO_BIT_RATE, 77 OT_RADIO_LQI_NONE = 0, ///< LQI measurement not supported 78 OT_RADIO_RSSI_INVALID = 127, ///< Invalid or unknown RSSI value 79 OT_RADIO_POWER_INVALID = 127, ///< Invalid or unknown power value 80 }; 81 82 /** 83 * This enumeration defines the channel page. 84 * 85 */ 86 enum 87 { 88 OT_RADIO_CHANNEL_PAGE_0 = 0, ///< 2.4 GHz IEEE 802.15.4-2006 89 OT_RADIO_CHANNEL_PAGE_0_MASK = (1U << OT_RADIO_CHANNEL_PAGE_0), ///< 2.4 GHz IEEE 802.15.4-2006 90 OT_RADIO_CHANNEL_PAGE_2 = 2, ///< 915 MHz IEEE 802.15.4-2006 91 OT_RADIO_CHANNEL_PAGE_2_MASK = (1U << OT_RADIO_CHANNEL_PAGE_2), ///< 915 MHz IEEE 802.15.4-2006 92 }; 93 94 /** 95 * This enumeration defines the frequency band channel range. 96 * 97 */ 98 enum 99 { 100 OT_RADIO_915MHZ_OQPSK_CHANNEL_MIN = 1, ///< 915 MHz IEEE 802.15.4-2006 101 OT_RADIO_915MHZ_OQPSK_CHANNEL_MAX = 10, ///< 915 MHz IEEE 802.15.4-2006 102 OT_RADIO_915MHZ_OQPSK_CHANNEL_MASK = 0x3ff << OT_RADIO_915MHZ_OQPSK_CHANNEL_MIN, ///< 915 MHz IEEE 802.15.4-2006 103 OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN = 11, ///< 2.4 GHz IEEE 802.15.4-2006 104 OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX = 26, ///< 2.4 GHz IEEE 802.15.4-2006 105 OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MASK = 0xffff << OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN, ///< 2.4 GHz IEEE 802.15.4-2006 106 }; 107 108 /** 109 * This type represents radio capabilities. 110 * 111 * The value is a bit-field indicating the capabilities supported by the radio. See `OT_RADIO_CAPS_*` definitions. 112 * 113 */ 114 typedef uint8_t otRadioCaps; 115 116 /** 117 * This enumeration defines constants that are used to indicate different radio capabilities. See `otRadioCaps`. 118 * 119 */ 120 enum 121 { 122 OT_RADIO_CAPS_NONE = 0, ///< Radio supports no capability. 123 OT_RADIO_CAPS_ACK_TIMEOUT = 1 << 0, ///< Radio supports AckTime event. 124 OT_RADIO_CAPS_ENERGY_SCAN = 1 << 1, ///< Radio supports Energy Scans. 125 OT_RADIO_CAPS_TRANSMIT_RETRIES = 1 << 2, ///< Radio supports tx retry logic with collision avoidance (CSMA). 126 OT_RADIO_CAPS_CSMA_BACKOFF = 1 << 3, ///< Radio supports CSMA backoff for frame transmission (but no retry). 127 OT_RADIO_CAPS_SLEEP_TO_TX = 1 << 4, ///< Radio supports direct transition from sleep to TX with CSMA. 128 OT_RADIO_CAPS_TRANSMIT_SEC = 1 << 5, ///< Radio supports tx security. 129 OT_RADIO_CAPS_TRANSMIT_TIMING = 1 << 6, ///< Radio supports tx at specific time. 130 OT_RADIO_CAPS_RECEIVE_TIMING = 1 << 7, ///< Radio supports rx at specific time. 131 }; 132 133 #define OT_PANID_BROADCAST 0xffff ///< IEEE 802.15.4 Broadcast PAN ID 134 135 /** 136 * This type represents the IEEE 802.15.4 PAN ID. 137 * 138 */ 139 typedef uint16_t otPanId; 140 141 /** 142 * This type represents the IEEE 802.15.4 Short Address. 143 * 144 */ 145 typedef uint16_t otShortAddress; 146 147 #define OT_EXT_ADDRESS_SIZE 8 ///< Size of an IEEE 802.15.4 Extended Address (bytes) 148 149 /** 150 * This enumeration defines constants about size of header IE in ACK. 151 * 152 */ 153 enum 154 { 155 OT_IE_HEADER_SIZE = 2, ///< Size of IE header in bytes. 156 OT_CSL_IE_SIZE = 4, ///< Size of CSL IE content in bytes. 157 OT_ACK_IE_MAX_SIZE = 16, ///< Max length for header IE in ACK. 158 OT_ENH_PROBING_IE_DATA_MAX_SIZE = 2, ///< Max length of Link Metrics data in Vendor-Specific IE. 159 }; 160 161 #define CSL_IE_HEADER_BYTES_LO 0x04 ///< Fixed CSL IE header first byte 162 #define CSL_IE_HEADER_BYTES_HI 0x0d ///< Fixed CSL IE header second byte 163 164 /** 165 * @struct otExtAddress 166 * 167 * This structure represents the IEEE 802.15.4 Extended Address. 168 * 169 */ 170 OT_TOOL_PACKED_BEGIN 171 struct otExtAddress 172 { 173 uint8_t m8[OT_EXT_ADDRESS_SIZE]; ///< IEEE 802.15.4 Extended Address bytes 174 } OT_TOOL_PACKED_END; 175 176 /** 177 * This structure represents the IEEE 802.15.4 Extended Address. 178 * 179 */ 180 typedef struct otExtAddress otExtAddress; 181 182 #define OT_MAC_KEY_SIZE 16 ///< Size of the MAC Key in bytes. 183 184 /** 185 * @struct otMacKey 186 * 187 * This structure represents a MAC Key. 188 * 189 */ 190 OT_TOOL_PACKED_BEGIN 191 struct otMacKey 192 { 193 uint8_t m8[OT_MAC_KEY_SIZE]; ///< MAC Key bytes. 194 } OT_TOOL_PACKED_END; 195 196 /** 197 * This structure represents a MAC Key. 198 * 199 */ 200 typedef struct otMacKey otMacKey; 201 202 /** 203 * This structure represents the IEEE 802.15.4 Header IE (Information Element) related information of a radio frame. 204 */ 205 typedef struct otRadioIeInfo 206 { 207 int64_t mNetworkTimeOffset; ///< The time offset to the Thread network time. 208 uint8_t mTimeIeOffset; ///< The Time IE offset from the start of PSDU. 209 uint8_t mTimeSyncSeq; ///< The Time sync sequence. 210 } otRadioIeInfo; 211 212 /** 213 * This structure represents an IEEE 802.15.4 radio frame. 214 */ 215 typedef struct otRadioFrame 216 { 217 uint8_t *mPsdu; ///< The PSDU. 218 219 uint16_t mLength; ///< Length of the PSDU. 220 uint8_t mChannel; ///< Channel used to transmit/receive the frame. 221 222 uint8_t mRadioType; ///< Radio link type - should be ignored by radio driver. 223 224 /** 225 * The union of transmit and receive information for a radio frame. 226 */ 227 union 228 { 229 /** 230 * Structure representing radio frame transmit information. 231 */ 232 struct 233 { 234 const otMacKey *mAesKey; ///< The key used for AES-CCM frame security. 235 otRadioIeInfo * mIeInfo; ///< The pointer to the Header IE(s) related information. 236 uint32_t mTxDelay; ///< The delay time for this transmission (based on `mTxDelayBaseTime`). 237 uint32_t mTxDelayBaseTime; ///< The base time for the transmission delay. 238 uint8_t mMaxCsmaBackoffs; ///< Maximum number of backoffs attempts before declaring CCA failure. 239 uint8_t mMaxFrameRetries; ///< Maximum number of retries allowed after a transmission failure. 240 241 /** 242 * Indicates whether frame counter and CSL IEs are properly updated in the header. 243 * 244 * If the platform layer does not provide `OT_RADIO_CAPS_TRANSMIT_SEC` capability, it can ignore this flag. 245 * 246 * If the platform provides `OT_RADIO_CAPS_TRANSMIT_SEC` capability, then platform is expected to handle tx 247 * security processing and assignment of frame counter. In this case the following behavior is expected: 248 * 249 * When `mIsHeaderUpdated` is set, it indicates that OpenThread core has already set the frame counter and 250 * CSL IEs (if security is enabled) in the prepared frame. The counter is ensured to match the counter value 251 * from the previous attempts of the same frame. The platform should not assign or change the frame counter 252 * (but may still need to perform security processing depending on `mIsSecurityProcessed` flag). 253 * 254 * If `mIsHeaderUpdated` is not set, then the frame counter and key CSL IE not set in the frame by 255 * OpenThread core and it is the responsibility of the radio platform to assign them. The platform 256 * must update the frame header (assign counter and CSL IE values) before sending the frame over the air, 257 * however if the the transmission gets aborted and the frame is never sent over the air (e.g., channel 258 * access error) the platform may choose to not update the header. If the platform updates the header, 259 * it must also set this flag before passing the frame back from the `otPlatRadioTxDone()` callback. 260 * 261 */ 262 bool mIsHeaderUpdated : 1; 263 bool mIsARetx : 1; ///< Indicates whether the frame is a retransmission or not. 264 bool mCsmaCaEnabled : 1; ///< Set to true to enable CSMA-CA for this packet, false otherwise. 265 bool mCslPresent : 1; ///< Set to true if CSL header IE is present. 266 bool mIsSecurityProcessed : 1; ///< True if SubMac should skip the AES processing of this frame. 267 } mTxInfo; 268 269 /** 270 * Structure representing radio frame receive information. 271 */ 272 struct 273 { 274 /** 275 * The timestamp when the frame was received in microseconds. 276 * 277 * The value SHALL be the time when the SFD was received when TIME_SYNC or CSL is enabled. 278 * Otherwise, the time when the MAC frame was fully received is also acceptable. 279 * 280 */ 281 uint64_t mTimestamp; 282 283 uint32_t mAckFrameCounter; ///< ACK security frame counter (applicable when `mAckedWithSecEnhAck` is set). 284 uint8_t mAckKeyId; ///< ACK security key index (applicable when `mAckedWithSecEnhAck` is set). 285 int8_t mRssi; ///< Received signal strength indicator in dBm for received frames. 286 uint8_t mLqi; ///< Link Quality Indicator for received frames. 287 288 // Flags 289 bool mAckedWithFramePending : 1; ///< This indicates if this frame was acknowledged with frame pending set. 290 bool mAckedWithSecEnhAck : 1; ///< This indicates if this frame was acknowledged with secured enhance ACK. 291 } mRxInfo; 292 } mInfo; 293 } otRadioFrame; 294 295 /** 296 * This structure represents the state of a radio. 297 * Initially, a radio is in the Disabled state. 298 */ 299 typedef enum otRadioState 300 { 301 OT_RADIO_STATE_DISABLED = 0, 302 OT_RADIO_STATE_SLEEP = 1, 303 OT_RADIO_STATE_RECEIVE = 2, 304 OT_RADIO_STATE_TRANSMIT = 3, 305 OT_RADIO_STATE_INVALID = 255, 306 } otRadioState; 307 308 /** 309 * The following are valid radio state transitions: 310 * 311 * (Radio ON) 312 * +----------+ Enable() +-------+ Receive() +---------+ Transmit() +----------+ 313 * | |----------->| |----------->| |-------------->| | 314 * | Disabled | | Sleep | | Receive | | Transmit | 315 * | |<-----------| |<-----------| |<--------------| | 316 * +----------+ Disable() +-------+ Sleep() +---------+ Receive() +----------+ 317 * (Radio OFF) or 318 * signal TransmitDone 319 * 320 * During the IEEE 802.15.4 data request command the transition Sleep->Receive->Transmit 321 * can be shortened to direct transition from Sleep to Transmit if the platform supports 322 * the OT_RADIO_CAPS_SLEEP_TO_TX capability. 323 */ 324 325 /** 326 * This structure represents radio coexistence metrics. 327 */ 328 typedef struct otRadioCoexMetrics 329 { 330 uint32_t mNumGrantGlitch; ///< Number of grant glitches. 331 uint32_t mNumTxRequest; ///< Number of tx requests. 332 uint32_t mNumTxGrantImmediate; ///< Number of tx requests while grant was active. 333 uint32_t mNumTxGrantWait; ///< Number of tx requests while grant was inactive. 334 uint32_t mNumTxGrantWaitActivated; ///< Number of tx requests while grant was inactive that were ultimately granted. 335 uint32_t mNumTxGrantWaitTimeout; ///< Number of tx requests while grant was inactive that timed out. 336 uint32_t mNumTxGrantDeactivatedDuringRequest; ///< Number of tx that were in progress when grant was deactivated. 337 uint32_t mNumTxDelayedGrant; ///< Number of tx requests that were not granted within 50us. 338 uint32_t mAvgTxRequestToGrantTime; ///< Average time in usec from tx request to grant. 339 uint32_t mNumRxRequest; ///< Number of rx requests. 340 uint32_t mNumRxGrantImmediate; ///< Number of rx requests while grant was active. 341 uint32_t mNumRxGrantWait; ///< Number of rx requests while grant was inactive. 342 uint32_t mNumRxGrantWaitActivated; ///< Number of rx requests while grant was inactive that were ultimately granted. 343 uint32_t mNumRxGrantWaitTimeout; ///< Number of rx requests while grant was inactive that timed out. 344 uint32_t mNumRxGrantDeactivatedDuringRequest; ///< Number of rx that were in progress when grant was deactivated. 345 uint32_t mNumRxDelayedGrant; ///< Number of rx requests that were not granted within 50us. 346 uint32_t mAvgRxRequestToGrantTime; ///< Average time in usec from rx request to grant. 347 uint32_t mNumRxGrantNone; ///< Number of rx requests that completed without receiving grant. 348 bool mStopped; ///< Stats collection stopped due to saturation. 349 } otRadioCoexMetrics; 350 351 /** 352 * This structure represents what metrics are specified to query. 353 * 354 */ 355 typedef struct otLinkMetrics 356 { 357 bool mPduCount : 1; ///< Pdu count. 358 bool mLqi : 1; ///< Link Quality Indicator. 359 bool mLinkMargin : 1; ///< Link Margin. 360 bool mRssi : 1; ///< Received Signal Strength Indicator. 361 bool mReserved : 1; ///< Reserved, this is for reference device. 362 } otLinkMetrics; 363 364 /** 365 * @} 366 * 367 */ 368 369 /** 370 * @defgroup radio-config Configuration 371 * 372 * @brief 373 * This module includes the platform abstraction for radio configuration. 374 * 375 * @{ 376 * 377 */ 378 379 /** 380 * Get the radio capabilities. 381 * 382 * @param[in] aInstance The OpenThread instance structure. 383 * 384 * @returns The radio capability bit vector (see `OT_RADIO_CAP_*` definitions). 385 * 386 */ 387 otRadioCaps otPlatRadioGetCaps(otInstance *aInstance); 388 389 /** 390 * Get the radio version string. 391 * 392 * This is an optional radio driver platform function. If not provided by platform radio driver, OpenThread uses 393 * the OpenThread version instead (@sa otGetVersionString()). 394 * 395 * @param[in] aInstance The OpenThread instance structure. 396 * 397 * @returns A pointer to the OpenThread radio version. 398 * 399 */ 400 const char *otPlatRadioGetVersionString(otInstance *aInstance); 401 402 /** 403 * Get the radio receive sensitivity value. 404 * 405 * @param[in] aInstance The OpenThread instance structure. 406 * 407 * @returns The radio receive sensitivity value in dBm. 408 * 409 */ 410 int8_t otPlatRadioGetReceiveSensitivity(otInstance *aInstance); 411 412 /** 413 * Get the factory-assigned IEEE EUI-64 for this interface. 414 * 415 * @param[in] aInstance The OpenThread instance structure. 416 * @param[out] aIeeeEui64 A pointer to the factory-assigned IEEE EUI-64. 417 * 418 */ 419 void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64); 420 421 /** 422 * Set the PAN ID for address filtering. 423 * 424 * @param[in] aInstance The OpenThread instance structure. 425 * @param[in] aPanId The IEEE 802.15.4 PAN ID. 426 * 427 */ 428 void otPlatRadioSetPanId(otInstance *aInstance, otPanId aPanId); 429 430 /** 431 * Set the Extended Address for address filtering. 432 * 433 * @param[in] aInstance The OpenThread instance structure. 434 * @param[in] aExtAddress A pointer to the IEEE 802.15.4 Extended Address stored in little-endian byte order. 435 * 436 * 437 */ 438 void otPlatRadioSetExtendedAddress(otInstance *aInstance, const otExtAddress *aExtAddress); 439 440 /** 441 * Set the Short Address for address filtering. 442 * 443 * @param[in] aInstance The OpenThread instance structure. 444 * @param[in] aShortAddress The IEEE 802.15.4 Short Address. 445 * 446 */ 447 void otPlatRadioSetShortAddress(otInstance *aInstance, otShortAddress aShortAddress); 448 449 /** 450 * Get the radio's transmit power in dBm. 451 * 452 * @note The transmit power returned will be no larger than the power specified in the max power table for 453 * the current channel. 454 * 455 * @param[in] aInstance The OpenThread instance structure. 456 * @param[out] aPower The transmit power in dBm. 457 * 458 * @retval OT_ERROR_NONE Successfully retrieved the transmit power. 459 * @retval OT_ERROR_INVALID_ARGS @p aPower was NULL. 460 * @retval OT_ERROR_NOT_IMPLEMENTED Transmit power configuration via dBm is not implemented. 461 * 462 */ 463 otError otPlatRadioGetTransmitPower(otInstance *aInstance, int8_t *aPower); 464 465 /** 466 * Set the radio's transmit power in dBm. 467 * 468 * @note The real transmit power will be no larger than the power specified in the max power table for 469 * the current channel. 470 * 471 * @param[in] aInstance The OpenThread instance structure. 472 * @param[in] aPower The transmit power in dBm. 473 * 474 * @retval OT_ERROR_NONE Successfully set the transmit power. 475 * @retval OT_ERROR_NOT_IMPLEMENTED Transmit power configuration via dBm is not implemented. 476 * 477 */ 478 otError otPlatRadioSetTransmitPower(otInstance *aInstance, int8_t aPower); 479 480 /** 481 * Get the radio's CCA ED threshold in dBm measured at antenna connector per IEEE 802.15.4 - 2015 section 10.1.4. 482 * 483 * @param[in] aInstance The OpenThread instance structure. 484 * @param[out] aThreshold The CCA ED threshold in dBm. 485 * 486 * @retval OT_ERROR_NONE Successfully retrieved the CCA ED threshold. 487 * @retval OT_ERROR_INVALID_ARGS @p aThreshold was NULL. 488 * @retval OT_ERROR_NOT_IMPLEMENTED CCA ED threshold configuration via dBm is not implemented. 489 * 490 */ 491 otError otPlatRadioGetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t *aThreshold); 492 493 /** 494 * Set the radio's CCA ED threshold in dBm measured at antenna connector per IEEE 802.15.4 - 2015 section 10.1.4. 495 * 496 * @param[in] aInstance The OpenThread instance structure. 497 * @param[in] aThreshold The CCA ED threshold in dBm. 498 * 499 * @retval OT_ERROR_NONE Successfully set the transmit power. 500 * @retval OT_ERROR_INVALID_ARGS Given threshold is out of range. 501 * @retval OT_ERROR_NOT_IMPLEMENTED CCA ED threshold configuration via dBm is not implemented. 502 * 503 */ 504 otError otPlatRadioSetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t aThreshold); 505 506 /** 507 * Get the external FEM's Rx LNA gain in dBm. 508 * 509 * @param[in] aInstance The OpenThread instance structure. 510 * @param[out] aGain The external FEM's Rx LNA gain in dBm. 511 * 512 * @retval OT_ERROR_NONE Successfully retrieved the external FEM's LNA gain. 513 * @retval OT_ERROR_INVALID_ARGS @p aGain was NULL. 514 * @retval OT_ERROR_NOT_IMPLEMENTED External FEM's LNA setting is not implemented. 515 * 516 */ 517 otError otPlatRadioGetFemLnaGain(otInstance *aInstance, int8_t *aGain); 518 519 /** 520 * Set the external FEM's Rx LNA gain in dBm. 521 * 522 * @param[in] aInstance The OpenThread instance structure. 523 * @param[in] aGain The external FEM's Rx LNA gain in dBm. 524 * 525 * @retval OT_ERROR_NONE Successfully set the external FEM's LNA gain. 526 * @retval OT_ERROR_NOT_IMPLEMENTED External FEM's LNA gain setting is not implemented. 527 * 528 */ 529 otError otPlatRadioSetFemLnaGain(otInstance *aInstance, int8_t aGain); 530 531 /** 532 * Get the status of promiscuous mode. 533 * 534 * @param[in] aInstance The OpenThread instance structure. 535 * 536 * @retval TRUE Promiscuous mode is enabled. 537 * @retval FALSE Promiscuous mode is disabled. 538 * 539 */ 540 bool otPlatRadioGetPromiscuous(otInstance *aInstance); 541 542 /** 543 * Enable or disable promiscuous mode. 544 * 545 * @param[in] aInstance The OpenThread instance structure. 546 * @param[in] aEnable TRUE to enable or FALSE to disable promiscuous mode. 547 * 548 */ 549 void otPlatRadioSetPromiscuous(otInstance *aInstance, bool aEnable); 550 551 /** 552 * Update MAC keys and key index 553 * 554 * This function is used when radio provides OT_RADIO_CAPS_TRANSMIT_SEC capability. 555 * 556 * @param[in] aInstance A pointer to an OpenThread instance. 557 * @param[in] aKeyIdMode The key ID mode. 558 * @param[in] aKeyId Current MAC key index. 559 * @param[in] aPrevKey A pointer to the previous MAC key. 560 * @param[in] aCurrKey A pointer to the current MAC key. 561 * @param[in] aNextKey A pointer to the next MAC key. 562 * 563 */ 564 void otPlatRadioSetMacKey(otInstance * aInstance, 565 uint8_t aKeyIdMode, 566 uint8_t aKeyId, 567 const otMacKey *aPrevKey, 568 const otMacKey *aCurrKey, 569 const otMacKey *aNextKey); 570 571 /** 572 * This method sets the current MAC frame counter value. 573 * 574 * This function is used when radio provides `OT_RADIO_CAPS_TRANSMIT_SEC` capability. 575 * 576 * @param[in] aInstance A pointer to an OpenThread instance. 577 * @param[in] aMacFrameCounter The MAC frame counter value. 578 * 579 */ 580 void otPlatRadioSetMacFrameCounter(otInstance *aInstance, uint32_t aMacFrameCounter); 581 582 /** 583 * Get the current estimated time (64bits width) of the radio chip. 584 * 585 * @param[in] aInstance A pointer to an OpenThread instance. 586 * 587 * @returns The current time in microseconds. UINT64_MAX when platform does not support or radio time is not ready. 588 * 589 */ 590 uint64_t otPlatRadioGetNow(otInstance *aInstance); 591 592 /** 593 * Get the bus speed in bits/second between the host and the radio chip. 594 * 595 * @param[in] aInstance A pointer to an OpenThread instance. 596 * 597 * @returns The bus speed in bits/second between the host and the radio chip. 598 * Return 0 when the MAC and above layer and Radio layer resides on the same chip. 599 * 600 */ 601 uint32_t otPlatRadioGetBusSpeed(otInstance *aInstance); 602 603 /** 604 * @} 605 * 606 */ 607 608 /** 609 * @defgroup radio-operation Operation 610 * 611 * @brief 612 * This module includes the platform abstraction for radio operations. 613 * 614 * @{ 615 * 616 */ 617 618 /** 619 * Get current state of the radio. 620 * 621 * This function is not required by OpenThread. It may be used for debugging and/or application-specific purposes. 622 * 623 * @note This function may be not implemented. It does not affect OpenThread. 624 * 625 * @param[in] aInstance The OpenThread instance structure. 626 * 627 * @return Current state of the radio. 628 * 629 */ 630 otRadioState otPlatRadioGetState(otInstance *aInstance); 631 632 /** 633 * Enable the radio. 634 * 635 * @param[in] aInstance The OpenThread instance structure. 636 * 637 * @retval OT_ERROR_NONE Successfully enabled. 638 * @retval OT_ERROR_FAILED The radio could not be enabled. 639 * 640 */ 641 otError otPlatRadioEnable(otInstance *aInstance); 642 643 /** 644 * Disable the radio. 645 * 646 * @param[in] aInstance The OpenThread instance structure. 647 * 648 * @retval OT_ERROR_NONE Successfully transitioned to Disabled. 649 * @retval OT_ERROR_INVALID_STATE The radio was not in sleep state. 650 * 651 */ 652 otError otPlatRadioDisable(otInstance *aInstance); 653 654 /** 655 * Check whether radio is enabled or not. 656 * 657 * @param[in] aInstance The OpenThread instance structure. 658 * 659 * @returns TRUE if the radio is enabled, FALSE otherwise. 660 * 661 */ 662 bool otPlatRadioIsEnabled(otInstance *aInstance); 663 664 /** 665 * Transition the radio from Receive to Sleep (turn off the radio). 666 * 667 * @param[in] aInstance The OpenThread instance structure. 668 * 669 * @retval OT_ERROR_NONE Successfully transitioned to Sleep. 670 * @retval OT_ERROR_BUSY The radio was transmitting. 671 * @retval OT_ERROR_INVALID_STATE The radio was disabled. 672 * 673 */ 674 otError otPlatRadioSleep(otInstance *aInstance); 675 676 /** 677 * Transition the radio from Sleep to Receive (turn on the radio). 678 * 679 * @param[in] aInstance The OpenThread instance structure. 680 * @param[in] aChannel The channel to use for receiving. 681 * 682 * @retval OT_ERROR_NONE Successfully transitioned to Receive. 683 * @retval OT_ERROR_INVALID_STATE The radio was disabled or transmitting. 684 * 685 */ 686 otError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel); 687 688 /** 689 * Schedule a radio reception window at a specific time and duration. 690 * 691 * @param[in] aChannel The radio channel on which to receive. 692 * @param[in] aStart The receive window start time, in microseconds. 693 * @param[in] aDuration The receive window duration, in microseconds 694 * 695 * @retval OT_ERROR_NONE Successfully scheduled receive window. 696 * @retval OT_ERROR_FAILED The receive window could not be scheduled. 697 */ 698 otError otPlatRadioReceiveAt(otInstance *aInstance, uint8_t aChannel, uint32_t aStart, uint32_t aDuration); 699 700 /** 701 * The radio driver calls this method to notify OpenThread of a received frame. 702 * 703 * @param[in] aInstance The OpenThread instance structure. 704 * @param[in] aFrame A pointer to the received frame or NULL if the receive operation failed. 705 * @param[in] aError OT_ERROR_NONE when successfully received a frame, 706 * OT_ERROR_ABORT when reception was aborted and a frame was not received, 707 * OT_ERROR_NO_BUFS when a frame could not be received due to lack of rx buffer space. 708 * 709 */ 710 extern void otPlatRadioReceiveDone(otInstance *aInstance, otRadioFrame *aFrame, otError aError); 711 712 /** 713 * The radio driver calls this method to notify OpenThread diagnostics module of a received frame. 714 * 715 * This function is used when diagnostics is enabled. 716 * 717 * @param[in] aInstance The OpenThread instance structure. 718 * @param[in] aFrame A pointer to the received frame or NULL if the receive operation failed. 719 * @param[in] aError OT_ERROR_NONE when successfully received a frame, 720 * OT_ERROR_ABORT when reception was aborted and a frame was not received, 721 * OT_ERROR_NO_BUFS when a frame could not be received due to lack of rx buffer space. 722 * 723 */ 724 extern void otPlatDiagRadioReceiveDone(otInstance *aInstance, otRadioFrame *aFrame, otError aError); 725 726 /** 727 * Get the radio transmit frame buffer. 728 * 729 * OpenThread forms the IEEE 802.15.4 frame in this buffer then calls `otPlatRadioTransmit()` to request transmission. 730 * 731 * @param[in] aInstance The OpenThread instance structure. 732 * 733 * @returns A pointer to the transmit frame buffer. 734 * 735 */ 736 otRadioFrame *otPlatRadioGetTransmitBuffer(otInstance *aInstance); 737 738 /** 739 * Begin the transmit sequence on the radio. 740 * 741 * The caller must form the IEEE 802.15.4 frame in the buffer provided by `otPlatRadioGetTransmitBuffer()` before 742 * requesting transmission. The channel and transmit power are also included in the otRadioFrame structure. 743 * 744 * The transmit sequence consists of: 745 * 1. Transitioning the radio to Transmit from one of the following states: 746 * - Receive if RX is on when the device is idle or OT_RADIO_CAPS_SLEEP_TO_TX is not supported 747 * - Sleep if RX is off when the device is idle and OT_RADIO_CAPS_SLEEP_TO_TX is supported. 748 * 2. Transmits the psdu on the given channel and at the given transmit power. 749 * 750 * @param[in] aInstance The OpenThread instance structure. 751 * @param[in] aFrame A pointer to the frame to be transmitted. 752 * 753 * @retval OT_ERROR_NONE Successfully transitioned to Transmit. 754 * @retval OT_ERROR_INVALID_STATE The radio was not in the Receive state. 755 * 756 */ 757 otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aFrame); 758 759 /** 760 * The radio driver calls this method to notify OpenThread that the transmission has started. 761 * 762 * @note This function should be called by the same thread that executes all of the other OpenThread code. It should 763 * not be called by ISR or any other task. 764 * 765 * @param[in] aInstance A pointer to the OpenThread instance structure. 766 * @param[in] aFrame A pointer to the frame that is being transmitted. 767 * 768 */ 769 extern void otPlatRadioTxStarted(otInstance *aInstance, otRadioFrame *aFrame); 770 771 /** 772 * The radio driver calls this function to notify OpenThread that the transmit operation has completed, 773 * providing both the transmitted frame and, if applicable, the received ack frame. 774 * 775 * When radio provides `OT_RADIO_CAPS_TRANSMIT_SEC` capability, radio platform layer updates @p aFrame 776 * with the security frame counter and key index values maintained by the radio. 777 * 778 * @param[in] aInstance The OpenThread instance structure. 779 * @param[in] aFrame A pointer to the frame that was transmitted. 780 * @param[in] aAckFrame A pointer to the ACK frame, NULL if no ACK was received. 781 * @param[in] aError OT_ERROR_NONE when the frame was transmitted, 782 * OT_ERROR_NO_ACK when the frame was transmitted but no ACK was received, 783 * OT_ERROR_CHANNEL_ACCESS_FAILURE tx could not take place due to activity on the channel, 784 * OT_ERROR_ABORT when transmission was aborted for other reasons. 785 * 786 */ 787 extern void otPlatRadioTxDone(otInstance *aInstance, otRadioFrame *aFrame, otRadioFrame *aAckFrame, otError aError); 788 789 /** 790 * The radio driver calls this method to notify OpenThread diagnostics module that the transmission has completed. 791 * 792 * This function is used when diagnostics is enabled. 793 * 794 * @param[in] aInstance The OpenThread instance structure. 795 * @param[in] aFrame A pointer to the frame that was transmitted. 796 * @param[in] aError OT_ERROR_NONE when the frame was transmitted, 797 * OT_ERROR_CHANNEL_ACCESS_FAILURE tx could not take place due to activity on the channel, 798 * OT_ERROR_ABORT when transmission was aborted for other reasons. 799 * 800 */ 801 extern void otPlatDiagRadioTransmitDone(otInstance *aInstance, otRadioFrame *aFrame, otError aError); 802 803 /** 804 * Get the most recent RSSI measurement. 805 * 806 * @param[in] aInstance The OpenThread instance structure. 807 * 808 * @returns The RSSI in dBm when it is valid. 127 when RSSI is invalid. 809 * 810 */ 811 int8_t otPlatRadioGetRssi(otInstance *aInstance); 812 813 /** 814 * Begin the energy scan sequence on the radio. 815 * 816 * This function is used when radio provides OT_RADIO_CAPS_ENERGY_SCAN capability. 817 * 818 * @param[in] aInstance The OpenThread instance structure. 819 * @param[in] aScanChannel The channel to perform the energy scan on. 820 * @param[in] aScanDuration The duration, in milliseconds, for the channel to be scanned. 821 * 822 * @retval OT_ERROR_NONE Successfully started scanning the channel. 823 * @retval OT_ERROR_NOT_IMPLEMENTED The radio doesn't support energy scanning. 824 * 825 */ 826 otError otPlatRadioEnergyScan(otInstance *aInstance, uint8_t aScanChannel, uint16_t aScanDuration); 827 828 /** 829 * The radio driver calls this method to notify OpenThread that the energy scan is complete. 830 * 831 * This function is used when radio provides OT_RADIO_CAPS_ENERGY_SCAN capability. 832 * 833 * @param[in] aInstance The OpenThread instance structure. 834 * @param[in] aEnergyScanMaxRssi The maximum RSSI encountered on the scanned channel. 835 * 836 */ 837 extern void otPlatRadioEnergyScanDone(otInstance *aInstance, int8_t aEnergyScanMaxRssi); 838 839 /** 840 * Enable/Disable source address match feature. 841 * 842 * The source address match feature controls how the radio layer decides the "frame pending" bit for acks sent in 843 * response to data request commands from children. 844 * 845 * If disabled, the radio layer must set the "frame pending" on all acks to data request commands. 846 * 847 * If enabled, the radio layer uses the source address match table to determine whether to set or clear the "frame 848 * pending" bit in an ack to a data request command. 849 * 850 * The source address match table provides the list of children for which there is a pending frame. Either a short 851 * address or an extended/long address can be added to the source address match table. 852 * 853 * @param[in] aInstance The OpenThread instance structure. 854 * @param[in] aEnable Enable/disable source address match feature. 855 * 856 */ 857 void otPlatRadioEnableSrcMatch(otInstance *aInstance, bool aEnable); 858 859 /** 860 * Add a short address to the source address match table. 861 * 862 * @param[in] aInstance The OpenThread instance structure. 863 * @param[in] aShortAddress The short address to be added. 864 * 865 * @retval OT_ERROR_NONE Successfully added short address to the source match table. 866 * @retval OT_ERROR_NO_BUFS No available entry in the source match table. 867 * 868 */ 869 otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, otShortAddress aShortAddress); 870 871 /** 872 * Add an extended address to the source address match table. 873 * 874 * @param[in] aInstance The OpenThread instance structure. 875 * @param[in] aExtAddress The extended address to be added stored in little-endian byte order. 876 * 877 * @retval OT_ERROR_NONE Successfully added extended address to the source match table. 878 * @retval OT_ERROR_NO_BUFS No available entry in the source match table. 879 * 880 */ 881 otError otPlatRadioAddSrcMatchExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress); 882 883 /** 884 * Remove a short address from the source address match table. 885 * 886 * @param[in] aInstance The OpenThread instance structure. 887 * @param[in] aShortAddress The short address to be removed. 888 * 889 * @retval OT_ERROR_NONE Successfully removed short address from the source match table. 890 * @retval OT_ERROR_NO_ADDRESS The short address is not in source address match table. 891 * 892 */ 893 otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, otShortAddress aShortAddress); 894 895 /** 896 * Remove an extended address from the source address match table. 897 * 898 * @param[in] aInstance The OpenThread instance structure. 899 * @param[in] aExtAddress The extended address to be removed stored in little-endian byte order. 900 * 901 * @retval OT_ERROR_NONE Successfully removed the extended address from the source match table. 902 * @retval OT_ERROR_NO_ADDRESS The extended address is not in source address match table. 903 * 904 */ 905 otError otPlatRadioClearSrcMatchExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress); 906 907 /** 908 * Clear all short addresses from the source address match table. 909 * 910 * @param[in] aInstance The OpenThread instance structure. 911 * 912 */ 913 void otPlatRadioClearSrcMatchShortEntries(otInstance *aInstance); 914 915 /** 916 * Clear all the extended/long addresses from source address match table. 917 * 918 * @param[in] aInstance The OpenThread instance structure. 919 * 920 */ 921 void otPlatRadioClearSrcMatchExtEntries(otInstance *aInstance); 922 923 /** 924 * Get the radio supported channel mask that the device is allowed to be on. 925 * 926 * @param[in] aInstance The OpenThread instance structure. 927 * 928 * @returns The radio supported channel mask. 929 * 930 */ 931 uint32_t otPlatRadioGetSupportedChannelMask(otInstance *aInstance); 932 933 /** 934 * Get the radio preferred channel mask that the device prefers to form on. 935 * 936 * @param[in] aInstance The OpenThread instance structure. 937 * 938 * @returns The radio preferred channel mask. 939 * 940 */ 941 uint32_t otPlatRadioGetPreferredChannelMask(otInstance *aInstance); 942 943 /** 944 * Enable the radio coex. 945 * 946 * This function is used when feature OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE is enabled. 947 * 948 * @param[in] aInstance The OpenThread instance structure. 949 * @param[in] aEnabled TRUE to enable the radio coex, FALSE otherwise. 950 * 951 * @retval OT_ERROR_NONE Successfully enabled. 952 * @retval OT_ERROR_FAILED The radio coex could not be enabled. 953 * 954 */ 955 otError otPlatRadioSetCoexEnabled(otInstance *aInstance, bool aEnabled); 956 957 /** 958 * Check whether radio coex is enabled or not. 959 * 960 * This function is used when feature OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE is enabled. 961 * 962 * @param[in] aInstance The OpenThread instance structure. 963 * 964 * @returns TRUE if the radio coex is enabled, FALSE otherwise. 965 * 966 */ 967 bool otPlatRadioIsCoexEnabled(otInstance *aInstance); 968 969 /** 970 * Get the radio coexistence metrics. 971 * 972 * This function is used when feature OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE is enabled. 973 * 974 * @param[in] aInstance The OpenThread instance structure. 975 * @param[out] aCoexMetrics A pointer to the coexistence metrics structure. 976 * 977 * @retval OT_ERROR_NONE Successfully retrieved the coex metrics. 978 * @retval OT_ERROR_INVALID_ARGS @p aCoexMetrics was NULL. 979 */ 980 otError otPlatRadioGetCoexMetrics(otInstance *aInstance, otRadioCoexMetrics *aCoexMetrics); 981 982 /** 983 * Enable or disable CSL receiver. 984 * 985 * @param[in] aInstance The OpenThread instance structure. 986 * @param[in] aCslPeriod CSL period, 0 for disabling CSL. 987 * @param[in] aShortAddr The short source address of CSL receiver's peer. 988 * @param[in] aExtAddr The extended source address of CSL receiver's peer. 989 * 990 * @note Platforms should use CSL peer addresses to include CSL IE when generating enhanced acks. 991 * 992 * @retval kErrorNotImplemented Radio driver doesn't support CSL. 993 * @retval kErrorFailed Other platform specific errors. 994 * @retval kErrorNone Successfully enabled or disabled CSL. 995 * 996 */ 997 otError otPlatRadioEnableCsl(otInstance * aInstance, 998 uint32_t aCslPeriod, 999 otShortAddress aShortAddr, 1000 const otExtAddress *aExtAddr); 1001 1002 /** 1003 * Update CSL sample time in radio driver. 1004 * 1005 * Sample time is stored in radio driver as a copy to calculate phase when sending ACK with CSL IE. 1006 * 1007 * @param[in] aInstance The OpenThread instance structure. 1008 * @param[in] aCslSampleTime The latest sample time. 1009 * 1010 */ 1011 void otPlatRadioUpdateCslSampleTime(otInstance *aInstance, uint32_t aCslSampleTime); 1012 1013 /** 1014 * Get the current accuracy, in units of ± ppm, of the clock used for scheduling CSL operations. 1015 * 1016 * @note Platforms may optimize this value based on operational conditions (i.e.: temperature). 1017 * 1018 * @param[in] aInstance A pointer to an OpenThread instance. 1019 * 1020 * @returns The current CSL rx/tx scheduling drift, in units of ± ppm. 1021 * 1022 */ 1023 uint8_t otPlatRadioGetCslAccuracy(otInstance *aInstance); 1024 1025 /** 1026 * Get the current uncertainty, in units of 10 us, of the clock used for scheduling CSL operations. 1027 * 1028 * @param[in] aInstance A pointer to an OpenThread instance. 1029 * 1030 * @returns The current CSL Clock Uncertainty in units of 10 us. 1031 * 1032 */ 1033 uint8_t otPlatRadioGetCslClockUncertainty(otInstance *aInstance); 1034 1035 /** 1036 * Set the max transmit power for a specific channel. 1037 * 1038 * @param[in] aInstance The OpenThread instance structure. 1039 * @param[in] aChannel The radio channel. 1040 * @param[in] aMaxPower The max power in dBm, passing OT_RADIO_RSSI_INVALID will disable this channel. 1041 * 1042 * @retval OT_ERROR_NOT_IMPLEMENTED The feature is not implemented 1043 * @retval OT_ERROR_INVALID_ARGS The specified channel is not valid. 1044 * @retval OT_ERROR_FAILED Other platform specific errors. 1045 * @retval OT_ERROR_NONE Successfully set max transmit poewr. 1046 * 1047 */ 1048 otError otPlatRadioSetChannelMaxTransmitPower(otInstance *aInstance, uint8_t aChannel, int8_t aMaxPower); 1049 1050 /** 1051 * Set the region code. 1052 * 1053 * The radio region format is the 2-bytes ascii representation of the 1054 * ISO 3166 alpha-2 code. 1055 * 1056 * @param[in] aInstance The OpenThread instance structure. 1057 * @param[in] aRegionCode The radio region. 1058 * 1059 * @retval OT_ERROR_FAILED Other platform specific errors. 1060 * @retval OT_ERROR_NONE Successfully set region code. 1061 * 1062 */ 1063 otError otPlatRadioSetRegion(otInstance *aInstance, uint16_t aRegionCode); 1064 1065 /** 1066 * Get the region code. 1067 * 1068 * The radio region format is the 2-bytes ascii representation of the 1069 * ISO 3166 alpha-2 code. 1070 1071 * @param[in] aInstance The OpenThread instance structure. 1072 * @param[out] aRegionCode The radio region. 1073 * 1074 * @retval OT_ERROR_INVALID_ARGS @p aRegionCode is nullptr. 1075 * @retval OT_ERROR_FAILED Other platform specific errors. 1076 * @retval OT_ERROR_NONE Successfully got region code. 1077 * 1078 */ 1079 otError otPlatRadioGetRegion(otInstance *aInstance, uint16_t *aRegionCode); 1080 1081 /** 1082 * Enable/disable or update Enhanced-ACK Based Probing in radio for a specific Initiator. 1083 * 1084 * After Enhanced-ACK Based Probing is configured by a specific Probing Initiator, the Enhanced-ACK sent to that 1085 * node should include Vendor-Specific IE containing Link Metrics data. This method informs the radio to start/stop to 1086 * collect Link Metrics data and include Vendor-Specific IE that containing the data in Enhanced-ACK sent to that 1087 * Probing Initiator. 1088 * 1089 * @param[in] aInstance The OpenThread instance structure. 1090 * @param[in] aLinkMetrics This parameter specifies what metrics to query. Per spec 4.11.3.4.4.6, at most 2 metrics 1091 * can be specified. The probing would be disabled if @p `aLinkMetrics` is bitwise 0. 1092 * @param[in] aShortAddr The short address of the Probing Initiator. 1093 * @param[in] aExtAddr The extended source address of the Probing Initiator. @p aExtAddr MUST NOT be `NULL`. 1094 * 1095 * @retval OT_ERROR_NONE Successfully configured the Enhanced-ACK Based Probing. 1096 * @retval OT_ERROR_INVALID_ARGS @p aExtAddress is `NULL`. 1097 * @retval OT_ERROR_NOT_FOUND The Initiator indicated by @p aShortAddress is not found when trying to clear. 1098 * @retval OT_ERROR_NO_BUFS No more Initiator can be supported. 1099 * 1100 */ 1101 otError otPlatRadioConfigureEnhAckProbing(otInstance * aInstance, 1102 otLinkMetrics aLinkMetrics, 1103 otShortAddress aShortAddress, 1104 const otExtAddress *aExtAddress); 1105 1106 /** 1107 * @} 1108 * 1109 */ 1110 1111 /** 1112 * @} 1113 * 1114 */ 1115 1116 #ifdef __cplusplus 1117 } // end of extern "C" 1118 #endif 1119 1120 #endif // OPENTHREAD_PLATFORM_RADIO_H_ 1121