• 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_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 CslNeighbor;
56 
57 /**
58  * Implements CSL tx scheduling functionality.
59  */
60 class CslTxScheduler : public InstanceLocator, private NonCopyable
61 {
62     friend class Mac::Mac;
63     friend class IndirectSender;
64 
65 public:
66     static constexpr uint8_t kMaxCslTriggeredTxAttempts = OPENTHREAD_CONFIG_MAC_MAX_TX_ATTEMPTS_INDIRECT_POLLS;
67 
68     /**
69      * Defines all the neighbor info required for scheduling CSL transmissions.
70      *
71      * `CslNeighbor` publicly inherits from this class.
72      */
73     class NeighborInfo
74     {
75     public:
GetCslTxAttempts(void) const76         uint8_t GetCslTxAttempts(void) const { return mCslTxAttempts; }
IncrementCslTxAttempts(void)77         void    IncrementCslTxAttempts(void) { mCslTxAttempts++; }
ResetCslTxAttempts(void)78         void    ResetCslTxAttempts(void) { mCslTxAttempts = 0; }
79 
IsCslSynchronized(void) const80         bool IsCslSynchronized(void) const { return mCslSynchronized && mCslPeriod > 0; }
SetCslSynchronized(bool aCslSynchronized)81         void SetCslSynchronized(bool aCslSynchronized) { mCslSynchronized = aCslSynchronized; }
82 
GetCslChannel(void) const83         uint8_t GetCslChannel(void) const { return mCslChannel; }
SetCslChannel(uint8_t aChannel)84         void    SetCslChannel(uint8_t aChannel) { mCslChannel = aChannel; }
85 
GetCslTimeout(void) const86         uint32_t GetCslTimeout(void) const { return mCslTimeout; }
SetCslTimeout(uint32_t aTimeout)87         void     SetCslTimeout(uint32_t aTimeout) { mCslTimeout = aTimeout; }
88 
GetCslPeriod(void) const89         uint16_t GetCslPeriod(void) const { return mCslPeriod; }
SetCslPeriod(uint16_t aPeriod)90         void     SetCslPeriod(uint16_t aPeriod) { mCslPeriod = aPeriod; }
91 
GetCslPhase(void) const92         uint16_t GetCslPhase(void) const { return mCslPhase; }
SetCslPhase(uint16_t aPhase)93         void     SetCslPhase(uint16_t aPhase) { mCslPhase = aPhase; }
94 
GetCslLastHeard(void) const95         TimeMilli GetCslLastHeard(void) const { return mCslLastHeard; }
SetCslLastHeard(TimeMilli aCslLastHeard)96         void      SetCslLastHeard(TimeMilli aCslLastHeard) { mCslLastHeard = aCslLastHeard; }
97 
GetLastRxTimestamp(void) const98         uint64_t GetLastRxTimestamp(void) const { return mLastRxTimestamp; }
SetLastRxTimestamp(uint64_t aLastRxTimestamp)99         void     SetLastRxTimestamp(uint64_t aLastRxTimestamp) { mLastRxTimestamp = aLastRxTimestamp; }
100 
101     private:
102         uint8_t  mCslTxAttempts : 7;   ///< Number of CSL triggered tx attempts.
103         bool     mCslSynchronized : 1; ///< Indicates whether or not the child is CSL synchronized.
104         uint8_t  mCslChannel;          ///< The channel the device will listen on.
105         uint32_t mCslTimeout;          ///< The sync timeout, in seconds.
106         uint16_t mCslPeriod; ///< CSL sampled listening period between consecutive channel samples in units of 10
107                              ///< symbols (160 microseconds).
108 
109         /**
110          * The time in units of 10 symbols from the first symbol of the frame
111          * containing the CSL IE was transmitted until the next channel sample,
112          * see IEEE 802.15.4-2015, section 6.12.2.
113          *
114          * The Thread standard further defines the CSL phase (see Thread 1.4,
115          * section 3.2.6.3.4, also conforming to IEEE 802.15.4-2020, section
116          * 6.12.2.1):
117          *  * The "first symbol" from the definition SHALL be interpreted as the
118          *    first symbol of the MAC Header.
119          *  * "until the next channel sample":
120          *     * The CSL Receiver SHALL be ready to receive when the preamble
121          *       time T_pa as specified below is reached.
122          *     * The CSL Receiver SHOULD be ready to receive earlier than T_pa
123          *       and SHOULD stay ready to receive until after the time specified
124          *       in CSL Phase, according to the implementation and accuracy
125          *       expectations.
126          *     * The CSL Transmitter SHALL start transmitting the first symbol
127          *       of the preamble of the frame to transmit at the preamble time
128          *       T_pa = (CSL-Phase-Time – 192 us) (that is, CCA must be
129          *       performed before time T_pa). Here, CSL-Phase-Time is the time
130          *       duration specified by the CslPhase field value (in units of 10
131          *       symbol periods).
132          *     * This implies that the CSL Transmitter SHALL start transmitting
133          *       the first symbol of the MAC Header at the time T_mh =
134          *       CSL-Phase-Time.
135          *
136          * Derivation of the next TX timestamp based on this definition and the
137          * RX timestamp of the packet containing the CSL IE:
138          *
139          * Note that RX and TX timestamps are defined to point to the end of the
140          * synchronization header (SHR).
141          *
142          * lastTmh = lastRxTimestamp + phrDuration
143          *
144          * nextTmh = lastTmh + symbolPeriod * 10 * (n * cslPeriod + cslPhase)
145          *         = lastTmh + 160us * (n * cslPeriod + cslPhase)
146          *
147          * nextTxTimestamp
148          *         = nextTmh - phrDuration
149          *         = lastRxTimestamp + 160us * (n * cslPeriod + cslPhase)
150          */
151         uint16_t  mCslPhase;
152         TimeMilli mCslLastHeard; ///< Radio clock time when last frame containing CSL IE was heard.
153         uint64_t
154             mLastRxTimestamp; ///< Radio clock time when last frame containing CSL IE was received, in microseconds.
155 
156         static_assert(kMaxCslTriggeredTxAttempts < (1 << 7), "mCslTxAttempts cannot fit max!");
157     };
158 
159     /**
160      * Initializes the CSL tx scheduler object.
161      *
162      * @param[in]  aInstance   A reference to the OpenThread instance.
163      */
164     explicit CslTxScheduler(Instance &aInstance);
165 
166     /**
167      * Updates the next CSL transmission (finds the nearest child).
168      *
169      * 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
170      * done yet, and it's aborted, this method would clear current tx CSL neighbor to notify the `HandleTransmitDone`
171      * that the operation has been aborted.
172      */
173     void Update(void);
174 
175     /**
176      * Clears all the states inside `CslTxScheduler` and the related states in each child.
177      */
178     void Clear(void);
179 
180     /**
181      * Updates the value of `mCslFrameRequestAheadUs`, based on bus speed, bus latency and `Mac::kCslRequestAhead`.
182      */
183     void UpdateFrameRequestAhead(void);
184 
185 private:
186     // Guard time in usec to add when checking delay while preparing the CSL frame for tx.
187     static constexpr uint32_t kFramePreparationGuardInterval = 1500;
188 
189     typedef IndirectSenderBase::FrameContext FrameContext;
190 
191     void RescheduleCslTx(void);
192 
193     uint32_t GetNextCslTransmissionDelay(const CslNeighbor &aCslNeighbor,
194                                          uint32_t          &aDelayFromLastRx,
195                                          uint32_t           aAheadUs) const;
196 
197     // Callbacks from `Mac`
198     Mac::TxFrame *HandleFrameRequest(Mac::TxFrames &aTxFrames);
199     void          HandleSentFrame(const Mac::TxFrame &aFrame, Error aError);
200 
201     void HandleSentFrame(const Mac::TxFrame &aFrame, Error aError, CslNeighbor &aaCslNeighbor);
202 
203     uint32_t     mCslFrameRequestAheadUs;
204     CslNeighbor *mCslTxNeighbor;
205     Message     *mCslTxMessage;
206     FrameContext mFrameContext;
207 };
208 
209 /**
210  * @}
211  */
212 
213 } // namespace ot
214 
215 #endif // OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
216 
217 #endif // CSL_TX_SCHEDULER_HPP_
218