1 /*
2 * Copyright (c) 2019, 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 * This file includes definitions for OpenThread radio abstraction.
32 */
33
34 #ifndef RADIO_HPP_
35 #define RADIO_HPP_
36
37 #include "openthread-core-config.h"
38
39 #include <openthread/radio_stats.h>
40 #include <openthread/platform/crypto.h>
41 #include <openthread/platform/radio.h>
42
43 #include "common/locator.hpp"
44 #include "common/non_copyable.hpp"
45 #include "common/numeric_limits.hpp"
46 #include "common/time.hpp"
47 #include "mac/mac_frame.hpp"
48
49 namespace ot {
50
51 static constexpr uint32_t kUsPerTenSymbols = OT_US_PER_TEN_SYMBOLS; ///< Time for 10 symbols in units of microseconds
52 static constexpr uint32_t kRadioHeaderShrDuration = 160; ///< Duration of SHR in us
53 static constexpr uint32_t kRadioHeaderPhrDuration = 32; ///< Duration of PHR in us
54
55 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
56 /**
57 * Minimum CSL period supported in units of 10 symbols.
58 *
59 */
60 static constexpr uint64_t kMinCslPeriod = OPENTHREAD_CONFIG_MAC_CSL_MIN_PERIOD * 1000 / kUsPerTenSymbols;
61 static constexpr uint64_t kMaxCslTimeout = OPENTHREAD_CONFIG_MAC_CSL_MAX_TIMEOUT;
62 #endif
63
64 /**
65 * @addtogroup core-radio
66 *
67 * @brief
68 * This module includes definitions for OpenThread radio abstraction.
69 *
70 * @{
71 *
72 */
73
74 /**
75 * Implements the radio statistics logic.
76 *
77 * The radio statistics are the time when the radio in TX/RX/radio state.
78 * Since this class collects these statistics from pure software level and no platform API is involved, a simplied
79 * model is used to calculate the time of different radio states. The data may not be very accurate, but it's
80 * sufficient to provide a general understanding of the proportion of time a device is in different radio states.
81 *
82 * The simplified model is:
83 * - The RadioStats is only aware of 2 states: RX and sleep.
84 * - Each time `Radio::Receive` or `Radio::Sleep` is called, it will check the current state and add the time since
85 * last time the methods were called. For example, `Sleep` is first called and `Receive` is called after 1 second,
86 * then 1 second will be added to SleepTime and the current state switches to `Receive`.
87 * - The time of TX will be calculated from the callback of TransmitDone. If TX returns OT_ERROR_NONE or
88 * OT_ERROR_NO_ACK, the tx time will be added according to the number of bytes sent. And the SleepTime or RxTime
89 * will be reduced accordingly.
90 * - When `GetStats` is called, an operation will be executed to calcute the time for the last state. And the result
91 * will be returned.
92 *
93 */
94 #if OPENTHREAD_CONFIG_RADIO_STATS_ENABLE && (OPENTHREAD_FTD || OPENTHREAD_MTD)
95
96 #if !OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
97 #error "OPENTHREAD_CONFIG_RADIO_STATS_ENABLE requires OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE".
98 #endif
99
100 class RadioStatistics
101 {
102 public:
103 enum Status : uint8_t
104 {
105 kDisabled,
106 kSleep,
107 kReceive,
108 };
109
110 explicit RadioStatistics(void);
111
112 void RecordStateChange(Status aStatus);
113 void HandleReceiveAt(uint32_t aDurationUs);
114 void RecordTxDone(otError aError, uint16_t aPsduLength);
115 void RecordRxDone(otError aError);
116 const otRadioTimeStats &GetStats(void);
117 void ResetTime(void);
118
119 private:
120 void UpdateTime(void);
121
122 Status mStatus;
123 otRadioTimeStats mTimeStats;
124 TimeMicro mLastUpdateTime;
125 };
126 #endif // OPENTHREAD_CONFIG_RADIO_STATS_ENABLE && (OPENTHREAD_FTD || OPENTHREAD_MTD)
127
128 /**
129 * Represents an OpenThread radio abstraction.
130 *
131 */
132 class Radio : public InstanceLocator, private NonCopyable
133 {
134 friend class Instance;
135
136 public:
137 static constexpr uint32_t kSymbolTime = OT_RADIO_SYMBOL_TIME;
138 static constexpr uint8_t kSymbolsPerOctet = OT_RADIO_SYMBOLS_PER_OCTET;
139 static constexpr uint32_t kPhyUsPerByte = kSymbolsPerOctet * kSymbolTime;
140 static constexpr uint8_t kChannelPage0 = OT_RADIO_CHANNEL_PAGE_0;
141 static constexpr uint8_t kChannelPage2 = OT_RADIO_CHANNEL_PAGE_2;
142 #if (OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT && OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT)
143 static constexpr uint16_t kNumChannelPages = 2;
144 static constexpr uint32_t kSupportedChannels =
145 OT_RADIO_915MHZ_OQPSK_CHANNEL_MASK | OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MASK;
146 static constexpr uint8_t kChannelMin = OT_RADIO_915MHZ_OQPSK_CHANNEL_MIN;
147 static constexpr uint8_t kChannelMax = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX;
148 #elif OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT
149 static constexpr uint16_t kNumChannelPages = 1;
150 static constexpr uint32_t kSupportedChannels = OT_RADIO_915MHZ_OQPSK_CHANNEL_MASK;
151 static constexpr uint8_t kChannelMin = OT_RADIO_915MHZ_OQPSK_CHANNEL_MIN;
152 static constexpr uint8_t kChannelMax = OT_RADIO_915MHZ_OQPSK_CHANNEL_MAX;
153 #elif OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT
154 static constexpr uint16_t kNumChannelPages = 1;
155 static constexpr uint32_t kSupportedChannels = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MASK;
156 static constexpr uint8_t kChannelMin = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN;
157 static constexpr uint8_t kChannelMax = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX;
158 #elif OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_SUPPORT
159 static constexpr uint16_t kNumChannelPages = 1;
160 static constexpr uint32_t kSupportedChannels = OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MASK;
161 static constexpr uint8_t kChannelMin = OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MIN;
162 static constexpr uint8_t kChannelMax = OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MAX;
163 #endif
164
165 static const uint8_t kSupportedChannelPages[kNumChannelPages];
166
167 static constexpr int8_t kInvalidRssi = OT_RADIO_RSSI_INVALID; ///< Invalid RSSI value.
168
169 static constexpr int8_t kDefaultReceiveSensitivity = -110; ///< Default receive sensitivity (in dBm).
170
171 static_assert((OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT || OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT ||
172 OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_SUPPORT),
173 "OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT "
174 "or OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT "
175 "or OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_SUPPORT "
176 "must be set to 1 to specify the radio mode");
177
178 /**
179 * Defines the callbacks from `Radio`.
180 *
181 */
182 class Callbacks : public InstanceLocator
183 {
184 friend class Radio;
185
186 public:
187 /**
188 * This callback method handles a "Receive Done" event from radio platform.
189 *
190 * @param[in] aFrame A pointer to the received frame or `nullptr` if the receive operation failed.
191 * @param[in] aError kErrorNone when successfully received a frame,
192 * kErrorAbort when reception was aborted and a frame was not received,
193 * kErrorNoBufs when a frame could not be received due to lack of rx buffer space.
194 *
195 */
196 void HandleReceiveDone(Mac::RxFrame *aFrame, Error aError);
197
198 /**
199 * This callback method handles a "Transmit Started" event from radio platform.
200 *
201 * @param[in] aFrame The frame that is being transmitted.
202 *
203 */
204 void HandleTransmitStarted(Mac::TxFrame &aFrame);
205
206 /**
207 * This callback method handles a "Transmit Done" event from radio platform.
208 *
209 * @param[in] aFrame The frame that was transmitted.
210 * @param[in] aAckFrame A pointer to the ACK frame, `nullptr` if no ACK was received.
211 * @param[in] aError kErrorNone when the frame was transmitted,
212 * kErrorNoAck when the frame was transmitted but no ACK was received,
213 * kErrorChannelAccessFailure tx could not take place due to activity on the
214 * channel, kErrorAbort when transmission was aborted for other reasons.
215 *
216 */
217 void HandleTransmitDone(Mac::TxFrame &aFrame, Mac::RxFrame *aAckFrame, Error aError);
218
219 /**
220 * This callback method handles "Energy Scan Done" event from radio platform.
221 *
222 * Is used when radio provides OT_RADIO_CAPS_ENERGY_SCAN capability. It is called from
223 * `otPlatRadioEnergyScanDone()`.
224 *
225 * @param[in] aMaxRssi The maximum RSSI encountered on the scanned channel.
226 *
227 */
228 void HandleEnergyScanDone(int8_t aMaxRssi);
229
230 #if OPENTHREAD_CONFIG_DIAG_ENABLE
231 /**
232 * This callback method handles a "Receive Done" event from radio platform when diagnostics mode is enabled.
233 *
234 * @param[in] aFrame A pointer to the received frame or `nullptr` if the receive operation failed.
235 * @param[in] aError kErrorNone when successfully received a frame,
236 * kErrorAbort when reception was aborted and a frame was not received,
237 * kErrorNoBufs when a frame could not be received due to lack of rx buffer space.
238 *
239 */
240 void HandleDiagsReceiveDone(Mac::RxFrame *aFrame, Error aError);
241
242 /**
243 * This callback method handles a "Transmit Done" event from radio platform when diagnostics mode is enabled.
244 *
245 * @param[in] aFrame The frame that was transmitted.
246 * @param[in] aError kErrorNone when the frame was transmitted,
247 * kErrorNoAck when the frame was transmitted but no ACK was received,
248 * kErrorChannelAccessFailure tx could not take place due to activity on the
249 * channel, kErrorAbort when transmission was aborted for other reasons.
250 *
251 */
252 void HandleDiagsTransmitDone(Mac::TxFrame &aFrame, Error aError);
253 #endif
254
255 private:
Callbacks(Instance & aInstance)256 explicit Callbacks(Instance &aInstance)
257 : InstanceLocator(aInstance)
258 {
259 }
260 };
261
262 /**
263 * Initializes the `Radio` object.
264 *
265 * @param[in] aInstance A reference to the OpenThread instance.
266 *
267 */
Radio(Instance & aInstance)268 explicit Radio(Instance &aInstance)
269 : InstanceLocator(aInstance)
270 , mCallbacks(aInstance)
271 {
272 }
273
274 /**
275 * Gets the radio version string.
276 *
277 * @returns A pointer to the OpenThread radio version.
278 *
279 */
280 const char *GetVersionString(void);
281
282 /**
283 * Gets the factory-assigned IEEE EUI-64 for the device.
284 *
285 * @param[out] aIeeeEui64 A reference to `Mac::ExtAddress` to place the factory-assigned IEEE EUI-64.
286 *
287 */
288 void GetIeeeEui64(Mac::ExtAddress &aIeeeEui64);
289
290 /**
291 * Gets the radio capabilities.
292 *
293 * @returns The radio capability bit vector (see `OT_RADIO_CAP_*` definitions).
294 *
295 */
296 otRadioCaps GetCaps(void);
297
298 /**
299 * Gets the radio receive sensitivity value.
300 *
301 * @returns The radio receive sensitivity value in dBm.
302 *
303 */
304 int8_t GetReceiveSensitivity(void) const;
305
306 #if OPENTHREAD_RADIO
307 /**
308 * Initializes the states of the Thread radio.
309 *
310 */
311 void Init(void);
312 #endif
313
314 /**
315 * Sets the PAN ID for address filtering.
316 *
317 * @param[in] aPanId The IEEE 802.15.4 PAN ID.
318 *
319 */
320 void SetPanId(Mac::PanId aPanId);
321
322 /**
323 * Sets the Extended Address for address filtering.
324 *
325 * @param[in] aExtAddress The IEEE 802.15.4 Extended Address stored in little-endian byte order.
326 *
327 */
328 void SetExtendedAddress(const Mac::ExtAddress &aExtAddress);
329
330 /**
331 * Sets the Short Address for address filtering.
332 *
333 * @param[in] aShortAddress The IEEE 802.15.4 Short Address.
334 *
335 */
336 void SetShortAddress(Mac::ShortAddress aShortAddress);
337
338 /**
339 * Sets MAC key and key ID.
340 *
341 * @param[in] aKeyIdMode MAC key ID mode.
342 * @param[in] aKeyId Current MAC key index.
343 * @param[in] aPrevKey The previous MAC key.
344 * @param[in] aCurrKey The current MAC key.
345 * @param[in] aNextKey The next MAC key.
346 *
347 */
348 void SetMacKey(uint8_t aKeyIdMode,
349 uint8_t aKeyId,
350 const Mac::KeyMaterial &aPrevKey,
351 const Mac::KeyMaterial &aCurrKey,
352 const Mac::KeyMaterial &aNextKey);
353
354 /**
355 * Sets the current MAC Frame Counter value.
356 *
357 * @param[in] aMacFrameCounter The MAC Frame Counter value.
358 *
359 */
SetMacFrameCounter(uint32_t aMacFrameCounter)360 void SetMacFrameCounter(uint32_t aMacFrameCounter)
361 {
362 otPlatRadioSetMacFrameCounter(GetInstancePtr(), aMacFrameCounter);
363 }
364
365 /**
366 * Sets the current MAC Frame Counter value only if the new given value is larger than the current
367 * value.
368 *
369 * @param[in] aMacFrameCounter The MAC Frame Counter value.
370 *
371 */
SetMacFrameCounterIfLarger(uint32_t aMacFrameCounter)372 void SetMacFrameCounterIfLarger(uint32_t aMacFrameCounter)
373 {
374 otPlatRadioSetMacFrameCounterIfLarger(GetInstancePtr(), aMacFrameCounter);
375 }
376
377 /**
378 * Gets the radio's transmit power in dBm.
379 *
380 * @param[out] aPower A reference to output the transmit power in dBm.
381 *
382 * @retval kErrorNone Successfully retrieved the transmit power.
383 * @retval kErrorNotImplemented Transmit power configuration via dBm is not implemented.
384 *
385 */
386 Error GetTransmitPower(int8_t &aPower);
387
388 /**
389 * Sets the radio's transmit power in dBm.
390 *
391 * @param[in] aPower The transmit power in dBm.
392 *
393 * @retval kErrorNone Successfully set the transmit power.
394 * @retval kErrorNotImplemented Transmit power configuration via dBm is not implemented.
395 *
396 */
397 Error SetTransmitPower(int8_t aPower);
398
399 /**
400 * Gets the radio's CCA ED threshold in dBm.
401 *
402 * @param[in] aThreshold The CCA ED threshold in dBm.
403 *
404 * @retval kErrorNone A reference to output the CCA ED threshold in dBm.
405 * @retval kErrorNotImplemented CCA ED threshold configuration via dBm is not implemented.
406 *
407 */
408 Error GetCcaEnergyDetectThreshold(int8_t &aThreshold);
409
410 /**
411 * Sets the radio's CCA ED threshold in dBm.
412 *
413 * @param[in] aThreshold The CCA ED threshold in dBm.
414 *
415 * @retval kErrorNone Successfully set the CCA ED threshold.
416 * @retval kErrorNotImplemented CCA ED threshold configuration via dBm is not implemented.
417 *
418 */
419 Error SetCcaEnergyDetectThreshold(int8_t aThreshold);
420
421 /**
422 * Gets the status of promiscuous mode.
423 *
424 * @retval TRUE Promiscuous mode is enabled.
425 * @retval FALSE Promiscuous mode is disabled.
426 *
427 */
428 bool GetPromiscuous(void);
429
430 /**
431 * Enables or disables promiscuous mode.
432 *
433 * @param[in] aEnable TRUE to enable or FALSE to disable promiscuous mode.
434 *
435 */
436 void SetPromiscuous(bool aEnable);
437
438 /**
439 * Indicates whether radio should stay in Receive or Sleep during idle periods.
440 *
441 * @param[in] aEnable TRUE to keep radio in Receive, FALSE to put to Sleep during idle periods.
442 *
443 */
444 void SetRxOnWhenIdle(bool aEnable);
445
446 /**
447 * Returns the current state of the radio.
448 *
449 * Is not required by OpenThread. It may be used for debugging and/or application-specific purposes.
450 *
451 * @note This function may be not implemented. In this case it always returns OT_RADIO_STATE_INVALID state.
452 *
453 * @return Current state of the radio.
454 *
455 */
456 otRadioState GetState(void);
457
458 /**
459 * Enables the radio.
460 *
461 * @retval kErrorNone Successfully enabled.
462 * @retval kErrorFailed The radio could not be enabled.
463 *
464 */
465 Error Enable(void);
466
467 /**
468 * Disables the radio.
469 *
470 * @retval kErrorNone Successfully transitioned to Disabled.
471 * @retval kErrorInvalidState The radio was not in sleep state.
472 *
473 */
474 Error Disable(void);
475
476 /**
477 * Indicates whether radio is enabled or not.
478 *
479 * @returns TRUE if the radio is enabled, FALSE otherwise.
480 *
481 */
482 bool IsEnabled(void);
483
484 /**
485 * Transitions the radio from Receive to Sleep (turn off the radio).
486 *
487 * @retval kErrorNone Successfully transitioned to Sleep.
488 * @retval kErrorBusy The radio was transmitting.
489 * @retval kErrorInvalidState The radio was disabled.
490 *
491 */
492 Error Sleep(void);
493
494 /**
495 * Transitions the radio from Sleep to Receive (turn on the radio).
496 *
497 * @param[in] aChannel The channel to use for receiving.
498 *
499 * @retval kErrorNone Successfully transitioned to Receive.
500 * @retval kErrorInvalidState The radio was disabled or transmitting.
501 *
502 */
503 Error Receive(uint8_t aChannel);
504
505 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
506 /**
507 * Updates the CSL sample time in radio.
508 *
509 * @param[in] aCslSampleTime The CSL sample time.
510 *
511 */
512 void UpdateCslSampleTime(uint32_t aCslSampleTime);
513
514 /**
515 * Schedules a radio reception window at a specific time and duration.
516 *
517 * @param[in] aChannel The radio channel on which to receive.
518 * @param[in] aStart The receive window start time, in microseconds.
519 * @param[in] aDuration The receive window duration, in microseconds.
520 *
521 * @retval kErrorNone Successfully scheduled receive window.
522 * @retval kErrorFailed The receive window could not be scheduled.
523 *
524 */
525 Error ReceiveAt(uint8_t aChannel, uint32_t aStart, uint32_t aDuration);
526
527 /**
528 * Enables CSL sampling in radio.
529 *
530 * @param[in] aCslPeriod CSL period, 0 for disabling CSL.
531 * @param[in] aShortAddr The short source address of CSL receiver's peer.
532 * @param[in] aExtAddr The extended source address of CSL receiver's peer.
533 *
534 * @note Platforms should use CSL peer addresses to include CSL IE when generating enhanced acks.
535 *
536 * @retval kErrorNotImplemented Radio driver doesn't support CSL.
537 * @retval kErrorFailed Other platform specific errors.
538 * @retval kErrorNone Successfully enabled or disabled CSL.
539 *
540 */
541 Error EnableCsl(uint32_t aCslPeriod, otShortAddress aShortAddr, const otExtAddress *aExtAddr);
542
543 /**
544 * Resets CSL receiver in radio.
545 *
546 * @retval kErrorNotImplemented Radio driver doesn't support CSL.
547 * @retval kErrorFailed Other platform specific errors.
548 * @retval kErrorNone Successfully disabled CSL.
549 *
550 */
551 Error ResetCsl(void);
552 #endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
553
554 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
555 /**
556 * Get the current accuracy, in units of ± ppm, of the clock used for scheduling CSL operations.
557 *
558 * @note Platforms may optimize this value based on operational conditions (i.e.: temperature).
559 *
560 * @returns The current CSL rx/tx scheduling drift, in units of ± ppm.
561 *
562 */
563 uint8_t GetCslAccuracy(void);
564
565 /**
566 * Get the fixed uncertainty of the Device for scheduling CSL operations in units of 10 microseconds.
567 *
568 * @returns The CSL Uncertainty in units of 10 us.
569 *
570 */
571 uint8_t GetCslUncertainty(void);
572 #endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
573
574 /**
575 * Gets the radio transmit frame buffer.
576 *
577 * OpenThread forms the IEEE 802.15.4 frame in this buffer then calls `Transmit()` to request transmission.
578 *
579 * @returns A reference to the transmit frame buffer.
580 *
581 */
582 Mac::TxFrame &GetTransmitBuffer(void);
583
584 /**
585 * Starts the transmit sequence on the radio.
586 *
587 * The caller must form the IEEE 802.15.4 frame in the buffer provided by `GetTransmitBuffer()` before
588 * requesting transmission. The channel and transmit power are also included in the frame.
589 *
590 * @param[in] aFrame A reference to the frame to be transmitted.
591 *
592 * @retval kErrorNone Successfully transitioned to Transmit.
593 * @retval kErrorInvalidState The radio was not in the Receive state.
594 *
595 */
596 Error Transmit(Mac::TxFrame &aFrame);
597
598 /**
599 * Gets the most recent RSSI measurement.
600 *
601 * @returns The RSSI in dBm when it is valid. 127 when RSSI is invalid.
602 *
603 */
604 int8_t GetRssi(void);
605
606 /**
607 * Begins the energy scan sequence on the radio.
608 *
609 * Is used when radio provides OT_RADIO_CAPS_ENERGY_SCAN capability.
610 *
611 * @param[in] aScanChannel The channel to perform the energy scan on.
612 * @param[in] aScanDuration The duration, in milliseconds, for the channel to be scanned.
613 *
614 * @retval kErrorNone Successfully started scanning the channel.
615 * @retval kErrorBusy The radio is performing energy scanning.
616 * @retval kErrorNotImplemented The radio doesn't support energy scanning.
617 *
618 */
619 Error EnergyScan(uint8_t aScanChannel, uint16_t aScanDuration);
620
621 /**
622 * Enables/disables source address match feature.
623 *
624 * The source address match feature controls how the radio layer decides the "frame pending" bit for acks sent in
625 * response to data request commands from children.
626 *
627 * If disabled, the radio layer must set the "frame pending" on all acks to data request commands.
628 *
629 * If enabled, the radio layer uses the source address match table to determine whether to set or clear the "frame
630 * pending" bit in an ack to a data request command.
631 *
632 * The source address match table provides the list of children for which there is a pending frame. Either a short
633 * address or an extended/long address can be added to the source address match table.
634 *
635 * @param[in] aEnable Enable/disable source address match feature.
636 *
637 */
638 void EnableSrcMatch(bool aEnable);
639
640 /**
641 * Adds a short address to the source address match table.
642 *
643 * @param[in] aShortAddress The short address to be added.
644 *
645 * @retval kErrorNone Successfully added short address to the source match table.
646 * @retval kErrorNoBufs No available entry in the source match table.
647 *
648 */
649 Error AddSrcMatchShortEntry(Mac::ShortAddress aShortAddress);
650
651 /**
652 * Adds an extended address to the source address match table.
653 *
654 * @param[in] aExtAddress The extended address to be added stored in little-endian byte order.
655 *
656 * @retval kErrorNone Successfully added extended address to the source match table.
657 * @retval kErrorNoBufs No available entry in the source match table.
658 *
659 */
660 Error AddSrcMatchExtEntry(const Mac::ExtAddress &aExtAddress);
661
662 /**
663 * Removes a short address from the source address match table.
664 *
665 * @param[in] aShortAddress The short address to be removed.
666 *
667 * @retval kErrorNone Successfully removed short address from the source match table.
668 * @retval kErrorNoAddress The short address is not in source address match table.
669 *
670 */
671 Error ClearSrcMatchShortEntry(Mac::ShortAddress aShortAddress);
672
673 /**
674 * Removes an extended address from the source address match table.
675 *
676 * @param[in] aExtAddress The extended address to be removed stored in little-endian byte order.
677 *
678 * @retval kErrorNone Successfully removed the extended address from the source match table.
679 * @retval kErrorNoAddress The extended address is not in source address match table.
680 *
681 */
682 Error ClearSrcMatchExtEntry(const Mac::ExtAddress &aExtAddress);
683
684 /**
685 * Clears all short addresses from the source address match table.
686 *
687 */
688 void ClearSrcMatchShortEntries(void);
689
690 /**
691 * Clears all the extended/long addresses from source address match table.
692 *
693 */
694 void ClearSrcMatchExtEntries(void);
695
696 /**
697 * Gets the radio supported channel mask that the device is allowed to be on.
698 *
699 * @returns The radio supported channel mask.
700 *
701 */
702 uint32_t GetSupportedChannelMask(void);
703
704 /**
705 * Gets the radio preferred channel mask that the device prefers to form on.
706 *
707 * @returns The radio preferred channel mask.
708 *
709 */
710 uint32_t GetPreferredChannelMask(void);
711
712 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
713 /**
714 * Enables/disables or updates Enhanced-ACK Based Probing in radio for a specific Initiator.
715 *
716 * After Enhanced-ACK Based Probing is configured by a specific Probing Initiator, the Enhanced-ACK sent to that
717 * node should include Vendor-Specific IE containing Link Metrics data. This method informs the radio to
718 * starts/stops to collect Link Metrics data and include Vendor-Specific IE that containing the data
719 * in Enhanced-ACK sent to that Probing Initiator.
720 *
721 * @param[in] aLinkMetrics This parameter specifies what metrics to query. Per spec 4.11.3.4.4.6, at most 2
722 * metrics can be specified. The probing would be disabled if @p `aLinkMetrics` is
723 * bitwise 0.
724 * @param[in] aShortAddress The short address of the the probing Initiator.
725 * @param[in] aExtAddress The extended source address of the probing Initiator.
726 *
727 * @retval kErrorNone Successfully enable/disable or update Enhanced-ACK Based Probing for a specific
728 * Initiator.
729 * @retval kErrorInvalidArgs @p aDataLength or @p aExtAddr is not valid.
730 * @retval kErrorNotFound The Initiator indicated by @p aShortAddress is not found when trying to clear.
731 * @retval kErrorNoBufs No more Initiator can be supported.
732 * @retval kErrorNotImplemented Radio driver doesn't support Enhanced-ACK Probing.
733 *
734 */
ConfigureEnhAckProbing(otLinkMetrics aLinkMetrics,const Mac::ShortAddress & aShortAddress,const Mac::ExtAddress & aExtAddress)735 Error ConfigureEnhAckProbing(otLinkMetrics aLinkMetrics,
736 const Mac::ShortAddress &aShortAddress,
737 const Mac::ExtAddress &aExtAddress)
738 {
739 return otPlatRadioConfigureEnhAckProbing(GetInstancePtr(), aLinkMetrics, aShortAddress, &aExtAddress);
740 }
741 #endif // OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
742
743 /**
744 * Checks if a given channel is valid as a CSL channel.
745 *
746 * @retval true The channel is valid.
747 * @retval false The channel is invalid.
748 *
749 */
IsCslChannelValid(uint8_t aCslChannel)750 static bool IsCslChannelValid(uint8_t aCslChannel)
751 {
752 return ((aCslChannel == 0) ||
753 ((kChannelMin == aCslChannel) || ((kChannelMin < aCslChannel) && (aCslChannel <= kChannelMax))));
754 }
755
756 /**
757 * Sets the region code.
758 *
759 * The radio region format is the 2-bytes ascii representation of the ISO 3166 alpha-2 code.
760 *
761 * @param[in] aRegionCode The radio region code. The `aRegionCode >> 8` is first ascii char
762 * and the `aRegionCode & 0xff` is the second ascii char.
763 *
764 * @retval kErrorFailed Other platform specific errors.
765 * @retval kErrorNone Successfully set region code.
766 * @retval kErrorNotImplemented The feature is not implemented.
767 *
768 */
SetRegion(uint16_t aRegionCode)769 Error SetRegion(uint16_t aRegionCode) { return otPlatRadioSetRegion(GetInstancePtr(), aRegionCode); }
770
771 /**
772 * Get the region code.
773 *
774 * The radio region format is the 2-bytes ascii representation of the ISO 3166 alpha-2 code.
775 *
776 * @param[out] aRegionCode The radio region code. The `aRegionCode >> 8` is first ascii char
777 * and the `aRegionCode & 0xff` is the second ascii char.
778 *
779 * @retval kErrorFailed Other platform specific errors.
780 * @retval kErrorNone Successfully set region code.
781 * @retval kErrorNotImplemented The feature is not implemented.
782 *
783 */
GetRegion(uint16_t & aRegionCode) const784 Error GetRegion(uint16_t &aRegionCode) const { return otPlatRadioGetRegion(GetInstancePtr(), &aRegionCode); }
785
786 /**
787 * Indicates whether a given channel page is supported based on the current configurations.
788 *
789 * @param[in] aChannelPage The channel page to check.
790 *
791 * @retval TRUE The @p aChannelPage is supported by radio.
792 * @retval FALASE The @p aChannelPage is not supported by radio.
793 *
794 */
SupportsChannelPage(uint8_t aChannelPage)795 static constexpr bool SupportsChannelPage(uint8_t aChannelPage)
796 {
797 #if OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT && OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT
798 return (aChannelPage == kChannelPage0) || (aChannelPage == kChannelPage2);
799 #elif OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT
800 return (aChannelPage == kChannelPage0);
801 #elif OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT
802 return (aChannelPage == kChannelPage2);
803 #elif OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_SUPPORT
804 return (aChannelPage == OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_PAGE);
805 #endif
806 }
807
808 /**
809 * Returns the channel mask for a given channel page if supported by the radio.
810 *
811 * @param[in] aChannelPage The channel page.
812 *
813 * @returns The channel mask for @p aChannelPage if page is supported by the radio, otherwise zero.
814 *
815 */
ChannelMaskForPage(uint8_t aChannelPage)816 static uint32_t ChannelMaskForPage(uint8_t aChannelPage)
817 {
818 uint32_t mask = 0;
819
820 #if OPENTHREAD_CONFIG_RADIO_2P4GHZ_OQPSK_SUPPORT
821 if (aChannelPage == kChannelPage0)
822 {
823 mask = OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MASK;
824 }
825 #endif
826
827 #if OPENTHREAD_CONFIG_RADIO_915MHZ_OQPSK_SUPPORT
828 if (aChannelPage == kChannelPage1)
829 {
830 mask = OT_RADIO_915MHZ_OQPSK_CHANNEL_MASK;
831 }
832 #endif
833
834 #if OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_SUPPORT
835 if (aChannelPage == OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_PAGE)
836 {
837 mask = OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MASK;
838 }
839 #endif
840 return mask;
841 }
842
843 private:
GetInstancePtr(void) const844 otInstance *GetInstancePtr(void) const { return reinterpret_cast<otInstance *>(&InstanceLocator::GetInstance()); }
845
846 Callbacks mCallbacks;
847 #if OPENTHREAD_CONFIG_RADIO_STATS_ENABLE && (OPENTHREAD_FTD || OPENTHREAD_MTD)
848 RadioStatistics mRadioStatistics;
849 #endif
850 };
851
852 //---------------------------------------------------------------------------------------------------------------------
853 // Radio APIs that are always mapped to the same `otPlatRadio` function (independent of the link type)
854
GetVersionString(void)855 inline const char *Radio::GetVersionString(void) { return otPlatRadioGetVersionString(GetInstancePtr()); }
856
GetIeeeEui64(Mac::ExtAddress & aIeeeEui64)857 inline void Radio::GetIeeeEui64(Mac::ExtAddress &aIeeeEui64)
858 {
859 otPlatRadioGetIeeeEui64(GetInstancePtr(), aIeeeEui64.m8);
860 }
861
GetSupportedChannelMask(void)862 inline uint32_t Radio::GetSupportedChannelMask(void) { return otPlatRadioGetSupportedChannelMask(GetInstancePtr()); }
863
GetPreferredChannelMask(void)864 inline uint32_t Radio::GetPreferredChannelMask(void) { return otPlatRadioGetPreferredChannelMask(GetInstancePtr()); }
865
866 //---------------------------------------------------------------------------------------------------------------------
867 // If IEEE 802.15.4 is among supported radio links, provide inline
868 // mapping of `Radio` method to related `otPlatRadio` functions.
869
870 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
871
GetCaps(void)872 inline otRadioCaps Radio::GetCaps(void) { return otPlatRadioGetCaps(GetInstancePtr()); }
873
GetReceiveSensitivity(void) const874 inline int8_t Radio::GetReceiveSensitivity(void) const { return otPlatRadioGetReceiveSensitivity(GetInstancePtr()); }
875
SetPanId(Mac::PanId aPanId)876 inline void Radio::SetPanId(Mac::PanId aPanId) { otPlatRadioSetPanId(GetInstancePtr(), aPanId); }
877
SetMacKey(uint8_t aKeyIdMode,uint8_t aKeyId,const Mac::KeyMaterial & aPrevKey,const Mac::KeyMaterial & aCurrKey,const Mac::KeyMaterial & aNextKey)878 inline void Radio::SetMacKey(uint8_t aKeyIdMode,
879 uint8_t aKeyId,
880 const Mac::KeyMaterial &aPrevKey,
881 const Mac::KeyMaterial &aCurrKey,
882 const Mac::KeyMaterial &aNextKey)
883 {
884 otRadioKeyType aKeyType;
885
886 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
887 aKeyType = OT_KEY_TYPE_KEY_REF;
888 #else
889 aKeyType = OT_KEY_TYPE_LITERAL_KEY;
890 #endif
891
892 otPlatRadioSetMacKey(GetInstancePtr(), aKeyIdMode, aKeyId, &aPrevKey, &aCurrKey, &aNextKey, aKeyType);
893 }
894
GetTransmitPower(int8_t & aPower)895 inline Error Radio::GetTransmitPower(int8_t &aPower) { return otPlatRadioGetTransmitPower(GetInstancePtr(), &aPower); }
896
SetTransmitPower(int8_t aPower)897 inline Error Radio::SetTransmitPower(int8_t aPower) { return otPlatRadioSetTransmitPower(GetInstancePtr(), aPower); }
898
GetCcaEnergyDetectThreshold(int8_t & aThreshold)899 inline Error Radio::GetCcaEnergyDetectThreshold(int8_t &aThreshold)
900 {
901 return otPlatRadioGetCcaEnergyDetectThreshold(GetInstancePtr(), &aThreshold);
902 }
903
SetCcaEnergyDetectThreshold(int8_t aThreshold)904 inline Error Radio::SetCcaEnergyDetectThreshold(int8_t aThreshold)
905 {
906 return otPlatRadioSetCcaEnergyDetectThreshold(GetInstancePtr(), aThreshold);
907 }
908
GetPromiscuous(void)909 inline bool Radio::GetPromiscuous(void) { return otPlatRadioGetPromiscuous(GetInstancePtr()); }
910
SetPromiscuous(bool aEnable)911 inline void Radio::SetPromiscuous(bool aEnable) { otPlatRadioSetPromiscuous(GetInstancePtr(), aEnable); }
912
SetRxOnWhenIdle(bool aEnable)913 inline void Radio::SetRxOnWhenIdle(bool aEnable) { otPlatRadioSetRxOnWhenIdle(GetInstancePtr(), aEnable); }
914
GetState(void)915 inline otRadioState Radio::GetState(void) { return otPlatRadioGetState(GetInstancePtr()); }
916
Enable(void)917 inline Error Radio::Enable(void)
918 {
919 #if OPENTHREAD_CONFIG_RADIO_STATS_ENABLE && (OPENTHREAD_FTD || OPENTHREAD_MTD)
920 mRadioStatistics.RecordStateChange(RadioStatistics::kSleep);
921 #endif
922 return otPlatRadioEnable(GetInstancePtr());
923 }
924
Disable(void)925 inline Error Radio::Disable(void)
926 {
927 #if OPENTHREAD_CONFIG_RADIO_STATS_ENABLE && (OPENTHREAD_FTD || OPENTHREAD_MTD)
928 mRadioStatistics.RecordStateChange(RadioStatistics::kDisabled);
929 #endif
930 return otPlatRadioDisable(GetInstancePtr());
931 }
932
IsEnabled(void)933 inline bool Radio::IsEnabled(void) { return otPlatRadioIsEnabled(GetInstancePtr()); }
934
Sleep(void)935 inline Error Radio::Sleep(void)
936 {
937 #if OPENTHREAD_CONFIG_RADIO_STATS_ENABLE && (OPENTHREAD_FTD || OPENTHREAD_MTD)
938 mRadioStatistics.RecordStateChange(RadioStatistics::kSleep);
939 #endif
940 return otPlatRadioSleep(GetInstancePtr());
941 }
942
Receive(uint8_t aChannel)943 inline Error Radio::Receive(uint8_t aChannel)
944 {
945 #if OPENTHREAD_CONFIG_RADIO_STATS_ENABLE && (OPENTHREAD_FTD || OPENTHREAD_MTD)
946 mRadioStatistics.RecordStateChange(RadioStatistics::kReceive);
947 #endif
948 return otPlatRadioReceive(GetInstancePtr(), aChannel);
949 }
950
951 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
UpdateCslSampleTime(uint32_t aCslSampleTime)952 inline void Radio::UpdateCslSampleTime(uint32_t aCslSampleTime)
953 {
954 otPlatRadioUpdateCslSampleTime(GetInstancePtr(), aCslSampleTime);
955 }
956
ReceiveAt(uint8_t aChannel,uint32_t aStart,uint32_t aDuration)957 inline Error Radio::ReceiveAt(uint8_t aChannel, uint32_t aStart, uint32_t aDuration)
958 {
959 Error error = otPlatRadioReceiveAt(GetInstancePtr(), aChannel, aStart, aDuration);
960 #if OPENTHREAD_CONFIG_RADIO_STATS_ENABLE && (OPENTHREAD_FTD || OPENTHREAD_MTD)
961 if (error == kErrorNone)
962 {
963 mRadioStatistics.HandleReceiveAt(aDuration);
964 }
965 #endif
966 return error;
967 }
968
EnableCsl(uint32_t aCslPeriod,otShortAddress aShortAddr,const otExtAddress * aExtAddr)969 inline Error Radio::EnableCsl(uint32_t aCslPeriod, otShortAddress aShortAddr, const otExtAddress *aExtAddr)
970 {
971 return otPlatRadioEnableCsl(GetInstancePtr(), aCslPeriod, aShortAddr, aExtAddr);
972 }
973
ResetCsl(void)974 inline Error Radio::ResetCsl(void) { return otPlatRadioResetCsl(GetInstancePtr()); }
975 #endif
976
977 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
GetCslAccuracy(void)978 inline uint8_t Radio::GetCslAccuracy(void) { return otPlatRadioGetCslAccuracy(GetInstancePtr()); }
979 #endif
980
981 #if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
GetCslUncertainty(void)982 inline uint8_t Radio::GetCslUncertainty(void) { return otPlatRadioGetCslUncertainty(GetInstancePtr()); }
983 #endif
984
GetTransmitBuffer(void)985 inline Mac::TxFrame &Radio::GetTransmitBuffer(void)
986 {
987 return *static_cast<Mac::TxFrame *>(otPlatRadioGetTransmitBuffer(GetInstancePtr()));
988 }
989
GetRssi(void)990 inline int8_t Radio::GetRssi(void) { return otPlatRadioGetRssi(GetInstancePtr()); }
991
EnergyScan(uint8_t aScanChannel,uint16_t aScanDuration)992 inline Error Radio::EnergyScan(uint8_t aScanChannel, uint16_t aScanDuration)
993 {
994 return otPlatRadioEnergyScan(GetInstancePtr(), aScanChannel, aScanDuration);
995 }
996
EnableSrcMatch(bool aEnable)997 inline void Radio::EnableSrcMatch(bool aEnable) { otPlatRadioEnableSrcMatch(GetInstancePtr(), aEnable); }
998
AddSrcMatchShortEntry(Mac::ShortAddress aShortAddress)999 inline Error Radio::AddSrcMatchShortEntry(Mac::ShortAddress aShortAddress)
1000 {
1001 return otPlatRadioAddSrcMatchShortEntry(GetInstancePtr(), aShortAddress);
1002 }
1003
AddSrcMatchExtEntry(const Mac::ExtAddress & aExtAddress)1004 inline Error Radio::AddSrcMatchExtEntry(const Mac::ExtAddress &aExtAddress)
1005 {
1006 return otPlatRadioAddSrcMatchExtEntry(GetInstancePtr(), &aExtAddress);
1007 }
1008
ClearSrcMatchShortEntry(Mac::ShortAddress aShortAddress)1009 inline Error Radio::ClearSrcMatchShortEntry(Mac::ShortAddress aShortAddress)
1010 {
1011 return otPlatRadioClearSrcMatchShortEntry(GetInstancePtr(), aShortAddress);
1012 }
1013
ClearSrcMatchExtEntry(const Mac::ExtAddress & aExtAddress)1014 inline Error Radio::ClearSrcMatchExtEntry(const Mac::ExtAddress &aExtAddress)
1015 {
1016 return otPlatRadioClearSrcMatchExtEntry(GetInstancePtr(), &aExtAddress);
1017 }
1018
ClearSrcMatchShortEntries(void)1019 inline void Radio::ClearSrcMatchShortEntries(void) { otPlatRadioClearSrcMatchShortEntries(GetInstancePtr()); }
1020
ClearSrcMatchExtEntries(void)1021 inline void Radio::ClearSrcMatchExtEntries(void) { otPlatRadioClearSrcMatchExtEntries(GetInstancePtr()); }
1022
1023 #else //----------------------------------------------------------------------------------------------------------------
1024
GetCaps(void)1025 inline otRadioCaps Radio::GetCaps(void)
1026 {
1027 return OT_RADIO_CAPS_ACK_TIMEOUT | OT_RADIO_CAPS_CSMA_BACKOFF | OT_RADIO_CAPS_TRANSMIT_RETRIES;
1028 }
1029
GetReceiveSensitivity(void) const1030 inline int8_t Radio::GetReceiveSensitivity(void) const { return kDefaultReceiveSensitivity; }
1031
SetPanId(Mac::PanId)1032 inline void Radio::SetPanId(Mac::PanId) {}
1033
SetExtendedAddress(const Mac::ExtAddress &)1034 inline void Radio::SetExtendedAddress(const Mac::ExtAddress &) {}
1035
SetShortAddress(Mac::ShortAddress)1036 inline void Radio::SetShortAddress(Mac::ShortAddress) {}
1037
SetMacKey(uint8_t,uint8_t,const Mac::KeyMaterial &,const Mac::KeyMaterial &,const Mac::KeyMaterial &)1038 inline void Radio::SetMacKey(uint8_t,
1039 uint8_t,
1040 const Mac::KeyMaterial &,
1041 const Mac::KeyMaterial &,
1042 const Mac::KeyMaterial &)
1043 {
1044 }
1045
GetTransmitPower(int8_t &)1046 inline Error Radio::GetTransmitPower(int8_t &) { return kErrorNotImplemented; }
1047
SetTransmitPower(int8_t)1048 inline Error Radio::SetTransmitPower(int8_t) { return kErrorNotImplemented; }
1049
GetCcaEnergyDetectThreshold(int8_t &)1050 inline Error Radio::GetCcaEnergyDetectThreshold(int8_t &) { return kErrorNotImplemented; }
1051
SetCcaEnergyDetectThreshold(int8_t)1052 inline Error Radio::SetCcaEnergyDetectThreshold(int8_t) { return kErrorNotImplemented; }
1053
GetPromiscuous(void)1054 inline bool Radio::GetPromiscuous(void) { return false; }
1055
SetPromiscuous(bool)1056 inline void Radio::SetPromiscuous(bool) {}
1057
SetRxOnWhenIdle(bool)1058 inline void Radio::SetRxOnWhenIdle(bool) {}
1059
GetState(void)1060 inline otRadioState Radio::GetState(void) { return OT_RADIO_STATE_DISABLED; }
1061
Enable(void)1062 inline Error Radio::Enable(void) { return kErrorNone; }
1063
Disable(void)1064 inline Error Radio::Disable(void) { return kErrorInvalidState; }
1065
IsEnabled(void)1066 inline bool Radio::IsEnabled(void) { return true; }
1067
Sleep(void)1068 inline Error Radio::Sleep(void) { return kErrorNone; }
1069
Receive(uint8_t)1070 inline Error Radio::Receive(uint8_t) { return kErrorNone; }
1071
1072 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
UpdateCslSampleTime(uint32_t)1073 inline void Radio::UpdateCslSampleTime(uint32_t) {}
1074
ReceiveAt(uint8_t,uint32_t,uint32_t)1075 inline Error Radio::ReceiveAt(uint8_t, uint32_t, uint32_t) { return kErrorNone; }
1076
EnableCsl(uint32_t,otShortAddress aShortAddr,const otExtAddress *)1077 inline Error Radio::EnableCsl(uint32_t, otShortAddress aShortAddr, const otExtAddress *)
1078 {
1079 return kErrorNotImplemented;
1080 }
1081
ResetCsl(void)1082 inline Error Radio::ResetCsl(void) { return kErrorNotImplemented; }
1083 #endif
1084
1085 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
GetCslAccuracy(void)1086 inline uint8_t Radio::GetCslAccuracy(void) { return NumericLimits<uint8_t>::kMax; }
1087
GetCslUncertainty(void)1088 inline uint8_t Radio::GetCslUncertainty(void) { return NumericLimits<uint8_t>::kMax; }
1089 #endif
1090
GetTransmitBuffer(void)1091 inline Mac::TxFrame &Radio::GetTransmitBuffer(void)
1092 {
1093 return *static_cast<Mac::TxFrame *>(otPlatRadioGetTransmitBuffer(GetInstancePtr()));
1094 }
1095
Transmit(Mac::TxFrame &)1096 inline Error Radio::Transmit(Mac::TxFrame &) { return kErrorAbort; }
1097
GetRssi(void)1098 inline int8_t Radio::GetRssi(void) { return kInvalidRssi; }
1099
EnergyScan(uint8_t,uint16_t)1100 inline Error Radio::EnergyScan(uint8_t, uint16_t) { return kErrorNotImplemented; }
1101
EnableSrcMatch(bool)1102 inline void Radio::EnableSrcMatch(bool) {}
1103
AddSrcMatchShortEntry(Mac::ShortAddress)1104 inline Error Radio::AddSrcMatchShortEntry(Mac::ShortAddress) { return kErrorNone; }
1105
AddSrcMatchExtEntry(const Mac::ExtAddress &)1106 inline Error Radio::AddSrcMatchExtEntry(const Mac::ExtAddress &) { return kErrorNone; }
1107
ClearSrcMatchShortEntry(Mac::ShortAddress)1108 inline Error Radio::ClearSrcMatchShortEntry(Mac::ShortAddress) { return kErrorNone; }
1109
ClearSrcMatchExtEntry(const Mac::ExtAddress &)1110 inline Error Radio::ClearSrcMatchExtEntry(const Mac::ExtAddress &) { return kErrorNone; }
1111
ClearSrcMatchShortEntries(void)1112 inline void Radio::ClearSrcMatchShortEntries(void) {}
1113
ClearSrcMatchExtEntries(void)1114 inline void Radio::ClearSrcMatchExtEntries(void) {}
1115
1116 #endif // #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
1117
1118 } // namespace ot
1119
1120 #endif // RADIO_HPP_
1121