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