• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2020, 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 #ifndef CSL_TX_SCHEDULER_HPP_
30 #define CSL_TX_SCHEDULER_HPP_
31 
32 #include "openthread-core-config.h"
33 
34 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
35 
36 #include "common/locator.hpp"
37 #include "common/message.hpp"
38 #include "common/non_copyable.hpp"
39 #include "common/time.hpp"
40 #include "mac/mac.hpp"
41 #include "mac/mac_frame.hpp"
42 #include "thread/indirect_sender_frame_context.hpp"
43 
44 namespace ot {
45 
46 /**
47  * @addtogroup core-mesh-forwarding
48  *
49  * @brief
50  *   This module includes definitions for CSL transmission scheduling.
51  *
52  * @{
53  */
54 
55 class Child;
56 
57 /**
58  * This class implements CSL tx scheduling functionality.
59  *
60  */
61 class CslTxScheduler : public InstanceLocator, private NonCopyable
62 {
63     friend class Mac::Mac;
64     friend class IndirectSender;
65 
66 public:
67     static constexpr uint8_t kMaxCslTriggeredTxAttempts = OPENTHREAD_CONFIG_MAC_MAX_TX_ATTEMPTS_INDIRECT_POLLS;
68 
69     /**
70      * This class defines all the child info required for scheduling CSL transmissions.
71      *
72      * `Child` class publicly inherits from this class.
73      *
74      */
75     class ChildInfo
76     {
77     public:
GetCslTxAttempts(void) const78         uint8_t GetCslTxAttempts(void) const { return mCslTxAttempts; }
IncrementCslTxAttempts(void)79         void    IncrementCslTxAttempts(void) { mCslTxAttempts++; }
ResetCslTxAttempts(void)80         void    ResetCslTxAttempts(void) { mCslTxAttempts = 0; }
81 
IsCslSynchronized(void) const82         bool IsCslSynchronized(void) const { return mCslSynchronized && mCslPeriod > 0; }
SetCslSynchronized(bool aCslSynchronized)83         void SetCslSynchronized(bool aCslSynchronized) { mCslSynchronized = aCslSynchronized; }
84 
GetCslChannel(void) const85         uint8_t GetCslChannel(void) const { return mCslChannel; }
SetCslChannel(uint8_t aChannel)86         void    SetCslChannel(uint8_t aChannel) { mCslChannel = aChannel; }
87 
GetCslTimeout(void) const88         uint32_t GetCslTimeout(void) const { return mCslTimeout; }
SetCslTimeout(uint32_t aTimeout)89         void     SetCslTimeout(uint32_t aTimeout) { mCslTimeout = aTimeout; }
90 
GetCslPeriod(void) const91         uint16_t GetCslPeriod(void) const { return mCslPeriod; }
SetCslPeriod(uint16_t aPeriod)92         void     SetCslPeriod(uint16_t aPeriod) { mCslPeriod = aPeriod; }
93 
GetCslPhase(void) const94         uint16_t GetCslPhase(void) const { return mCslPhase; }
SetCslPhase(uint16_t aPhase)95         void     SetCslPhase(uint16_t aPhase) { mCslPhase = aPhase; }
96 
GetCslLastHeard(void) const97         TimeMilli GetCslLastHeard(void) const { return mCslLastHeard; }
SetCslLastHeard(TimeMilli aCslLastHeard)98         void      SetCslLastHeard(TimeMilli aCslLastHeard) { mCslLastHeard = aCslLastHeard; }
99 
GetLastRxTimestamp(void) const100         uint64_t GetLastRxTimestamp(void) const { return mLastRxTimstamp; }
SetLastRxTimestamp(uint64_t aLastRxTimestamp)101         void     SetLastRxTimestamp(uint64_t aLastRxTimestamp) { mLastRxTimstamp = aLastRxTimestamp; }
102 
103     private:
104         uint8_t   mCslTxAttempts : 7;   ///< Number of CSL triggered tx attempts.
105         bool      mCslSynchronized : 1; ///< Indicates whether or not the child is CSL synchronized.
106         uint8_t   mCslChannel;          ///< The channel the device will listen on.
107         uint32_t  mCslTimeout;          ///< The sync timeout, in seconds.
108         uint16_t  mCslPeriod;           ///< CSL sampled listening period in units of 10 symbols (160 microseconds).
109         uint16_t  mCslPhase;            ///< The time when the next CSL sample will start.
110         TimeMilli mCslLastHeard;        ///< Time when last frame containing CSL IE was heard.
111         uint64_t  mLastRxTimstamp;      ///< Time when last frame containing CSL IE was received, in microseconds.
112 
113         static_assert(kMaxCslTriggeredTxAttempts < (1 << 7), "mCslTxAttempts cannot fit max!");
114     };
115 
116     /**
117      * This class defines the callbacks used by the `CslTxScheduler`.
118      *
119      */
120     class Callbacks : public InstanceLocator
121     {
122         friend class CslTxScheduler;
123 
124     private:
125         typedef IndirectSenderBase::FrameContext FrameContext;
126 
127         /**
128          * This constructor initializes the callbacks object.
129          *
130          * @param[in]  aInstance   A reference to the OpenThread instance.
131          *
132          */
133         explicit Callbacks(Instance &aInstance);
134 
135         /**
136          * This callback method requests a frame to be prepared for CSL transmission to a given SSED.
137          *
138          * @param[out] aFrame    A reference to a MAC frame where the new frame would be placed.
139          * @param[out] aContext  A reference to a `FrameContext` where the context for the new frame would be placed.
140          * @param[in]  aChild    The child for which to prepare the frame.
141          *
142          * @retval kErrorNone   Frame was prepared successfully.
143          * @retval kErrorAbort  CSL transmission should be aborted (no frame for the child).
144          *
145          */
146         Error PrepareFrameForChild(Mac::TxFrame &aFrame, FrameContext &aContext, Child &aChild);
147 
148         /**
149          * This callback method notifies the end of CSL frame transmission to a child.
150          *
151          * @param[in]  aFrame     The transmitted frame.
152          * @param[in]  aContext   The context associated with the frame when it was prepared.
153          * @param[in]  aError     kErrorNone when the frame was transmitted successfully,
154          *                        kErrorNoAck when the frame was transmitted but no ACK was received,
155          *                        kErrorChannelAccessFailure tx failed due to activity on the channel,
156          *                        kErrorAbort when transmission was aborted for other reasons.
157          * @param[in]  aChild     The child to which the frame was transmitted.
158          *
159          */
160         void HandleSentFrameToChild(const Mac::TxFrame &aFrame,
161                                     const FrameContext &aContext,
162                                     Error               aError,
163                                     Child &             aChild);
164     };
165     /**
166      * This constructor initializes the CSL tx scheduler object.
167      *
168      * @param[in]  aInstance   A reference to the OpenThread instance.
169      *
170      */
171     explicit CslTxScheduler(Instance &aInstance);
172 
173     /**
174      * This method updates the next CSL transmission (finds the nearest child).
175      *
176      * It would then request the `Mac` to do the CSL tx. If the last CSL tx has been fired at `Mac` but hasn't been
177      * done yet, and it's aborted, this method would set `mCslTxChild` to `nullptr` to notify the `HandleTransmitDone`
178      * that the operation has been aborted.
179      *
180      */
181     void Update(void);
182 
183     /**
184      * This method clears all the states inside `CslTxScheduler` and the related states in each child.
185      *
186      */
187     void Clear(void);
188 
189 private:
190     void InitFrameRequestAhead(void);
191     void RescheduleCslTx(void);
192 
193     uint32_t GetNextCslTransmissionDelay(const Child &aChild, uint32_t &aDelayFromLastRx) const;
194 
195     // Callbacks from `Mac`
196     Mac::TxFrame *HandleFrameRequest(Mac::TxFrames &aTxFrames);
197     void          HandleSentFrame(const Mac::TxFrame &aFrame, Error aError);
198 
199     void HandleSentFrame(const Mac::TxFrame &aFrame, Error aError, Child &aChild);
200 
201     uint32_t                mCslFrameRequestAheadUs;
202     Child *                 mCslTxChild;
203     Message *               mCslTxMessage;
204     Callbacks::FrameContext mFrameContext;
205     Callbacks               mCallbacks;
206 };
207 
208 /**
209  * @}
210  *
211  */
212 
213 } // namespace ot
214 
215 #endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
216 
217 #endif // CSL_TX_SCHEDULER_HPP_
218