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