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 MAC radio links.
32  */
33 
34 #ifndef MAC_LINKS_HPP_
35 #define MAC_LINKS_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include "common/debug.hpp"
40 #include "common/locator.hpp"
41 #include "mac/mac_frame.hpp"
42 #include "mac/mac_types.hpp"
43 #include "mac/sub_mac.hpp"
44 #include "radio/radio.hpp"
45 #include "radio/trel_link.hpp"
46 
47 namespace ot {
48 namespace Mac {
49 
50 /**
51  * @addtogroup core-mac
52  *
53  * @brief
54  *   This module includes definitions for MAC radio links (multi radio).
55  *
56  * @{
57  */
58 
59 /**
60  * Represents tx frames for different radio link types.
61  */
62 class TxFrames : InstanceLocator
63 {
64     friend class Links;
65 
66 public:
67 #if OPENTHREAD_CONFIG_MULTI_RADIO
68     /**
69      * Gets the `TxFrame` for a given radio link type.
70      *
71      * Also updates the selected radio types (from `GetSelectedRadioTypes()`) to include the @p aRadioType.
72      *
73      * @param[in] aRadioType   A radio link type.
74      *
75      * @returns A reference to the `TxFrame` for the given radio link type.
76      */
77     TxFrame &GetTxFrame(RadioType aRadioType);
78 
79     /**
80      * Gets the `TxFrame` with the smallest MTU size among a given set of radio types.
81      *
82      * Also updates the selected radio types (from `GetSelectedRadioTypes()`) to include the set
83      * @p aRadioTypes.
84      *
85      * @param[in] aRadioTypes   A set of radio link types.
86      *
87      * @returns A reference to the `TxFrame` with the smallest MTU size among the set of @p aRadioTypes.
88      */
89     TxFrame &GetTxFrame(RadioTypes aRadioTypes);
90 
91     /**
92      * Gets the `TxFrame` for sending a broadcast frame.
93      *
94      * Also updates the selected radio type (from `GetSelectedRadioTypes()`) to include all radio types
95      * (supported by device).
96      *
97      * The broadcast frame is the `TxFrame` with the smallest MTU size among all radio types.
98      *
99      * @returns A reference to a `TxFrame` for broadcast.
100      */
101     TxFrame &GetBroadcastTxFrame(void);
102 
103     /**
104      * Gets the selected radio types.
105      *
106      * This set specifies the radio links the frame should be sent over (in parallel). The set starts a empty after
107      * method `Clear()` is called. It gets updated through calls to methods `GetTxFrame(aType)`,
108      * `GetTxFrame(aRadioTypes)`, or `GetBroadcastTxFrame()`.
109      *
110      * @returns The selected radio types.
111      */
GetSelectedRadioTypes(void) const112     RadioTypes GetSelectedRadioTypes(void) const { return mSelectedRadioTypes; }
113 
114     /**
115      * Gets the required radio types.
116      *
117      * This set specifies the radio links for which we expect the frame tx to be successful to consider the overall tx
118      * successful. If the set is empty, successful tx over any radio link is sufficient for overall tx to be considered
119      * successful. The required radio type set is expected to be a subset of selected radio types.
120      *
121      * The set starts as empty after `Clear()` call. It can be updated through `SetRequiredRadioTypes()` method
122      *
123      * @returns The required radio types.
124      */
GetRequiredRadioTypes(void) const125     RadioTypes GetRequiredRadioTypes(void) const { return mRequiredRadioTypes; }
126 
127     /**
128      * Sets the required types.
129      *
130      * Please see `GetRequiredRadioTypes()` for more details on how this set is used during tx.
131      *
132      * @param[in] aRadioTypes   A set of radio link types.
133      */
SetRequiredRadioTypes(RadioTypes aRadioTypes)134     void SetRequiredRadioTypes(RadioTypes aRadioTypes) { mRequiredRadioTypes = aRadioTypes; }
135 
136 #else // #if OPENTHREAD_CONFIG_MULTI_RADIO
137 
138 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
139     /**
140      * Gets the tx frame.
141      *
142      * @returns A reference to `TxFrame`.
143      */
144     TxFrame &GetTxFrame(void) { return mTxFrame802154; }
145 #elif OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
146     /**
147      * Gets the tx frame.
148      *
149      * @returns A reference to `TxFrame`.
150      */
151     TxFrame &GetTxFrame(void) { return mTxFrameTrel; }
152 #endif
153     /**
154      * Gets a tx frame for sending a broadcast frame.
155      *
156      * @returns A reference to a `TxFrame` for broadcast.
157      */
158     TxFrame &GetBroadcastTxFrame(void) { return GetTxFrame(); }
159 
160 #endif // #if OPENTHREAD_CONFIG_MULTI_RADIO
161 
162     /**
163      * Clears all supported radio tx frames (sets the PSDU length to zero and clears flags).
164      */
Clear(void)165     void Clear(void)
166     {
167 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
168         mTxFrame802154.SetLength(0);
169         mTxFrame802154.SetIsARetransmission(false);
170         mTxFrame802154.SetIsSecurityProcessed(false);
171         mTxFrame802154.SetCsmaCaEnabled(true); // Set to true by default, only set to `false` for CSL transmission
172         mTxFrame802154.SetIsHeaderUpdated(false);
173 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
174         mTxFrame802154.SetTxDelay(0);
175         mTxFrame802154.SetTxDelayBaseTime(0);
176 #endif
177         mTxFrame802154.SetTxPower(kRadioPowerInvalid);
178 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
179         mTxFrame802154.SetCslIePresent(false);
180 #endif
181 #endif
182 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
183         mTxFrameTrel.SetLength(0);
184         mTxFrameTrel.SetIsARetransmission(false);
185         mTxFrameTrel.SetIsSecurityProcessed(false);
186         mTxFrameTrel.SetCsmaCaEnabled(true);
187         mTxFrameTrel.SetIsHeaderUpdated(false);
188 #endif
189 
190 #if OPENTHREAD_CONFIG_MULTI_RADIO
191         mSelectedRadioTypes.Clear();
192         mRequiredRadioTypes.Clear();
193 #endif
194     }
195 
196     /**
197      * Sets the channel on all supported radio tx frames.
198      *
199      * @param[in] aChannel  A channel.
200      */
SetChannel(uint8_t aChannel)201     void SetChannel(uint8_t aChannel)
202     {
203 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
204         mTxFrame802154.SetChannel(aChannel);
205 #endif
206 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
207         mTxFrameTrel.SetChannel(aChannel);
208 #endif
209     }
210 
211     /**
212      * Sets the Sequence Number value on all supported radio tx frames.
213      *
214      * @param[in]  aSequence  The Sequence Number value.
215      */
SetSequence(uint8_t aSequence)216     void SetSequence(uint8_t aSequence)
217     {
218 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
219         mTxFrame802154.SetSequence(aSequence);
220 #endif
221 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
222         mTxFrameTrel.SetSequence(aSequence);
223 #endif
224     }
225 
226     /**
227      * Sets the maximum number of the CSMA-CA backoffs on all supported radio tx
228      * frames.
229      *
230      * @param[in]  aMaxCsmaBackoffs  The maximum number of CSMA-CA backoffs.
231      */
SetMaxCsmaBackoffs(uint8_t aMaxCsmaBackoffs)232     void SetMaxCsmaBackoffs(uint8_t aMaxCsmaBackoffs)
233     {
234 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
235         mTxFrame802154.SetMaxCsmaBackoffs(aMaxCsmaBackoffs);
236 #endif
237 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
238         mTxFrameTrel.SetMaxCsmaBackoffs(aMaxCsmaBackoffs);
239 #endif
240     }
241 
242     /**
243      * Sets the maximum number of retries allowed after a transmission failure on all supported radio tx
244      * frames.
245      *
246      * @param[in]  aMaxFrameRetries  The maximum number of retries allowed after a transmission failure.
247      */
SetMaxFrameRetries(uint8_t aMaxFrameRetries)248     void SetMaxFrameRetries(uint8_t aMaxFrameRetries)
249     {
250 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
251         mTxFrame802154.SetMaxFrameRetries(aMaxFrameRetries);
252 #endif
253 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
254         mTxFrameTrel.SetMaxFrameRetries(aMaxFrameRetries);
255 #endif
256     }
257 
258 private:
259     explicit TxFrames(Instance &aInstance);
260 
261 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
262     TxFrame &mTxFrame802154;
263 #endif
264 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
265     TxFrame &mTxFrameTrel;
266 #endif
267 
268 #if OPENTHREAD_CONFIG_MULTI_RADIO
269     RadioTypes mSelectedRadioTypes;
270     RadioTypes mRequiredRadioTypes;
271 #endif
272 };
273 
274 /**
275  * Represents MAC radio links (multi radio).
276  */
277 class Links : public InstanceLocator
278 {
279     friend class ot::Instance;
280 
281 public:
282     /**
283      * Initializes the `Links` object.
284      *
285      * @param[in]  aInstance  A reference to the OpenThread instance.
286      */
287     explicit Links(Instance &aInstance);
288 
289     /**
290      * Sets the PAN ID.
291      *
292      * @param[in] aPanId  The PAN ID.
293      */
SetPanId(PanId aPanId)294     void SetPanId(PanId aPanId)
295     {
296 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
297         mSubMac.SetPanId(aPanId);
298 #endif
299 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
300         mTrel.SetPanId(aPanId);
301 #endif
302     }
303 
304     /**
305      * Gets the MAC Short Address.
306      *
307      * @returns The MAC Short Address.
308      */
GetShortAddress(void) const309     ShortAddress GetShortAddress(void) const
310     {
311         return
312 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
313             mSubMac.GetShortAddress();
314 #else
315             mShortAddress;
316 #endif
317     }
318 
319     /**
320      * Sets the MAC Short Address.
321      *
322      * @param[in] aShortAddress   A MAC Short Address.
323      */
SetShortAddress(ShortAddress aShortAddress)324     void SetShortAddress(ShortAddress aShortAddress)
325     {
326 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
327         mSubMac.SetShortAddress(aShortAddress);
328 #else
329         mShortAddress = aShortAddress;
330 #endif
331     }
332 
333     /**
334      * Gets the alternate MAC short address.
335      *
336      * @returns The alternate MAC short address, or `kShortAddrInvalid` if there is no alternate address.
337      */
GetAlternateShortAddress(void) const338     ShortAddress GetAlternateShortAddress(void) const
339     {
340         return
341 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
342             mSubMac.GetAlternateShortAddress();
343 #else
344             mAlternateShortAddress;
345 #endif
346     }
347 
348     /**
349      * Sets the alternate MAC short address.
350      *
351      * @param[in] aShortAddress   The alternate short address. Use `kShortAddrInvalid` to clear it.
352      */
SetAlternateShortAddress(ShortAddress aShortAddress)353     void SetAlternateShortAddress(ShortAddress aShortAddress)
354     {
355 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
356         mSubMac.SetAlternateShortAddress(aShortAddress);
357 #else
358         mAlternateShortAddress = aShortAddress;
359 #endif
360     }
361 
362     /**
363      * Gets the MAC Extended Address.
364      *
365      * @returns The MAC Extended Address.
366      */
GetExtAddress(void) const367     const ExtAddress &GetExtAddress(void) const
368     {
369         return
370 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
371             mSubMac.GetExtAddress();
372 #else
373             mExtAddress;
374 #endif
375     }
376 
377     /**
378      * Sets the MAC Extended Address.
379      *
380      * @param[in] aExtAddress  A MAC Extended Address.
381      */
SetExtAddress(const ExtAddress & aExtAddress)382     void SetExtAddress(const ExtAddress &aExtAddress)
383     {
384 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
385         mSubMac.SetExtAddress(aExtAddress);
386 #else
387         mExtAddress = aExtAddress;
388 #endif
389 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
390         mTrel.HandleExtAddressChange();
391 #endif
392     }
393 
394     /**
395      * Registers a callback to provide received packet capture for IEEE 802.15.4 frames.
396      *
397      * @param[in]  aPcapCallback     A pointer to a function that is called when receiving an IEEE 802.15.4 link frame
398      *                               or nullptr to disable the callback.
399      * @param[in]  aCallbackContext  A pointer to application-specific context.
400      */
SetPcapCallback(otLinkPcapCallback aPcapCallback,void * aCallbackContext)401     void SetPcapCallback(otLinkPcapCallback aPcapCallback, void *aCallbackContext)
402     {
403 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
404         mSubMac.SetPcapCallback(aPcapCallback, aCallbackContext);
405 #endif
406         OT_UNUSED_VARIABLE(aPcapCallback);
407         OT_UNUSED_VARIABLE(aCallbackContext);
408     }
409 
410     /**
411      * Indicates whether radio should stay in Receive or Sleep during idle periods.
412      *
413      * @param[in]  aRxOnWhenIdle  TRUE to keep radio in Receive, FALSE to put to Sleep during idle periods.
414      */
SetRxOnWhenIdle(bool aRxOnWhenIdle)415     void SetRxOnWhenIdle(bool aRxOnWhenIdle)
416     {
417 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
418         mSubMac.SetRxOnWhenIdle(aRxOnWhenIdle);
419 #endif
420         OT_UNUSED_VARIABLE(aRxOnWhenIdle);
421     }
422 
423     /**
424      * Enables all radio links.
425      */
Enable(void)426     void Enable(void)
427     {
428 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
429         IgnoreError(mSubMac.Enable());
430 #endif
431 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
432         mTrel.Enable();
433 #endif
434     }
435 
436     /**
437      * Disables all radio links.
438      */
Disable(void)439     void Disable(void)
440     {
441 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
442         IgnoreError(mSubMac.Disable());
443 #endif
444 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
445         mTrel.Disable();
446 #endif
447     }
448 
449     /**
450      * Transitions all radio links to Sleep.
451      */
Sleep(void)452     void Sleep(void)
453     {
454 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
455         IgnoreError(mSubMac.Sleep());
456 #endif
457 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
458         mTrel.Sleep();
459 #endif
460     }
461 
462 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
463     /**
464      * Configures CSL parameters in all radios.
465      *
466      * @param[in]  aPeriod    The CSL period.
467      * @param[in]  aChannel   The CSL channel.
468      * @param[in]  aShortAddr The short source address of CSL receiver's peer.
469      * @param[in]  aExtAddr   The extended source address of CSL receiver's peer.
470      *
471      * @retval  TRUE if CSL Period or CSL Channel changed.
472      * @retval  FALSE if CSL Period and CSL Channel did not change.
473      */
UpdateCsl(uint16_t aPeriod,uint8_t aChannel,otShortAddress aShortAddr,const otExtAddress * aExtAddr)474     bool UpdateCsl(uint16_t aPeriod, uint8_t aChannel, otShortAddress aShortAddr, const otExtAddress *aExtAddr)
475     {
476         bool retval = false;
477 
478         OT_UNUSED_VARIABLE(aPeriod);
479         OT_UNUSED_VARIABLE(aChannel);
480         OT_UNUSED_VARIABLE(aShortAddr);
481         OT_UNUSED_VARIABLE(aExtAddr);
482 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
483         retval = mSubMac.UpdateCsl(aPeriod, aChannel, aShortAddr, aExtAddr);
484 #endif
485         return retval;
486     }
487 
488     /**
489      * Transitions all radios link to CSL sample state, given that a non-zero CSL period is configured.
490      *
491      * CSL sample state is only applicable and used for 15.4 radio link. Other link are transitioned to sleep state
492      * when CSL period is non-zero.
493      */
CslSample(void)494     void CslSample(void)
495     {
496 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
497         mSubMac.CslSample();
498 #endif
499 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
500         mTrel.Sleep();
501 #endif
502     }
503 #endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
504 
505 #if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
506     /**
507      * Configures wake-up listening parameters in all radios.
508      *
509      * @param[in]  aEnable    Whether to enable or disable wake-up listening.
510      * @param[in]  aInterval  The wake-up listen interval in microseconds.
511      * @param[in]  aDuration  The wake-up listen duration in microseconds.
512      * @param[in]  aChannel   The wake-up channel.
513      */
UpdateWakeupListening(bool aEnable,uint32_t aInterval,uint32_t aDuration,uint8_t aChannel)514     void UpdateWakeupListening(bool aEnable, uint32_t aInterval, uint32_t aDuration, uint8_t aChannel)
515     {
516         OT_UNUSED_VARIABLE(aEnable);
517         OT_UNUSED_VARIABLE(aInterval);
518         OT_UNUSED_VARIABLE(aDuration);
519         OT_UNUSED_VARIABLE(aChannel);
520 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
521         mSubMac.UpdateWakeupListening(aEnable, aInterval, aDuration, aChannel);
522 #endif
523     }
524 #endif
525 
526     /**
527      * Transitions all radio links to Receive.
528      *
529      * @param[in]  aChannel   The channel to use for receiving.
530      */
Receive(uint8_t aChannel)531     void Receive(uint8_t aChannel)
532     {
533 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
534         IgnoreError(mSubMac.Receive(aChannel));
535 #endif
536 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
537         mTrel.Receive(aChannel);
538 #endif
539     }
540 
541     /**
542      * Gets the radio transmit frames.
543      *
544      * @returns The transmit frames.
545      */
GetTxFrames(void)546     TxFrames &GetTxFrames(void) { return mTxFrames; }
547 
548 #if !OPENTHREAD_CONFIG_MULTI_RADIO
549 
550     /**
551      * Sends a prepared frame.
552      *
553      * The prepared frame is from `GetTxFrames()`. This method is available only in single radio link mode.
554      */
Send(void)555     void Send(void)
556     {
557 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
558         SuccessOrAssert(mSubMac.Send());
559 #endif
560 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
561         mTrel.Send();
562 #endif
563     }
564 
565 #else // #if !OPENTHREAD_CONFIG_MULTI_RADIO
566 
567     /**
568      * Sends prepared frames over a given set of radio links.
569      *
570      * The prepared frame must be from `GetTxFrames()`. This method is available only in multi radio link mode.
571      *
572      * @param[in] aFrame       A reference to a prepared frame.
573      * @param[in] aRadioTypes  A set of radio types to send on.
574      */
575     void Send(TxFrame &aFrame, RadioTypes aRadioTypes);
576 
577 #endif // !OPENTHREAD_CONFIG_MULTI_RADIO
578 
579     /**
580      * Gets the number of transmit retries for the last transmitted frame.
581      *
582      * @returns Number of transmit retries.
583      */
GetTransmitRetries(void) const584     uint8_t GetTransmitRetries(void) const
585     {
586         return
587 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
588             mSubMac.GetTransmitRetries();
589 #else
590             0;
591 #endif
592     }
593 
594     /**
595      * Gets the most recent RSSI measurement from radio link.
596      *
597      * @returns The RSSI in dBm when it is valid. `Radio::kInvalidRssi` when RSSI is invalid.
598      */
GetRssi(void) const599     int8_t GetRssi(void) const
600     {
601         return
602 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
603             mSubMac.GetRssi();
604 #else
605             Radio::kInvalidRssi;
606 #endif
607     }
608 
609     /**
610      * Begins energy scan.
611      *
612      * @param[in] aScanChannel   The channel to perform the energy scan on.
613      * @param[in] aScanDuration  The duration, in milliseconds, for the channel to be scanned.
614      *
615      * @retval kErrorNone            Successfully started scanning the channel.
616      * @retval kErrorBusy            The radio is performing energy scanning.
617      * @retval kErrorInvalidState    The radio was disabled or transmitting.
618      * @retval kErrorNotImplemented  Energy scan is not supported by radio link.
619      */
EnergyScan(uint8_t aScanChannel,uint16_t aScanDuration)620     Error EnergyScan(uint8_t aScanChannel, uint16_t aScanDuration)
621     {
622         OT_UNUSED_VARIABLE(aScanChannel);
623         OT_UNUSED_VARIABLE(aScanDuration);
624 
625         return
626 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
627             mSubMac.EnergyScan(aScanChannel, aScanDuration);
628 #else
629             kErrorNotImplemented;
630 #endif
631     }
632 
633     /**
634      * Returns the noise floor value (currently use the radio receive sensitivity value).
635      *
636      * @returns The noise floor value in dBm.
637      */
GetNoiseFloor(void) const638     int8_t GetNoiseFloor(void) const
639     {
640         return
641 #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
642             mSubMac.GetNoiseFloor();
643 #else
644             kDefaultNoiseFloor;
645 #endif
646     }
647 
648     /**
649      * Gets a reference to the `SubMac` instance.
650      *
651      * @returns A reference to the `SubMac` instance.
652      */
GetSubMac(void)653     SubMac &GetSubMac(void) { return mSubMac; }
654 
655     /**
656      * Gets a reference to the `SubMac` instance.
657      *
658      * @returns A reference to the `SubMac` instance.
659      */
GetSubMac(void) const660     const SubMac &GetSubMac(void) const { return mSubMac; }
661 
662     /**
663      * Returns a reference to the current MAC key (for Key Mode 1) for a given Frame.
664      *
665      * @param[in] aFrame    The frame for which to get the MAC key.
666      *
667      * @returns A reference to the current MAC key.
668      */
669     const KeyMaterial *GetCurrentMacKey(const Frame &aFrame) const;
670 
671     /**
672      * Returns a reference to the temporary MAC key (for Key Mode 1) for a given Frame based on a given
673      * Key Sequence.
674      *
675      * @param[in] aFrame        The frame for which to get the MAC key.
676      * @param[in] aKeySequence  The Key Sequence number (MUST be one off (+1 or -1) from current key sequence number).
677      *
678      * @returns A reference to the temporary MAC key.
679      */
680     const KeyMaterial *GetTemporaryMacKey(const Frame &aFrame, uint32_t aKeySequence) const;
681 
682 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
683     /**
684      * Sets the current MAC frame counter value from the value from a `TxFrame`.
685      *
686      * @param[in] TxFrame  The `TxFrame` from which to get the counter value.
687      *
688      * @retval kErrorNone            If successful.
689      * @retval kErrorInvalidState    If the raw link-layer isn't enabled.
690      */
691     void SetMacFrameCounter(TxFrame &aFrame);
692 #endif
693 
694 private:
695     static constexpr int8_t kDefaultNoiseFloor = Radio::kDefaultReceiveSensitivity;
696 
697     SubMac mSubMac;
698 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
699     Trel::Link mTrel;
700 #endif
701 
702     // `TxFrames` member definition should be after `mSubMac`, `mTrel`
703     // definitions to allow it to use their methods from its
704     // constructor.
705     TxFrames mTxFrames;
706 
707 #if !OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
708     ShortAddress mShortAddress;
709     ShortAddress mAlternateShortAddress;
710     ExtAddress   mExtAddress;
711 #endif
712 };
713 
714 /**
715  * @}
716  */
717 
718 } // namespace Mac
719 } // namespace ot
720 
721 #endif // MAC_LINKS_HPP_
722