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