1 /* 2 * Copyright (c) 2016, 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 a Thread `Child`. 32 */ 33 34 #ifndef CHILD_HPP_ 35 #define CHILD_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #include "common/bit_set.hpp" 40 #include "thread/neighbor.hpp" 41 42 namespace ot { 43 44 #if OPENTHREAD_FTD 45 46 #if OPENTHREAD_CONFIG_MLE_IP_ADDRS_PER_CHILD < 2 47 #error OPENTHREAD_CONFIG_MLE_IP_ADDRS_PER_CHILD should be at least set to 2. 48 #endif 49 50 /** 51 * Represents a Thread Child. 52 */ 53 class Child : public CslNeighbor 54 { 55 public: 56 static constexpr uint8_t kMaxRequestTlvs = 6; 57 58 /** 59 * Maximum number of registered IPv6 addresses per child (excluding the mesh-local EID). 60 */ 61 static constexpr uint16_t kNumIp6Addresses = OPENTHREAD_CONFIG_MLE_IP_ADDRS_PER_CHILD - 1; 62 63 /** 64 * Represents the iterator for registered IPv6 address list of an MTD child. 65 */ 66 typedef otChildIp6AddressIterator AddressIterator; 67 68 /** 69 * The initial value for an `AddressIterator`. 70 */ 71 static constexpr AddressIterator kAddressIteratorInit = OT_CHILD_IP6_ADDRESS_ITERATOR_INIT; 72 73 /** 74 * Represents diagnostic information for a Thread Child. 75 */ 76 class Info : public otChildInfo, public Clearable<Info> 77 { 78 public: 79 /** 80 * Sets the `Info` instance from a given `Child`. 81 * 82 * @param[in] aChild A neighbor. 83 */ 84 void SetFrom(const Child &aChild); 85 }; 86 87 /** 88 * Represents an IPv6 address entry registered by an MTD child. 89 */ 90 class Ip6AddrEntry : public Ip6::Address 91 { 92 public: 93 /** 94 * Indicates whether the entry matches a given IPv6 address. 95 * 96 * @param[in] aAddress The IPv6 address. 97 * 98 * @retval TRUE The entry matches @p aAddress. 99 * @retval FALSE The entry does not match @p aAddress. 100 */ Matches(const Ip6::Address & aAddress) const101 bool Matches(const Ip6::Address &aAddress) const { return (*this == aAddress); } 102 103 #if OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE 104 /** 105 * Gets the MLR state of the IPv6 address entry. 106 * 107 * @param[in] aChild The child owning this address entry. 108 * 109 * @returns The MLR state of IPv6 address entry. 110 */ 111 MlrState GetMlrState(const Child &aChild) const; 112 113 /** 114 * Sets the MLR state of the IPv6 address entry. 115 * 116 * @param[in] aState The MLR state. 117 * @param[in] aChild The child owning this address entry. 118 */ 119 void SetMlrState(MlrState aState, Child &aChild); 120 #endif 121 }; 122 123 /** 124 * Represents an array of IPv6 address entries registered by an MTD child. 125 * 126 * This array does not include the mesh-local EID. 127 */ 128 typedef Array<Ip6AddrEntry, kNumIp6Addresses> Ip6AddressArray; 129 130 /** 131 * Initializes the `Child` object. 132 * 133 * @param[in] aInstance A reference to OpenThread instance. 134 */ Init(Instance & aInstance)135 void Init(Instance &aInstance) { Neighbor::Init(aInstance); } 136 137 /** 138 * Clears the child entry. 139 */ 140 void Clear(void); 141 142 /** 143 * Clears the IPv6 address list for the child. 144 */ 145 void ClearIp6Addresses(void); 146 147 /** 148 * Sets the device mode flags. 149 * 150 * @param[in] aMode The device mode flags. 151 */ 152 void SetDeviceMode(Mle::DeviceMode aMode); 153 154 /** 155 * Gets the mesh-local IPv6 address. 156 * 157 * @param[out] aAddress A reference to an IPv6 address to provide address (if any). 158 * 159 * @retval kErrorNone Successfully found the mesh-local address and updated @p aAddress. 160 * @retval kErrorNotFound No mesh-local IPv6 address in the IPv6 address list. 161 */ 162 Error GetMeshLocalIp6Address(Ip6::Address &aAddress) const; 163 164 /** 165 * Returns the Mesh Local Interface Identifier. 166 * 167 * @returns The Mesh Local Interface Identifier. 168 */ GetMeshLocalIid(void) const169 const Ip6::InterfaceIdentifier &GetMeshLocalIid(void) const { return mMeshLocalIid; } 170 171 /** 172 * Gets an array of registered IPv6 address entries by the child. 173 * 174 * The array does not include the mesh-local EID. The ML-EID can retrieved using `GetMeshLocalIp6Address()`. 175 * 176 * @returns The array of registered IPv6 addresses by the child. 177 */ GetIp6Addresses(void) const178 const Ip6AddressArray &GetIp6Addresses(void) const { return mIp6Addresses; } 179 180 /** 181 * Gets an array of registered IPv6 address entries by the child. 182 * 183 * The array does not include the mesh-local EID. The ML-EID can retrieved using `GetMeshLocalIp6Address()`. 184 * 185 * @returns The array of registered IPv6 addresses by the child. 186 */ GetIp6Addresses(void)187 Ip6AddressArray &GetIp6Addresses(void) { return mIp6Addresses; } 188 189 /** 190 * Iterates over all registered IPv6 addresses (using an iterator). 191 * 192 * @param[in,out] aIterator The iterator to use. On success the iterator will be updated. 193 * To get the first IPv6 address the iterator should be set to `kAddressIteratorInit` 194 * @param[out] aAddress A reference to an IPv6 address to return the address. 195 * 196 * @retval kErrorNone Successfully got the next IPv6 address. @p aIterator and @p aAddress are updated. 197 * @retval kErrorNotFound No more address. 198 */ 199 Error GetNextIp6Address(AddressIterator &aIterator, Ip6::Address &aAddress) const; 200 201 /** 202 * Adds an IPv6 address to the list. 203 * 204 * @param[in] aAddress A reference to IPv6 address to be added. 205 * 206 * @retval kErrorNone Successfully added the new address. 207 * @retval kErrorAlready Address is already in the list. 208 * @retval kErrorNoBufs Already at maximum number of addresses. No entry available to add the new address. 209 * @retval kErrorInvalidArgs Address is invalid (it is the Unspecified Address). 210 */ 211 Error AddIp6Address(const Ip6::Address &aAddress); 212 213 /** 214 * Removes an IPv6 address from the list. 215 * 216 * @param[in] aAddress A reference to IPv6 address to be removed. 217 * 218 * @retval kErrorNone Successfully removed the address. 219 * @retval kErrorNotFound Address was not found in the list. 220 * @retval kErrorInvalidArgs Address is invalid (it is the Unspecified Address). 221 */ 222 Error RemoveIp6Address(const Ip6::Address &aAddress); 223 224 /** 225 * Indicates whether an IPv6 address is in the list of IPv6 addresses of the child. 226 * 227 * @param[in] aAddress A reference to IPv6 address. 228 * 229 * @retval TRUE The address exists on the list. 230 * @retval FALSE Address was not found in the list. 231 */ 232 bool HasIp6Address(const Ip6::Address &aAddress) const; 233 234 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE 235 /** 236 * Retrieves the Domain Unicast Address registered by the child. 237 * 238 * @param[out] aAddress A reference to return the DUA address. 239 * 240 * @retval kErrorNone Successfully retrieved the DUA address, @p aAddress is updated. 241 * @retval kErrorNotFound Could not find any DUA address. 242 */ 243 Error GetDomainUnicastAddress(Ip6::Address &aAddress) const; 244 #endif 245 246 /** 247 * Gets the child timeout. 248 * 249 * @returns The child timeout. 250 */ GetTimeout(void) const251 uint32_t GetTimeout(void) const { return mTimeout; } 252 253 /** 254 * Sets the child timeout. 255 * 256 * @param[in] aTimeout The child timeout. 257 */ SetTimeout(uint32_t aTimeout)258 void SetTimeout(uint32_t aTimeout) { mTimeout = aTimeout; } 259 260 /** 261 * Gets the network data version. 262 * 263 * @returns The network data version. 264 */ GetNetworkDataVersion(void) const265 uint8_t GetNetworkDataVersion(void) const { return mNetworkDataVersion; } 266 267 /** 268 * Sets the network data version. 269 * 270 * @param[in] aVersion The network data version. 271 */ SetNetworkDataVersion(uint8_t aVersion)272 void SetNetworkDataVersion(uint8_t aVersion) { mNetworkDataVersion = aVersion; } 273 274 /** 275 * Generates a new challenge value to use during a child attach. 276 */ GenerateChallenge(void)277 void GenerateChallenge(void) { mAttachChallenge.GenerateRandom(); } 278 279 /** 280 * Gets the current challenge value used during attach. 281 * 282 * @returns The current challenge value. 283 */ GetChallenge(void) const284 const Mle::TxChallenge &GetChallenge(void) const { return mAttachChallenge; } 285 286 /** 287 * Clears the requested TLV list. 288 */ ClearRequestTlvs(void)289 void ClearRequestTlvs(void) { memset(mRequestTlvs, Mle::Tlv::kInvalid, sizeof(mRequestTlvs)); } 290 291 /** 292 * Returns the requested TLV at index @p aIndex. 293 * 294 * @param[in] aIndex The index into the requested TLV list. 295 * 296 * @returns The requested TLV at index @p aIndex. 297 */ GetRequestTlv(uint8_t aIndex) const298 uint8_t GetRequestTlv(uint8_t aIndex) const { return mRequestTlvs[aIndex]; } 299 300 /** 301 * Sets the requested TLV at index @p aIndex. 302 * 303 * @param[in] aIndex The index into the requested TLV list. 304 * @param[in] aType The TLV type. 305 */ SetRequestTlv(uint8_t aIndex,uint8_t aType)306 void SetRequestTlv(uint8_t aIndex, uint8_t aType) { mRequestTlvs[aIndex] = aType; } 307 308 /** 309 * Returns the supervision interval (in seconds). 310 * 311 * @returns The supervision interval (in seconds). 312 */ GetSupervisionInterval(void) const313 uint16_t GetSupervisionInterval(void) const { return mSupervisionInterval; } 314 315 /** 316 * Sets the supervision interval. 317 * 318 * @param[in] aInterval The supervision interval (in seconds). 319 */ SetSupervisionInterval(uint16_t aInterval)320 void SetSupervisionInterval(uint16_t aInterval) { mSupervisionInterval = aInterval; } 321 322 /** 323 * Increments the number of seconds since last supervision of the child. 324 */ IncrementSecondsSinceLastSupervision(void)325 void IncrementSecondsSinceLastSupervision(void) { mSecondsSinceSupervision++; } 326 327 /** 328 * Returns the number of seconds since last supervision of the child (last message to the child) 329 * 330 * @returns Number of seconds since last supervision of the child. 331 */ GetSecondsSinceLastSupervision(void) const332 uint16_t GetSecondsSinceLastSupervision(void) const { return mSecondsSinceSupervision; } 333 334 /** 335 * Resets the number of seconds since last supervision of the child to zero. 336 */ ResetSecondsSinceLastSupervision(void)337 void ResetSecondsSinceLastSupervision(void) { mSecondsSinceSupervision = 0; } 338 339 #if OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE 340 /** 341 * Returns if the Child has IPv6 address @p aAddress of MLR state `kMlrStateRegistered`. 342 * 343 * @param[in] aAddress The IPv6 address. 344 * 345 * @retval true If the Child has IPv6 address @p aAddress of MLR state `kMlrStateRegistered`. 346 * @retval false If the Child does not have IPv6 address @p aAddress of MLR state `kMlrStateRegistered`. 347 */ 348 bool HasMlrRegisteredAddress(const Ip6::Address &aAddress) const; 349 350 /** 351 * Returns if the Child has any IPv6 address of MLR state `kMlrStateRegistered`. 352 * 353 * @retval true If the Child has any IPv6 address of MLR state `kMlrStateRegistered`. 354 * @retval false If the Child does not have any IPv6 address of MLR state `kMlrStateRegistered`. 355 */ HasAnyMlrRegisteredAddress(void) const356 bool HasAnyMlrRegisteredAddress(void) const { return !mMlrRegisteredSet.IsEmpty(); } 357 358 /** 359 * Returns if the Child has any IPv6 address of MLR state `kMlrStateToRegister`. 360 * 361 * @retval true If the Child has any IPv6 address of MLR state `kMlrStateToRegister`. 362 * @retval false If the Child does not have any IPv6 address of MLR state `kMlrStateToRegister`. 363 */ HasAnyMlrToRegisterAddress(void) const364 bool HasAnyMlrToRegisterAddress(void) const { return !mMlrToRegisterSet.IsEmpty(); } 365 #endif // OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE 366 367 private: 368 typedef BitSet<kNumIp6Addresses> ChildIp6AddressSet; 369 370 uint32_t mTimeout; 371 372 Ip6::InterfaceIdentifier mMeshLocalIid; 373 Ip6AddressArray mIp6Addresses; 374 #if OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE 375 ChildIp6AddressSet mMlrToRegisterSet; 376 ChildIp6AddressSet mMlrRegisteredSet; 377 #endif 378 379 uint8_t mNetworkDataVersion; 380 381 union 382 { 383 uint8_t mRequestTlvs[kMaxRequestTlvs]; 384 Mle::TxChallenge mAttachChallenge; 385 }; 386 387 uint16_t mSupervisionInterval; 388 uint16_t mSecondsSinceSupervision; 389 }; 390 391 DefineCoreType(otChildInfo, Child::Info); 392 393 #endif // OPENTHREAD_FTD 394 395 } // namespace ot 396 397 #endif // CHILD_HPP_ 398