| /* |
| * Copyright (c) 2020, The OpenThread Authors. |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * 3. Neither the name of the copyright holder nor the |
| * names of its contributors may be used to endorse or promote products |
| * derived from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
| * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| * POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #ifndef CSL_TX_SCHEDULER_HPP_ |
| #define CSL_TX_SCHEDULER_HPP_ |
| |
| #include "openthread-core-config.h" |
| |
| #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE |
| |
| #include "common/locator.hpp" |
| #include "common/message.hpp" |
| #include "common/non_copyable.hpp" |
| #include "common/time.hpp" |
| #include "mac/mac.hpp" |
| #include "mac/mac_frame.hpp" |
| #include "thread/indirect_sender_frame_context.hpp" |
| |
| namespace ot { |
| |
| /** |
| * @addtogroup core-mesh-forwarding |
| * |
| * @brief |
| * This module includes definitions for CSL transmission scheduling. |
| * |
| * @{ |
| */ |
| |
| class Child; |
| |
| /** |
| * This class implements CSL tx scheduling functionality. |
| * |
| */ |
| class CslTxScheduler : public InstanceLocator, private NonCopyable |
| { |
| friend class Mac::Mac; |
| friend class IndirectSender; |
| |
| public: |
| static constexpr uint8_t kMaxCslTriggeredTxAttempts = OPENTHREAD_CONFIG_MAC_MAX_TX_ATTEMPTS_INDIRECT_POLLS; |
| |
| /** |
| * This class defines all the child info required for scheduling CSL transmissions. |
| * |
| * `Child` class publicly inherits from this class. |
| * |
| */ |
| class ChildInfo |
| { |
| public: |
| uint8_t GetCslTxAttempts(void) const { return mCslTxAttempts; } |
| void IncrementCslTxAttempts(void) { mCslTxAttempts++; } |
| void ResetCslTxAttempts(void) { mCslTxAttempts = 0; } |
| |
| bool IsCslSynchronized(void) const { return mCslSynchronized && mCslPeriod > 0; } |
| void SetCslSynchronized(bool aCslSynchronized) { mCslSynchronized = aCslSynchronized; } |
| |
| uint8_t GetCslChannel(void) const { return mCslChannel; } |
| void SetCslChannel(uint8_t aChannel) { mCslChannel = aChannel; } |
| |
| uint32_t GetCslTimeout(void) const { return mCslTimeout; } |
| void SetCslTimeout(uint32_t aTimeout) { mCslTimeout = aTimeout; } |
| |
| uint16_t GetCslPeriod(void) const { return mCslPeriod; } |
| void SetCslPeriod(uint16_t aPeriod) { mCslPeriod = aPeriod; } |
| |
| uint16_t GetCslPhase(void) const { return mCslPhase; } |
| void SetCslPhase(uint16_t aPhase) { mCslPhase = aPhase; } |
| |
| TimeMilli GetCslLastHeard(void) const { return mCslLastHeard; } |
| void SetCslLastHeard(TimeMilli aCslLastHeard) { mCslLastHeard = aCslLastHeard; } |
| |
| uint64_t GetLastRxTimestamp(void) const { return mLastRxTimstamp; } |
| void SetLastRxTimestamp(uint64_t aLastRxTimestamp) { mLastRxTimstamp = aLastRxTimestamp; } |
| |
| private: |
| uint8_t mCslTxAttempts : 7; ///< Number of CSL triggered tx attempts. |
| bool mCslSynchronized : 1; ///< Indicates whether or not the child is CSL synchronized. |
| uint8_t mCslChannel; ///< The channel the device will listen on. |
| uint32_t mCslTimeout; ///< The sync timeout, in seconds. |
| uint16_t mCslPeriod; ///< CSL sampled listening period in units of 10 symbols (160 microseconds). |
| uint16_t mCslPhase; ///< The time when the next CSL sample will start. |
| TimeMilli mCslLastHeard; ///< Time when last frame containing CSL IE was heard. |
| uint64_t mLastRxTimstamp; ///< Time when last frame containing CSL IE was received, in microseconds. |
| |
| static_assert(kMaxCslTriggeredTxAttempts < (1 << 7), "mCslTxAttempts cannot fit max!"); |
| }; |
| |
| /** |
| * This class defines the callbacks used by the `CslTxScheduler`. |
| * |
| */ |
| class Callbacks : public InstanceLocator |
| { |
| friend class CslTxScheduler; |
| |
| private: |
| typedef IndirectSenderBase::FrameContext FrameContext; |
| |
| /** |
| * This constructor initializes the callbacks object. |
| * |
| * @param[in] aInstance A reference to the OpenThread instance. |
| * |
| */ |
| explicit Callbacks(Instance &aInstance); |
| |
| /** |
| * This callback method requests a frame to be prepared for CSL transmission to a given SSED. |
| * |
| * @param[out] aFrame A reference to a MAC frame where the new frame would be placed. |
| * @param[out] aContext A reference to a `FrameContext` where the context for the new frame would be placed. |
| * @param[in] aChild The child for which to prepare the frame. |
| * |
| * @retval kErrorNone Frame was prepared successfully. |
| * @retval kErrorAbort CSL transmission should be aborted (no frame for the child). |
| * |
| */ |
| Error PrepareFrameForChild(Mac::TxFrame &aFrame, FrameContext &aContext, Child &aChild); |
| |
| /** |
| * This callback method notifies the end of CSL frame transmission to a child. |
| * |
| * @param[in] aFrame The transmitted frame. |
| * @param[in] aContext The context associated with the frame when it was prepared. |
| * @param[in] aError kErrorNone when the frame was transmitted successfully, |
| * kErrorNoAck when the frame was transmitted but no ACK was received, |
| * kErrorChannelAccessFailure tx failed due to activity on the channel, |
| * kErrorAbort when transmission was aborted for other reasons. |
| * @param[in] aChild The child to which the frame was transmitted. |
| * |
| */ |
| void HandleSentFrameToChild(const Mac::TxFrame &aFrame, |
| const FrameContext &aContext, |
| Error aError, |
| Child & aChild); |
| }; |
| /** |
| * This constructor initializes the CSL tx scheduler object. |
| * |
| * @param[in] aInstance A reference to the OpenThread instance. |
| * |
| */ |
| explicit CslTxScheduler(Instance &aInstance); |
| |
| /** |
| * This method updates the next CSL transmission (finds the nearest child). |
| * |
| * 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 |
| * done yet, and it's aborted, this method would set `mCslTxChild` to `nullptr` to notify the `HandleTransmitDone` |
| * that the operation has been aborted. |
| * |
| */ |
| void Update(void); |
| |
| /** |
| * This method clears all the states inside `CslTxScheduler` and the related states in each child. |
| * |
| */ |
| void Clear(void); |
| |
| private: |
| void InitFrameRequestAhead(void); |
| void RescheduleCslTx(void); |
| |
| uint32_t GetNextCslTransmissionDelay(const Child &aChild, uint32_t &aDelayFromLastRx) const; |
| |
| // Callbacks from `Mac` |
| Mac::TxFrame *HandleFrameRequest(Mac::TxFrames &aTxFrames); |
| void HandleSentFrame(const Mac::TxFrame &aFrame, Error aError); |
| |
| void HandleSentFrame(const Mac::TxFrame &aFrame, Error aError, Child &aChild); |
| |
| uint32_t mCslFrameRequestAheadUs; |
| Child * mCslTxChild; |
| Message * mCslTxMessage; |
| Callbacks::FrameContext mFrameContext; |
| Callbacks mCallbacks; |
| }; |
| |
| /** |
| * @} |
| * |
| */ |
| |
| } // namespace ot |
| |
| #endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE |
| |
| #endif // CSL_TX_SCHEDULER_HPP_ |