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