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  * @param[in]   aInstance    A pointer to an OpenThread instance.
706  * @param[in]   aKeyIdMode   The key ID mode.
707  * @param[in]   aKeyId       Current MAC key index.
708  * @param[in]   aPrevKey     A pointer to the previous MAC key.
709  * @param[in]   aCurrKey     A pointer to the current MAC key.
710  * @param[in]   aNextKey     A pointer to the next MAC key.
711  * @param[in]   aKeyType     Key Type used.
712  */
713 void otPlatRadioSetMacKey(otInstance             *aInstance,
714                           uint8_t                 aKeyIdMode,
715                           uint8_t                 aKeyId,
716                           const otMacKeyMaterial *aPrevKey,
717                           const otMacKeyMaterial *aCurrKey,
718                           const otMacKeyMaterial *aNextKey,
719                           otRadioKeyType          aKeyType);
720 
721 /**
722  * Sets the current MAC frame counter value.
723  *
724  * Is used when radio provides `OT_RADIO_CAPS_TRANSMIT_SEC` capability.
725  *
726  * @param[in]   aInstance         A pointer to an OpenThread instance.
727  * @param[in]   aMacFrameCounter  The MAC frame counter value.
728  */
729 void otPlatRadioSetMacFrameCounter(otInstance *aInstance, uint32_t aMacFrameCounter);
730 
731 /**
732  * Sets the current MAC frame counter value only if the new given value is larger than the current value.
733  *
734  * Is used when radio provides `OT_RADIO_CAPS_TRANSMIT_SEC` capability.
735  *
736  * @param[in]   aInstance         A pointer to an OpenThread instance.
737  * @param[in]   aMacFrameCounter  The MAC frame counter value.
738  */
739 void otPlatRadioSetMacFrameCounterIfLarger(otInstance *aInstance, uint32_t aMacFrameCounter);
740 
741 /**
742  * Get the current time in microseconds referenced to a continuous monotonic
743  * local radio clock (64 bits width).
744  *
745  * The radio clock SHALL NOT wrap during the device's uptime. Implementations
746  * SHALL therefore identify and compensate for internal counter overflows. The
747  * clock does not have a defined epoch and it SHALL NOT introduce any continuous
748  * or discontinuous adjustments (e.g. leap seconds). Implementations SHALL
749  * compensate for any sleep times of the device.
750  *
751  * Implementations MAY choose to discipline the radio clock and compensate for
752  * sleep times by any means (e.g. by combining a high precision/low power RTC
753  * with a high resolution counter) as long as the exposed combined clock
754  * provides continuous monotonic microsecond resolution ticks within the
755  * accuracy limits announced by @ref otPlatRadioGetCslAccuracy.
756  *
757  * @param[in]   aInstance    A pointer to an OpenThread instance.
758  *
759  * @returns The current time in microseconds. UINT64_MAX when platform does not
760  * support or radio time is not ready.
761  */
762 uint64_t otPlatRadioGetNow(otInstance *aInstance);
763 
764 /**
765  * Get the bus speed in bits/second between the host and the radio chip.
766  *
767  * @param[in]   aInstance    A pointer to an OpenThread instance.
768  *
769  * @returns The bus speed in bits/second between the host and the radio chip.
770  *          Return 0 when the MAC and above layer and Radio layer resides on the same chip.
771  */
772 uint32_t otPlatRadioGetBusSpeed(otInstance *aInstance);
773 
774 /**
775  * Get the bus latency in microseconds between the host and the radio chip.
776  *
777  * @param[in]   aInstance    A pointer to an OpenThread instance.
778  *
779  * @returns The bus latency in microseconds between the host and the radio chip.
780  *          Return 0 when the MAC and above layer and Radio layer resides on the same chip.
781  */
782 uint32_t otPlatRadioGetBusLatency(otInstance *aInstance);
783 
784 /**
785  * @}
786  */
787 
788 /**
789  * @defgroup radio-operation Radio Operation
790  *
791  * @brief
792  *   This module includes the platform abstraction for radio operations.
793  *
794  * @{
795  */
796 
797 /**
798  * Get current state of the radio.
799  *
800  * Is not required by OpenThread. It may be used for debugging and/or application-specific purposes.
801  *
802  * @note This function may be not implemented. It does not affect OpenThread.
803  *
804  * @param[in] aInstance  The OpenThread instance structure.
805  *
806  * @return  Current state of the radio.
807  */
808 otRadioState otPlatRadioGetState(otInstance *aInstance);
809 
810 /**
811  * Enable the radio.
812  *
813  * @param[in] aInstance  The OpenThread instance structure.
814  *
815  * @retval OT_ERROR_NONE     Successfully enabled.
816  * @retval OT_ERROR_FAILED   The radio could not be enabled.
817  */
818 otError otPlatRadioEnable(otInstance *aInstance);
819 
820 /**
821  * Disable the radio.
822  *
823  * @param[in] aInstance  The OpenThread instance structure.
824  *
825  * @retval OT_ERROR_NONE            Successfully transitioned to Disabled.
826  * @retval OT_ERROR_INVALID_STATE   The radio was not in sleep state.
827  */
828 otError otPlatRadioDisable(otInstance *aInstance);
829 
830 /**
831  * Check whether radio is enabled or not.
832  *
833  * @param[in] aInstance  The OpenThread instance structure.
834  *
835  * @returns TRUE if the radio is enabled, FALSE otherwise.
836  */
837 bool otPlatRadioIsEnabled(otInstance *aInstance);
838 
839 /**
840  * Transition the radio from Receive to Sleep (turn off the radio).
841  *
842  * @param[in] aInstance  The OpenThread instance structure.
843  *
844  * @retval OT_ERROR_NONE          Successfully transitioned to Sleep.
845  * @retval OT_ERROR_BUSY          The radio was transmitting.
846  * @retval OT_ERROR_INVALID_STATE The radio was disabled.
847  */
848 otError otPlatRadioSleep(otInstance *aInstance);
849 
850 /**
851  * Transition the radio from Sleep to Receive (turn on the radio).
852  *
853  * @param[in]  aInstance  The OpenThread instance structure.
854  * @param[in]  aChannel   The channel to use for receiving.
855  *
856  * @retval OT_ERROR_NONE          Successfully transitioned to Receive.
857  * @retval OT_ERROR_INVALID_STATE The radio was disabled or transmitting.
858  */
859 otError otPlatRadioReceive(otInstance *aInstance, uint8_t aChannel);
860 
861 /**
862  * Schedule a radio reception window at a specific time and duration.
863  *
864  * @param[in]  aChannel   The radio channel on which to receive.
865  * @param[in]  aStart     The receive window start time relative to the local
866  *                        radio clock, see `otPlatRadioGetNow`. The radio
867  *                        receiver SHALL be on and ready to receive the first
868  *                        symbol of a frame's SHR at the window start time.
869  * @param[in]  aDuration  The receive window duration, in microseconds, as
870  *                        measured by the local radio clock. The radio SHOULD be
871  *                        turned off (or switched to TX mode if an ACK frame
872  *                        needs to be sent) after that duration unless it is
873  *                        still actively receiving a frame. In the latter case
874  *                        the radio SHALL be kept in reception mode until frame
875  *                        reception has either succeeded or failed.
876  *
877  * @retval OT_ERROR_NONE    Successfully scheduled receive window.
878  * @retval OT_ERROR_FAILED  The receive window could not be scheduled.
879  */
880 otError otPlatRadioReceiveAt(otInstance *aInstance, uint8_t aChannel, uint32_t aStart, uint32_t aDuration);
881 
882 /**
883  * The radio driver calls this method to notify OpenThread of a received frame.
884  *
885  * @param[in]  aInstance The OpenThread instance structure.
886  * @param[in]  aFrame    A pointer to the received frame or NULL if the receive operation failed.
887  * @param[in]  aError    OT_ERROR_NONE when successfully received a frame,
888  *                       OT_ERROR_ABORT when reception was aborted and a frame was not received,
889  *                       OT_ERROR_NO_BUFS when a frame could not be received due to lack of rx buffer space.
890  */
891 extern void otPlatRadioReceiveDone(otInstance *aInstance, otRadioFrame *aFrame, otError aError);
892 
893 /**
894  * The radio driver calls this method to notify OpenThread diagnostics module of a received frame.
895  *
896  * Is used when diagnostics is enabled.
897  *
898  * @param[in]  aInstance The OpenThread instance structure.
899  * @param[in]  aFrame    A pointer to the received frame or NULL if the receive operation failed.
900  * @param[in]  aError    OT_ERROR_NONE when successfully received a frame,
901  *                       OT_ERROR_ABORT when reception was aborted and a frame was not received,
902  *                       OT_ERROR_NO_BUFS when a frame could not be received due to lack of rx buffer space.
903  */
904 extern void otPlatDiagRadioReceiveDone(otInstance *aInstance, otRadioFrame *aFrame, otError aError);
905 
906 /**
907  * Get the radio transmit frame buffer.
908  *
909  * OpenThread forms the IEEE 802.15.4 frame in this buffer then calls `otPlatRadioTransmit()` to request transmission.
910  *
911  * @param[in] aInstance  The OpenThread instance structure.
912  *
913  * @returns A pointer to the transmit frame buffer.
914  */
915 otRadioFrame *otPlatRadioGetTransmitBuffer(otInstance *aInstance);
916 
917 /**
918  * Begin the transmit sequence on the radio.
919  *
920  * The caller must form the IEEE 802.15.4 frame in the buffer provided by `otPlatRadioGetTransmitBuffer()` before
921  * requesting transmission.  The channel and transmit power are also included in the otRadioFrame structure.
922  *
923  * The transmit sequence consists of:
924  * 1. Transitioning the radio to Transmit from one of the following states:
925  *    - Receive if RX is on when the device is idle or OT_RADIO_CAPS_SLEEP_TO_TX is not supported
926  *    - Sleep if RX is off when the device is idle and OT_RADIO_CAPS_SLEEP_TO_TX is supported.
927  * 2. Transmits the psdu on the given channel and at the given transmit power.
928  *
929  * @param[in] aInstance  The OpenThread instance structure.
930  * @param[in] aFrame     A pointer to the frame to be transmitted.
931  *
932  * @retval OT_ERROR_NONE          Successfully transitioned to Transmit.
933  * @retval OT_ERROR_INVALID_STATE The radio was not in the Receive state.
934  */
935 otError otPlatRadioTransmit(otInstance *aInstance, otRadioFrame *aFrame);
936 
937 /**
938  * The radio driver calls this method to notify OpenThread that the transmission has started.
939  *
940  * @note  This function should be called by the same thread that executes all of the other OpenThread code. It should
941  *        not be called by ISR or any other task.
942  *
943  * @param[in]  aInstance  A pointer to the OpenThread instance structure.
944  * @param[in]  aFrame     A pointer to the frame that is being transmitted.
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 extern void otPlatRadioTxDone(otInstance *aInstance, otRadioFrame *aFrame, otRadioFrame *aAckFrame, otError aError);
964 
965 /**
966  * The radio driver calls this method to notify OpenThread diagnostics module that the transmission has completed.
967  *
968  * Is used when diagnostics is enabled.
969  *
970  * @param[in]  aInstance      The OpenThread instance structure.
971  * @param[in]  aFrame         A pointer to the frame that was transmitted.
972  * @param[in]  aError         OT_ERROR_NONE when the frame was transmitted,
973  *                            OT_ERROR_CHANNEL_ACCESS_FAILURE tx could not take place due to activity on the channel,
974  *                            OT_ERROR_ABORT when transmission was aborted for other reasons.
975  */
976 extern void otPlatDiagRadioTransmitDone(otInstance *aInstance, otRadioFrame *aFrame, otError aError);
977 
978 /**
979  * Get the most recent RSSI measurement.
980  *
981  * @param[in] aInstance  The OpenThread instance structure.
982  *
983  * @returns The RSSI in dBm when it is valid.  127 when RSSI is invalid.
984  */
985 int8_t otPlatRadioGetRssi(otInstance *aInstance);
986 
987 /**
988  * Begin the energy scan sequence on the radio.
989  *
990  * Is used when radio provides OT_RADIO_CAPS_ENERGY_SCAN capability.
991  *
992  * @param[in] aInstance      The OpenThread instance structure.
993  * @param[in] aScanChannel   The channel to perform the energy scan on.
994  * @param[in] aScanDuration  The duration, in milliseconds, for the channel to be scanned.
995  *
996  * @retval OT_ERROR_NONE             Successfully started scanning the channel.
997  * @retval OT_ERROR_BUSY             The radio is performing energy scanning.
998  * @retval OT_ERROR_NOT_IMPLEMENTED  The radio doesn't support energy scanning.
999  */
1000 otError otPlatRadioEnergyScan(otInstance *aInstance, uint8_t aScanChannel, uint16_t aScanDuration);
1001 
1002 /**
1003  * The radio driver calls this method to notify OpenThread that the energy scan is complete.
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]  aEnergyScanMaxRssi  The maximum RSSI encountered on the scanned channel.
1009  */
1010 extern void otPlatRadioEnergyScanDone(otInstance *aInstance, int8_t aEnergyScanMaxRssi);
1011 
1012 /**
1013  * The radio driver calls this method to notify OpenThread that the spinel bus latency has been changed.
1014  *
1015  * @param[in]  aInstance  The OpenThread instance structure.
1016  */
1017 extern void otPlatRadioBusLatencyChanged(otInstance *aInstance);
1018 
1019 /**
1020  * Enable/Disable source address match feature.
1021  *
1022  * The source address match feature controls how the radio layer decides the "frame pending" bit for acks sent in
1023  * response to data request commands from children.
1024  *
1025  * If disabled, the radio layer must set the "frame pending" on all acks to data request commands.
1026  *
1027  * If enabled, the radio layer uses the source address match table to determine whether to set or clear the "frame
1028  * pending" bit in an ack to a data request command.
1029  *
1030  * The source address match table provides the list of children for which there is a pending frame. Either a short
1031  * address or an extended/long address can be added to the source address match table.
1032  *
1033  * @param[in]  aInstance   The OpenThread instance structure.
1034  * @param[in]  aEnable     Enable/disable source address match feature.
1035  */
1036 void otPlatRadioEnableSrcMatch(otInstance *aInstance, bool aEnable);
1037 
1038 /**
1039  * Add a short address to the source address match table.
1040  *
1041  * @param[in]  aInstance      The OpenThread instance structure.
1042  * @param[in]  aShortAddress  The short address to be added.
1043  *
1044  * @retval OT_ERROR_NONE      Successfully added short address to the source match table.
1045  * @retval OT_ERROR_NO_BUFS   No available entry in the source match table.
1046  */
1047 otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, otShortAddress aShortAddress);
1048 
1049 /**
1050  * Add an extended address to the source address match table.
1051  *
1052  * @param[in]  aInstance    The OpenThread instance structure.
1053  * @param[in]  aExtAddress  The extended address to be added stored in little-endian byte order.
1054  *
1055  * @retval OT_ERROR_NONE      Successfully added extended address to the source match table.
1056  * @retval OT_ERROR_NO_BUFS   No available entry in the source match table.
1057  */
1058 otError otPlatRadioAddSrcMatchExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress);
1059 
1060 /**
1061  * Remove a short address from the source address match table.
1062  *
1063  * @param[in]  aInstance      The OpenThread instance structure.
1064  * @param[in]  aShortAddress  The short address to be removed.
1065  *
1066  * @retval OT_ERROR_NONE        Successfully removed short address from the source match table.
1067  * @retval OT_ERROR_NO_ADDRESS  The short address is not in source address match table.
1068  */
1069 otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, otShortAddress aShortAddress);
1070 
1071 /**
1072  * Remove an extended address from the source address match table.
1073  *
1074  * @param[in]  aInstance    The OpenThread instance structure.
1075  * @param[in]  aExtAddress  The extended address to be removed stored in little-endian byte order.
1076  *
1077  * @retval OT_ERROR_NONE        Successfully removed the extended address from the source match table.
1078  * @retval OT_ERROR_NO_ADDRESS  The extended address is not in source address match table.
1079  */
1080 otError otPlatRadioClearSrcMatchExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress);
1081 
1082 /**
1083  * Clear all short addresses from the source address match table.
1084  *
1085  * @param[in]  aInstance   The OpenThread instance structure.
1086  */
1087 void otPlatRadioClearSrcMatchShortEntries(otInstance *aInstance);
1088 
1089 /**
1090  * Clear all the extended/long addresses from source address match table.
1091  *
1092  * @param[in]  aInstance   The OpenThread instance structure.
1093  */
1094 void otPlatRadioClearSrcMatchExtEntries(otInstance *aInstance);
1095 
1096 /**
1097  * Get the radio supported channel mask that the device is allowed to be on.
1098  *
1099  * @param[in]  aInstance   The OpenThread instance structure.
1100  *
1101  * @returns The radio supported channel mask.
1102  */
1103 uint32_t otPlatRadioGetSupportedChannelMask(otInstance *aInstance);
1104 
1105 /**
1106  * Gets the radio preferred channel mask that the device prefers to form on.
1107  *
1108  * @param[in]  aInstance   The OpenThread instance structure.
1109  *
1110  * @returns The radio preferred channel mask.
1111  */
1112 uint32_t otPlatRadioGetPreferredChannelMask(otInstance *aInstance);
1113 
1114 /**
1115  * Enable the radio coex.
1116  *
1117  * Is used when feature OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE is enabled.
1118  *
1119  * @param[in] aInstance  The OpenThread instance structure.
1120  * @param[in] aEnabled   TRUE to enable the radio coex, FALSE otherwise.
1121  *
1122  * @retval OT_ERROR_NONE     Successfully enabled.
1123  * @retval OT_ERROR_FAILED   The radio coex could not be enabled.
1124  */
1125 otError otPlatRadioSetCoexEnabled(otInstance *aInstance, bool aEnabled);
1126 
1127 /**
1128  * Check whether radio coex is enabled or not.
1129  *
1130  * Is used when feature OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE is enabled.
1131  *
1132  * @param[in] aInstance  The OpenThread instance structure.
1133  *
1134  * @returns TRUE if the radio coex is enabled, FALSE otherwise.
1135  */
1136 bool otPlatRadioIsCoexEnabled(otInstance *aInstance);
1137 
1138 /**
1139  * Get the radio coexistence metrics.
1140  *
1141  * Is used when feature OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE is enabled.
1142  *
1143  * @param[in]  aInstance     The OpenThread instance structure.
1144  * @param[out] aCoexMetrics  A pointer to the coexistence metrics structure.
1145  *
1146  * @retval OT_ERROR_NONE          Successfully retrieved the coex metrics.
1147  * @retval OT_ERROR_INVALID_ARGS  @p aCoexMetrics was NULL.
1148  */
1149 otError otPlatRadioGetCoexMetrics(otInstance *aInstance, otRadioCoexMetrics *aCoexMetrics);
1150 
1151 /**
1152  * Enable or disable CSL receiver.
1153  *
1154  * @param[in]  aInstance     The OpenThread instance structure.
1155  * @param[in]  aCslPeriod    CSL period, 0 for disabling CSL. CSL period is in unit of 10 symbols.
1156  * @param[in]  aShortAddr    The short source address of CSL receiver's peer.
1157  * @param[in]  aExtAddr      The extended source address of CSL receiver's peer.
1158  *
1159  * @note Platforms should use CSL peer addresses to include CSL IE when generating enhanced acks.
1160  *
1161  * @retval  OT_ERROR_NOT_IMPLEMENTED Radio driver doesn't support CSL.
1162  * @retval  OT_ERROR_FAILED          Other platform specific errors.
1163  * @retval  OT_ERROR_NONE            Successfully enabled or disabled CSL.
1164  */
1165 otError otPlatRadioEnableCsl(otInstance         *aInstance,
1166                              uint32_t            aCslPeriod,
1167                              otShortAddress      aShortAddr,
1168                              const otExtAddress *aExtAddr);
1169 
1170 /**
1171  * Reset CSL receiver in the platform.
1172  *
1173  * @note Defaults to `otPlatRadioEnableCsl(aInstance,0, Mac::kShortAddrInvalid, nullptr);`
1174  *
1175  * @param[in]  aInstance     The OpenThread instance structure.
1176  *
1177  * @retval  OT_ERROR_NOT_IMPLEMENTED Radio driver doesn't support CSL.
1178  * @retval  OT_ERROR_FAILED          Other platform specific errors.
1179  * @retval  OT_ERROR_NONE            Successfully disabled CSL.
1180  */
1181 otError otPlatRadioResetCsl(otInstance *aInstance);
1182 
1183 /**
1184  * Update CSL sample time in radio driver.
1185  *
1186  * Sample time is stored in radio driver as a copy to calculate phase when
1187  * sending ACK with CSL IE. The CSL sample (window) of the CSL receiver extends
1188  * before and after the sample time. The CSL sample time marks a timestamp in
1189  * the CSL sample window when a frame should be received in "ideal conditions"
1190  * if there would be no inaccuracy/clock-drift.
1191  *
1192  * @param[in]  aInstance         The OpenThread instance structure.
1193  * @param[in]  aCslSampleTime    The next sample time, in microseconds. It is
1194  *                               the time when the first symbol of the MHR of
1195  *                               the frame is expected.
1196  */
1197 void otPlatRadioUpdateCslSampleTime(otInstance *aInstance, uint32_t aCslSampleTime);
1198 
1199 /**
1200  * Get the current estimated worst case accuracy (maximum ± deviation from the
1201  * nominal frequency) of the local radio clock in units of PPM. This is the
1202  * clock used to schedule CSL operations.
1203  *
1204  * @note Implementations MAY estimate this value based on current operating
1205  * conditions (e.g. temperature).
1206  *
1207  * In case the implementation does not estimate the current value but returns a
1208  * fixed value, this value MUST be the worst-case accuracy over all possible
1209  * foreseen operating conditions (temperature, pressure, etc) of the
1210  * implementation.
1211  *
1212  * @param[in]   aInstance    A pointer to an OpenThread instance.
1213  *
1214  * @returns The current CSL rx/tx scheduling drift, in PPM.
1215  */
1216 uint8_t otPlatRadioGetCslAccuracy(otInstance *aInstance);
1217 
1218 /**
1219  * The fixed uncertainty (i.e. random jitter) of the arrival time of CSL
1220  * transmissions received by this device in units of 10 microseconds.
1221  *
1222  * This designates the worst case constant positive or negative deviation of
1223  * the actual arrival time of a transmission from the transmission time
1224  * calculated relative to the local radio clock independent of elapsed time. In
1225  * addition to uncertainty accumulated over elapsed time, the CSL channel sample
1226  * ("RX window") must be extended by twice this deviation such that an actual
1227  * transmission is guaranteed to be detected by the local receiver in the
1228  * presence of random arrival time jitter.
1229  *
1230  * @param[in]   aInstance    A pointer to an OpenThread instance.
1231  *
1232  * @returns The CSL Uncertainty in units of 10 us.
1233  */
1234 uint8_t otPlatRadioGetCslUncertainty(otInstance *aInstance);
1235 
1236 /**
1237  * Set the max transmit power for a specific channel.
1238  *
1239  * @note This function will be deprecated in October 2027. It is recommended to use the function
1240  *       `otPlatRadioSetChannelTargetPower()`.
1241  *
1242  * @param[in]  aInstance    The OpenThread instance structure.
1243  * @param[in]  aChannel     The radio channel.
1244  * @param[in]  aMaxPower    The max power in dBm, passing OT_RADIO_RSSI_INVALID will disable this channel.
1245  *
1246  * @retval  OT_ERROR_NOT_IMPLEMENTED  The feature is not implemented
1247  * @retval  OT_ERROR_INVALID_ARGS     The specified channel is not valid.
1248  * @retval  OT_ERROR_FAILED           Other platform specific errors.
1249  * @retval  OT_ERROR_NONE             Successfully set max transmit power.
1250  */
1251 otError otPlatRadioSetChannelMaxTransmitPower(otInstance *aInstance, uint8_t aChannel, int8_t aMaxPower);
1252 
1253 /**
1254  * Set the region code.
1255  *
1256  * The radio region format is the 2-bytes ascii representation of the
1257  * ISO 3166 alpha-2 code.
1258  *
1259  * @param[in]  aInstance    The OpenThread instance structure.
1260  * @param[in]  aRegionCode  The radio region code. The `aRegionCode >> 8` is first ascii char
1261  *                          and the `aRegionCode & 0xff` is the second ascii char.
1262  *
1263  * @retval  OT_ERROR_FAILED           Other platform specific errors.
1264  * @retval  OT_ERROR_NONE             Successfully set region code.
1265  * @retval  OT_ERROR_NOT_IMPLEMENTED  The feature is not implemented.
1266  */
1267 otError otPlatRadioSetRegion(otInstance *aInstance, uint16_t aRegionCode);
1268 
1269 /**
1270  * Get the region code.
1271  *
1272  * The radio region format is the 2-bytes ascii representation of the
1273  * ISO 3166 alpha-2 code.
1274 
1275  * @param[in]  aInstance    The OpenThread instance structure.
1276  * @param[out] aRegionCode  The radio region.
1277  *
1278  * @retval  OT_ERROR_INVALID_ARGS     @p aRegionCode is nullptr.
1279  * @retval  OT_ERROR_FAILED           Other platform specific errors.
1280  * @retval  OT_ERROR_NONE             Successfully got region code.
1281  * @retval  OT_ERROR_NOT_IMPLEMENTED  The feature is not implemented.
1282  */
1283 otError otPlatRadioGetRegion(otInstance *aInstance, uint16_t *aRegionCode);
1284 
1285 /**
1286  * Enable/disable or update Enhanced-ACK Based Probing in radio for a specific Initiator.
1287  *
1288  * After Enhanced-ACK Based Probing is configured by a specific Probing Initiator, the Enhanced-ACK sent to that
1289  * node should include Vendor-Specific IE containing Link Metrics data. This method informs the radio to start/stop to
1290  * collect Link Metrics data and include Vendor-Specific IE that containing the data in Enhanced-ACK sent to that
1291  * Probing Initiator.
1292  *
1293  * @param[in]  aInstance     The OpenThread instance structure.
1294  * @param[in]  aLinkMetrics  This parameter specifies what metrics to query. Per spec 4.11.3.4.4.6, at most 2 metrics
1295  *                           can be specified. The probing would be disabled if @p `aLinkMetrics` is bitwise 0.
1296  * @param[in]  aShortAddress The short address of the Probing Initiator.
1297  * @param[in]  aExtAddress   The extended source address of the Probing Initiator. @p aExtAddr MUST NOT be `NULL`.
1298  *
1299  * @retval  OT_ERROR_NONE            Successfully configured the Enhanced-ACK Based Probing.
1300  * @retval  OT_ERROR_INVALID_ARGS    @p aExtAddress is `NULL`.
1301  * @retval  OT_ERROR_NOT_FOUND       The Initiator indicated by @p aShortAddress is not found when trying to clear.
1302  * @retval  OT_ERROR_NO_BUFS         No more Initiator can be supported.
1303  * @retval  OT_ERROR_NOT_IMPLEMENTED The feature is not implemented.
1304  */
1305 otError otPlatRadioConfigureEnhAckProbing(otInstance         *aInstance,
1306                                           otLinkMetrics       aLinkMetrics,
1307                                           otShortAddress      aShortAddress,
1308                                           const otExtAddress *aExtAddress);
1309 
1310 /**
1311  * Add a calibrated power of the specified channel to the power calibration table.
1312  *
1313  * @note This API is an optional radio platform API. It's up to the platform layer to implement it.
1314  *
1315  * The @p aActualPower is the actual measured output power when the parameters of the radio hardware modules
1316  * are set to the @p aRawPowerSetting.
1317  *
1318  * The raw power setting is an opaque byte array. OpenThread doesn't define the format of the raw power setting.
1319  * Its format is radio hardware related and it should be defined by the developers in the platform radio driver.
1320  * For example, if the radio hardware contains both the radio chip and the FEM chip, the raw power setting can be
1321  * a combination of the radio power register and the FEM gain value.
1322  *
1323  * @param[in] aInstance               The OpenThread instance structure.
1324  * @param[in] aChannel                The radio channel.
1325  * @param[in] aActualPower            The actual power in 0.01dBm.
1326  * @param[in] aRawPowerSetting        A pointer to the raw power setting byte array.
1327  * @param[in] aRawPowerSettingLength  The length of the @p aRawPowerSetting.
1328  *
1329  * @retval OT_ERROR_NONE             Successfully added the calibrated power to the power calibration table.
1330  * @retval OT_ERROR_NO_BUFS          No available entry in the power calibration table.
1331  * @retval OT_ERROR_INVALID_ARGS     The @p aChannel, @p aActualPower or @p aRawPowerSetting is invalid or the
1332  *                                   @p aActualPower already exists in the power calibration table.
1333  * @retval OT_ERROR_NOT_IMPLEMENTED  This feature is not implemented.
1334  */
1335 otError otPlatRadioAddCalibratedPower(otInstance    *aInstance,
1336                                       uint8_t        aChannel,
1337                                       int16_t        aActualPower,
1338                                       const uint8_t *aRawPowerSetting,
1339                                       uint16_t       aRawPowerSettingLength);
1340 
1341 /**
1342  * Clear all calibrated powers from the power calibration table.
1343  *
1344  * @note This API is an optional radio platform API. It's up to the platform layer to implement it.
1345  *
1346  * @param[in]  aInstance   The OpenThread instance structure.
1347  *
1348  * @retval OT_ERROR_NONE             Successfully cleared all calibrated powers from the power calibration table.
1349  * @retval OT_ERROR_NOT_IMPLEMENTED  This feature is not implemented.
1350  */
1351 otError otPlatRadioClearCalibratedPowers(otInstance *aInstance);
1352 
1353 /**
1354  * Set the target power for the given channel.
1355  *
1356  * @note This API is an optional radio platform API. It's up to the platform layer to implement it.
1357  *       If this function and `otPlatRadioSetTransmitPower()` are implemented at the same time:
1358  *       - If neither of these two functions is called, the radio outputs the platform-defined default power.
1359  *       - If both functions are called, the last one to be called takes effect.
1360  *
1361  * The radio driver should set the actual output power to be less than or equal to the @p aTargetPower and as close
1362  * as possible to the @p aTargetPower. If the @p aTargetPower is lower than the minimum output power supported
1363  * by the platform, the output power should be set to the minimum output power supported by the platform.  If the
1364  * @p aTargetPower is higher than the maximum output power supported by the platform, the output power should be
1365  * set to the maximum output power supported by the platform. If the @p aTargetPower is set to `INT16_MAX`, the
1366  * corresponding channel is disabled.
1367  *
1368  * @param[in]  aInstance     The OpenThread instance structure.
1369  * @param[in]  aChannel      The radio channel.
1370  * @param[in]  aTargetPower  The target power in 0.01dBm.
1371  *
1372  * @retval  OT_ERROR_NONE             Successfully set the target power.
1373  * @retval  OT_ERROR_INVALID_ARGS     The @p aChannel is invalid.
1374  * @retval  OT_ERROR_NOT_IMPLEMENTED  The feature is not implemented.
1375  */
1376 otError otPlatRadioSetChannelTargetPower(otInstance *aInstance, uint8_t aChannel, int16_t aTargetPower);
1377 
1378 /**
1379  * Get the raw power setting for the given channel.
1380  *
1381  * @note OpenThread `src/core/utils` implements a default implementation of the API `otPlatRadioAddCalibratedPower()`,
1382  *       `otPlatRadioClearCalibratedPowers()` and `otPlatRadioSetChannelTargetPower()`. This API is provided by
1383  *       the default implementation to get the raw power setting for the given channel. If the platform doesn't
1384  *       use the default implementation, it can ignore this API.
1385  *
1386  * Platform radio layer should parse the raw power setting based on the radio layer defined format and set the
1387  * parameters of each radio hardware module.
1388  *
1389  * @param[in]      aInstance               The OpenThread instance structure.
1390  * @param[in]      aChannel                The radio channel.
1391  * @param[out]     aRawPowerSetting        A pointer to the raw power setting byte array.
1392  * @param[in,out]  aRawPowerSettingLength  On input, a pointer to the size of @p aRawPowerSetting.
1393  *                                         On output, a pointer to the length of the raw power setting data.
1394  *
1395  * @retval  OT_ERROR_NONE          Successfully got the target power.
1396  * @retval  OT_ERROR_INVALID_ARGS  The @p aChannel is invalid, @p aRawPowerSetting or @p aRawPowerSettingLength is NULL
1397  *                                 or @aRawPowerSettingLength is too short.
1398  * @retval  OT_ERROR_NOT_FOUND     The raw power setting for the @p aChannel was not found.
1399  */
1400 extern otError otPlatRadioGetRawPowerSetting(otInstance *aInstance,
1401                                              uint8_t     aChannel,
1402                                              uint8_t    *aRawPowerSetting,
1403                                              uint16_t   *aRawPowerSettingLength);
1404 
1405 /**
1406  * @}
1407  */
1408 
1409 /**
1410  * @}
1411  */
1412 
1413 #ifdef __cplusplus
1414 } // end of extern "C"
1415 #endif
1416 
1417 #endif // OPENTHREAD_PLATFORM_RADIO_H_
1418