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