• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 handling of data polls and indirect frame transmission.
32  */
33 
34 #ifndef DATA_POLL_HANDLER_HPP_
35 #define DATA_POLL_HANDLER_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include "common/code_utils.hpp"
40 #include "common/locator.hpp"
41 #include "common/non_copyable.hpp"
42 #include "common/timer.hpp"
43 #include "mac/mac.hpp"
44 #include "mac/mac_frame.hpp"
45 #include "thread/indirect_sender_frame_context.hpp"
46 
47 namespace ot {
48 
49 /**
50  * @addtogroup core-data-poll-handler
51  *
52  * @brief
53  *   This module includes definitions for data poll handler.
54  *
55  * @{
56  */
57 
58 #if OPENTHREAD_FTD || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
59 
60 #if OPENTHREAD_FTD
61 class Child;
62 #endif
63 
64 /**
65  * Implements the data poll (mac data request command) handler.
66  */
67 class DataPollHandler : public InstanceLocator, private NonCopyable
68 {
69     friend class Mac::Mac;
70 
71 public:
72     static constexpr uint8_t kMaxPollTriggeredTxAttempts = OPENTHREAD_CONFIG_MAC_MAX_TX_ATTEMPTS_INDIRECT_POLLS;
73 
74     /**
75      * Defines frame change request types used as input to `RequestFrameChange()`.
76      */
77     enum FrameChange : uint8_t
78     {
79         kPurgeFrame,   ///< Indicates that previous frame should be purged. Any ongoing indirect tx should be aborted.
80         kReplaceFrame, ///< Indicates that previous frame needs to be replaced with a new higher priority one.
81     };
82 
83     /**
84      * Defines all the neighbor info required for handling of data polls and indirect frame transmissions.
85      *
86      * `Child` (and `CslNeighbor`) class publicly inherits from this class.
87      */
88     class NeighborInfo
89     {
90         friend class DataPollHandler;
91 #if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
92         friend class CslTxScheduler;
93 #endif
94 
95     private:
IsDataPollPending(void) const96         bool IsDataPollPending(void) const { return mDataPollPending; }
SetDataPollPending(bool aPending)97         void SetDataPollPending(bool aPending) { mDataPollPending = aPending; }
98 
GetIndirectFrameCounter(void) const99         uint32_t GetIndirectFrameCounter(void) const { return mIndirectFrameCounter; }
SetIndirectFrameCounter(uint32_t aFrameCounter)100         void     SetIndirectFrameCounter(uint32_t aFrameCounter) { mIndirectFrameCounter = aFrameCounter; }
101 
GetIndirectKeyId(void) const102         uint8_t GetIndirectKeyId(void) const { return mIndirectKeyId; }
SetIndirectKeyId(uint8_t aKeyId)103         void    SetIndirectKeyId(uint8_t aKeyId) { mIndirectKeyId = aKeyId; }
104 
GetIndirectTxAttempts(void) const105         uint8_t GetIndirectTxAttempts(void) const { return mIndirectTxAttempts; }
ResetIndirectTxAttempts(void)106         void    ResetIndirectTxAttempts(void) { mIndirectTxAttempts = 0; }
IncrementIndirectTxAttempts(void)107         void    IncrementIndirectTxAttempts(void) { mIndirectTxAttempts++; }
108 
GetIndirectDataSequenceNumber(void) const109         uint8_t GetIndirectDataSequenceNumber(void) const { return mIndirectDsn; }
SetIndirectDataSequenceNumber(uint8_t aDsn)110         void    SetIndirectDataSequenceNumber(uint8_t aDsn) { mIndirectDsn = aDsn; }
111 
IsFramePurgePending(void) const112         bool IsFramePurgePending(void) const { return mFramePurgePending; }
SetFramePurgePending(bool aPurgePending)113         void SetFramePurgePending(bool aPurgePending) { mFramePurgePending = aPurgePending; }
114 
IsFrameReplacePending(void) const115         bool IsFrameReplacePending(void) const { return mFrameReplacePending; }
SetFrameReplacePending(bool aReplacePending)116         void SetFrameReplacePending(bool aReplacePending) { mFrameReplacePending = aReplacePending; }
117 
118 #if OPENTHREAD_CONFIG_MULTI_RADIO
GetLastPollRadioType(void) const119         Mac::RadioType GetLastPollRadioType(void) const { return mLastPollRadioType; }
SetLastPollRadioType(Mac::RadioType aRadioType)120         void           SetLastPollRadioType(Mac::RadioType aRadioType) { mLastPollRadioType = aRadioType; }
121 #endif
122 
123         uint32_t mIndirectFrameCounter;    // Frame counter for current indirect frame (used for retx).
124         uint8_t  mIndirectKeyId;           // Key Id for current indirect frame (used for retx).
125         uint8_t  mIndirectDsn;             // MAC level Data Sequence Number (DSN) for retx attempts.
126         uint8_t  mIndirectTxAttempts : 5;  // Number of data poll triggered tx attempts.
127         bool     mDataPollPending : 1;     // Indicates whether or not a Data Poll was received.
128         bool     mFramePurgePending : 1;   // Indicates a pending purge request for the current indirect frame.
129         bool     mFrameReplacePending : 1; // Indicates a pending replace request for the current indirect frame.
130 #if OPENTHREAD_CONFIG_MULTI_RADIO
131         Mac::RadioType mLastPollRadioType; // The radio link last data poll frame was received on.
132 #endif
133 
134         static_assert(kMaxPollTriggeredTxAttempts < (1 << 5), "mIndirectTxAttempts cannot fit max!");
135     };
136 
137 #if OPENTHREAD_FTD
138 
139     /**
140      * Initializes the data poll handler object.
141      *
142      * @param[in]  aInstance   A reference to the OpenThread instance.
143      */
144     explicit DataPollHandler(Instance &aInstance);
145 
146     /**
147      * Clears any state/info saved per child for indirect frame transmission.
148      */
149     void Clear(void);
150 
151     /**
152      * Requests a frame change for a given child.
153      *
154      * Two types of frame change requests are supported:
155      *
156      * 1) "Purge Frame" which indicates that the previous frame should be purged and any ongoing indirect tx aborted.
157      * 2) "Replace Frame" which indicates that the previous frame needs to be replaced with a new higher priority one.
158      *
159      * If there is no ongoing indirect frame transmission to the child, the request will be handled immediately and the
160      * callback `HandleFrameChangeDone()` is called directly from this method itself. This callback notifies the next
161      * layer (`IndirectSender`) that the indirect frame/message for the child can be safely updated.
162      *
163      * If there is an ongoing indirect frame transmission to this child, the request can not be handled immediately.
164      * The following options can happen based on the request type:
165      *
166      * 1) In case of "purge" request, the ongoing indirect transmission is aborted and upon completion of the abort the
167      *    callback `HandleFrameChangeDone()` is invoked.
168      *
169      * 2) In case of "replace" request, the ongoing indirect transmission is allowed to finish (current tx attempt).
170      *    2.a) If the tx attempt is successful, the `IndirectSender::HandleSentFrameToChild()` in invoked which
171      *         indicates the "replace" could not happen (in this case `HandleFrameChangeDone()` is no longer called).
172      *    2.b) If the ongoing tx attempt is unsuccessful, then callback `HandleFrameChangeDone()` is invoked to allow
173      *         the next layer to update the frame/message for the child.
174      *
175      * If there is a pending request, a subsequent call to this method is ignored except for the case where pending
176      * request is for "replace frame" and new one is for "purge frame" where the "purge" overrides the "replace"
177      * request.
178      *
179      * @param[in]  aChange    The frame change type.
180      * @param[in]  aChild     The child to process its frame change.
181      */
182     void RequestFrameChange(FrameChange aChange, Child &aChild);
183 
184 private:
185     typedef IndirectSenderBase::FrameContext FrameContext;
186 
187     // Callbacks from MAC
188     void          HandleDataPoll(Mac::RxFrame &aFrame);
189     Mac::TxFrame *HandleFrameRequest(Mac::TxFrames &aTxFrames);
190     void          HandleSentFrame(const Mac::TxFrame &aFrame, Error aError);
191 
192     void HandleSentFrame(const Mac::TxFrame &aFrame, Error aError, Child &aChild);
193     void ProcessPendingPolls(void);
194     void ResetTxAttempts(Child &aChild);
195 
196     Child       *mIndirectTxChild; // The child being handled (`nullptr` indicates no active indirect tx).
197     FrameContext mFrameContext;    // Context for the prepared frame for the current indirect tx (if any)
198 
199 #endif // OPENTHREAD_FTD
200 };
201 
202 #endif // OPENTHREAD_FTD || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
203 
204 /**
205  * @}
206  */
207 
208 } // namespace ot
209 
210 #endif // DATA_POLL_HANDLER_HPP_
211