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