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