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