• 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 /**
30  * @file
31  *   This file includes definitions for managing Domain Unicast Address feature defined in Thread 1.2.
32  */
33 
34 #ifndef DUA_MANAGER_HPP_
35 #define DUA_MANAGER_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #if OPENTHREAD_CONFIG_DUA_ENABLE || (OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE)
40 
41 #if OPENTHREAD_CONFIG_DUA_ENABLE && (OPENTHREAD_CONFIG_THREAD_VERSION < OT_THREAD_VERSION_1_2)
42 #error "Thread 1.2 or higher version is required for OPENTHREAD_CONFIG_DUA_ENABLE"
43 #endif
44 
45 #if OPENTHREAD_CONFIG_DUA_ENABLE && !OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE
46 #error "OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE is required for OPENTHREAD_CONFIG_DUA_ENABLE"
47 #endif
48 
49 #include "backbone_router/bbr_leader.hpp"
50 #include "coap/coap_message.hpp"
51 #include "common/locator.hpp"
52 #include "common/non_copyable.hpp"
53 #include "common/notifier.hpp"
54 #include "common/tasklet.hpp"
55 #include "common/time.hpp"
56 #include "common/time_ticker.hpp"
57 #include "common/timer.hpp"
58 #include "net/netif.hpp"
59 #include "thread/child.hpp"
60 #include "thread/thread_tlvs.hpp"
61 #include "thread/tmf.hpp"
62 
63 namespace ot {
64 
65 /**
66  * @addtogroup core-dua
67  *
68  * @brief
69  *   This module includes definitions for generating, managing, registering Domain Unicast Address.
70  *
71  * @{
72  *
73  * @defgroup core-dua Dua
74  *
75  * @}
76  */
77 
78 /**
79  * Implements managing DUA.
80  */
81 class DuaManager : public InstanceLocator, private NonCopyable
82 {
83     friend class ot::Notifier;
84     friend class ot::TimeTicker;
85     friend class Tmf::Agent;
86 
87 public:
88     /**
89      * Initializes the object.
90      *
91      * @param[in]  aInstance     A reference to the OpenThread instance.
92      */
93     explicit DuaManager(Instance &aInstance);
94 
95     /**
96      * Notifies Domain Prefix changes.
97      *
98      * @param[in]  aEvent  The Domain Prefix event.
99      */
100     void HandleDomainPrefixUpdate(BackboneRouter::DomainPrefixEvent aEvent);
101 
102     /**
103      * Notifies Primary Backbone Router status.
104      *
105      * @param[in]  aState   The state or state change of Primary Backbone Router.
106      * @param[in]  aConfig  The Primary Backbone Router service.
107      */
108     void HandleBackboneRouterPrimaryUpdate(BackboneRouter::Leader::State aState, const BackboneRouter::Config &aConfig);
109 
110 #if OPENTHREAD_CONFIG_DUA_ENABLE
111 
112     /**
113      * Returns a reference to the Domain Unicast Address.
114      *
115      * @returns A reference to the Domain Unicast Address.
116      */
GetDomainUnicastAddress(void) const117     const Ip6::Address &GetDomainUnicastAddress(void) const { return mDomainUnicastAddress.GetAddress(); }
118 
119     /**
120      * Sets the Interface Identifier manually specified for the Thread Domain Unicast Address.
121      *
122      * @param[in]  aIid        A reference to the Interface Identifier to set.
123      *
124      * @retval kErrorNone          Successfully set the Interface Identifier.
125      * @retval kErrorInvalidArgs   The specified Interface Identifier is reserved.
126      */
127     Error SetFixedDuaInterfaceIdentifier(const Ip6::InterfaceIdentifier &aIid);
128 
129     /**
130      * Clears the Interface Identifier manually specified for the Thread Domain Unicast Address.
131      */
132     void ClearFixedDuaInterfaceIdentifier(void);
133 
134     /**
135      * Indicates whether or not there is Interface Identifier manually specified for the Thread
136      * Domain Unicast Address.
137      *
138      * @retval true  If there is Interface Identifier manually specified.
139      * @retval false If there is no Interface Identifier manually specified.
140      */
IsFixedDuaInterfaceIdentifierSet(void)141     bool IsFixedDuaInterfaceIdentifierSet(void) { return !mFixedDuaInterfaceIdentifier.IsUnspecified(); }
142 
143     /**
144      * Gets the Interface Identifier for the Thread Domain Unicast Address if manually specified.
145      *
146      * @returns A reference to the Interface Identifier.
147      */
GetFixedDuaInterfaceIdentifier(void) const148     const Ip6::InterfaceIdentifier &GetFixedDuaInterfaceIdentifier(void) const { return mFixedDuaInterfaceIdentifier; }
149 
150     /*
151      * Restores duplicate address detection information from non-volatile memory.
152      */
153     void Restore(void);
154 
155     /**
156      * Notifies duplicated Domain Unicast Address.
157      */
158     void NotifyDuplicateDomainUnicastAddress(void);
159 #endif
160 
161 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE
162     /**
163      * Events related to a Child DUA address.
164      */
165     enum ChildDuaAddressEvent : uint8_t
166     {
167         kAddressAdded,     ///< A new DUA registered by the Child via Address Registration.
168         kAddressChanged,   ///< A different DUA registered by the Child via Address Registration.
169         kAddressRemoved,   ///< DUA registered by the Child is removed and not in Address Registration.
170         kAddressUnchanged, ///< The Child registers the same DUA again.
171     };
172 
173     /**
174      * Handles Child DUA address event.
175      *
176      * @param[in] aChild   A child.
177      * @param[in] aEvent   The DUA address event for @p aChild.
178      */
179     void HandleChildDuaAddressEvent(const Child &aChild, ChildDuaAddressEvent aEvent);
180 #endif
181 
182 private:
183     static constexpr uint32_t kDuaDadPeriod               = 100; // DAD wait time to become "Preferred" (in sec).
184     static constexpr uint8_t  kNoBufDelay                 = 5;   // In sec.
185     static constexpr uint8_t  KResponseTimeoutDelay       = 30;  // In sec.
186     static constexpr uint8_t  kNewRouterRegistrationDelay = 3;   // Delay (in sec) to establish link for a new router.
187     static constexpr uint8_t  kNewDuaRegistrationDelay    = 1;   // Delay (in sec) for newly added DUA.
188 
189 #if OPENTHREAD_CONFIG_DUA_ENABLE
190     Error GenerateDomainUnicastAddressIid(void);
191     Error Store(void);
192 
193     void AddDomainUnicastAddress(void);
194     void RemoveDomainUnicastAddress(void);
195     void UpdateRegistrationDelay(uint8_t aDelay);
196 #endif
197 
198 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE
199     void SendAddressNotification(Ip6::Address &aAddress, ThreadStatusTlv::DuaStatus aStatus, const Child &aChild);
200 #endif
201 
202     void HandleNotifierEvents(Events aEvents);
203 
204     void HandleTimeTick(void);
205 
206     void UpdateTimeTickerRegistration(void);
207 
208     static void HandleDuaResponse(void                *aContext,
209                                   otMessage           *aMessage,
210                                   const otMessageInfo *aMessageInfo,
211                                   otError              aResult);
212     void        HandleDuaResponse(Coap::Message *aMessage, const Ip6::MessageInfo *aMessageInfo, Error aResult);
213 
214     template <Uri kUri> void HandleTmf(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
215 
216     Error ProcessDuaResponse(Coap::Message &aMessage);
217 
218     void PerformNextRegistration(void);
219     void UpdateReregistrationDelay(void);
220     void UpdateCheckDelay(uint8_t aDelay);
221 
222     using RegistrationTask = TaskletIn<DuaManager, &DuaManager::PerformNextRegistration>;
223 
224     RegistrationTask mRegistrationTask;
225     Ip6::Address     mRegisteringDua;
226     bool             mIsDuaPending : 1;
227 
228 #if OPENTHREAD_CONFIG_DUA_ENABLE
229     enum DuaState : uint8_t
230     {
231         kNotExist,    ///< DUA is not available.
232         kToRegister,  ///< DUA is to be registered.
233         kRegistering, ///< DUA is being registered.
234         kRegistered,  ///< DUA is registered.
235     };
236 
237     DuaState  mDuaState;
238     uint8_t   mDadCounter;
239     TimeMilli mLastRegistrationTime; // The time (in milliseconds) when sent last DUA.req or received DUA.rsp.
240     Ip6::InterfaceIdentifier   mFixedDuaInterfaceIdentifier;
241     Ip6::Netif::UnicastAddress mDomainUnicastAddress;
242 #endif
243 
244     union
245     {
246         struct
247         {
248             uint16_t mReregistrationDelay; // Delay (in seconds) for DUA re-registration.
249             uint8_t  mCheckDelay;          // Delay (in seconds) for checking whether or not registration is required.
250 #if OPENTHREAD_CONFIG_DUA_ENABLE
251             uint8_t mRegistrationDelay; // Delay (in seconds) for DUA registration.
252 #endif
253         } mFields;
254         uint32_t mValue; // Non-zero indicates timer should start.
255     } mDelay;
256 
257 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE
258     // TODO: (DUA) may re-evaluate the alternative option of distributing the flags into the child table:
259     //       - Child class itself have some padding - may save some RAM
260     //       - Avoid cross reference between a bit-vector and the child entry
261     ChildMask mChildDuaMask;             // Child Mask for child who registers DUA via Child Update Request.
262     ChildMask mChildDuaRegisteredMask;   // Child Mask for child's DUA that was registered by the parent on behalf.
263     uint16_t  mChildIndexDuaRegistering; // Child Index of the DUA being registered.
264 #endif
265 };
266 
267 DeclareTmfHandler(DuaManager, kUriDuaRegistrationNotify);
268 
269 } // namespace ot
270 
271 #endif // OPENTHREAD_CONFIG_DUA_ENABLE || (OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE)
272 #endif // DUA_MANAGER_HPP_
273