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