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