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 /** 46 * Represents a Thread Child. 47 * 48 */ 49 class Child : public Neighbor, 50 public IndirectSender::ChildInfo, 51 public DataPollHandler::ChildInfo 52 #if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE 53 , 54 public CslTxScheduler::ChildInfo 55 #endif 56 { 57 class AddressIteratorBuilder; 58 59 public: 60 static constexpr uint8_t kMaxRequestTlvs = 6; 61 62 /** 63 * Represents diagnostic information for a Thread Child. 64 * 65 */ 66 class Info : public otChildInfo, public Clearable<Info> 67 { 68 public: 69 /** 70 * Sets the `Info` instance from a given `Child`. 71 * 72 * @param[in] aChild A neighbor. 73 * 74 */ 75 void SetFrom(const Child &aChild); 76 }; 77 78 /** 79 * Defines an iterator used to go through IPv6 address entries of a child. 80 * 81 */ 82 class AddressIterator : public Unequatable<AddressIterator> 83 { 84 friend class AddressIteratorBuilder; 85 86 public: 87 /** 88 * Represents an index indicating the current IPv6 address entry to which the iterator is pointing. 89 * 90 */ 91 typedef otChildIp6AddressIterator Index; 92 93 /** 94 * Initializes the iterator associated with a given `Child` starting from beginning of the 95 * IPv6 address list. 96 * 97 * @param[in] aChild A reference to a child entry. 98 * @param[in] aFilter An IPv6 address type filter restricting iterator to certain type of addresses. 99 * 100 */ AddressIterator(const Child & aChild,Ip6::Address::TypeFilter aFilter=Ip6::Address::kTypeAny)101 explicit AddressIterator(const Child &aChild, Ip6::Address::TypeFilter aFilter = Ip6::Address::kTypeAny) 102 : AddressIterator(aChild, 0, aFilter) 103 { 104 } 105 106 /** 107 * Initializes the iterator associated with a given `Child` starting from a given index 108 * 109 * @param[in] aChild A reference to the child entry. 110 * @param[in] aIndex An index (`Index`) with which to initialize the iterator. 111 * @param[in] aFilter An IPv6 address type filter restricting iterator to certain type of addresses. 112 * 113 */ AddressIterator(const Child & aChild,Index aIndex,Ip6::Address::TypeFilter aFilter=Ip6::Address::kTypeAny)114 AddressIterator(const Child &aChild, Index aIndex, Ip6::Address::TypeFilter aFilter = Ip6::Address::kTypeAny) 115 : mChild(aChild) 116 , mFilter(aFilter) 117 , mIndex(aIndex) 118 { 119 Update(); 120 } 121 122 /** 123 * Converts the iterator into an index. 124 * 125 * @returns An index corresponding to the iterator. 126 * 127 */ GetAsIndex(void) const128 Index GetAsIndex(void) const { return mIndex; } 129 130 /** 131 * Gets the iterator's associated `Child` entry. 132 * 133 * @returns The associated child entry. 134 * 135 */ GetChild(void) const136 const Child &GetChild(void) const { return mChild; } 137 138 /** 139 * Gets the current `Child` IPv6 Address to which the iterator is pointing. 140 * 141 * @returns A pointer to the associated IPv6 Address, or `nullptr` if iterator is done. 142 * 143 */ 144 const Ip6::Address *GetAddress(void) const; 145 146 /** 147 * Indicates whether the iterator has reached end of the list. 148 * 149 * @retval TRUE There are no more entries in the list (reached end of the list). 150 * @retval FALSE The current entry is valid. 151 * 152 */ IsDone(void) const153 bool IsDone(void) const { return (mIndex >= kMaxIndex); } 154 155 /** 156 * Overloads `++` operator (pre-increment) to advance the iterator. 157 * 158 * The iterator is moved to point to the next `Address` entry. If there are no more `Ip6::Address` entries 159 * `IsDone()` returns `true`. 160 * 161 */ operator ++(void)162 void operator++(void) { mIndex++, Update(); } 163 164 /** 165 * Overloads `++` operator (post-increment) to advance the iterator. 166 * 167 * The iterator is moved to point to the next `Address` entry. If there are no more `Ip6::Address` entries 168 * `IsDone()` returns `true`. 169 * 170 */ operator ++(int)171 void operator++(int) { mIndex++, Update(); } 172 173 /** 174 * Overloads the `*` dereference operator and gets a reference to `Ip6::Address` to which the 175 * iterator is currently pointing. 176 * 177 * MUST be used when the iterator is not done (i.e., `IsDone()` returns `false`). 178 * 179 * @returns A reference to the `Ip6::Address` entry currently pointed by the iterator. 180 * 181 */ operator *(void) const182 const Ip6::Address &operator*(void) const { return *GetAddress(); } 183 184 /** 185 * Overloads operator `==` to evaluate whether or not two `Iterator` instances are equal. 186 * 187 * MUST be used when the two iterators are associated with the same `Child` entry. 188 * 189 * @param[in] aOther The other `Iterator` to compare with. 190 * 191 * @retval TRUE If the two `Iterator` objects are equal. 192 * @retval FALSE If the two `Iterator` objects are not equal. 193 * 194 */ operator ==(const AddressIterator & aOther) const195 bool operator==(const AddressIterator &aOther) const { return (mIndex == aOther.mIndex); } 196 197 private: 198 enum IteratorType : uint8_t 199 { 200 kEndIterator, 201 }; 202 203 static constexpr uint16_t kMaxIndex = OPENTHREAD_CONFIG_MLE_IP_ADDRS_PER_CHILD; 204 AddressIterator(const Child & aChild,IteratorType)205 AddressIterator(const Child &aChild, IteratorType) 206 : mChild(aChild) 207 , mIndex(kMaxIndex) 208 { 209 } 210 211 void Update(void); 212 213 const Child &mChild; 214 Ip6::Address::TypeFilter mFilter; 215 Index mIndex; 216 Ip6::Address mMeshLocalAddress; 217 }; 218 219 /** 220 * Initializes the `Child` object. 221 * 222 * @param[in] aInstance A reference to OpenThread instance. 223 * 224 */ Init(Instance & aInstance)225 void Init(Instance &aInstance) { Neighbor::Init(aInstance); } 226 227 /** 228 * Clears the child entry. 229 * 230 */ 231 void Clear(void); 232 233 /** 234 * Clears the IPv6 address list for the child. 235 * 236 */ 237 void ClearIp6Addresses(void); 238 239 /** 240 * Sets the device mode flags. 241 * 242 * @param[in] aMode The device mode flags. 243 * 244 */ 245 void SetDeviceMode(Mle::DeviceMode aMode); 246 247 /** 248 * Gets the mesh-local IPv6 address. 249 * 250 * @param[out] aAddress A reference to an IPv6 address to provide address (if any). 251 * 252 * @retval kErrorNone Successfully found the mesh-local address and updated @p aAddress. 253 * @retval kErrorNotFound No mesh-local IPv6 address in the IPv6 address list. 254 * 255 */ 256 Error GetMeshLocalIp6Address(Ip6::Address &aAddress) const; 257 258 /** 259 * Returns the Mesh Local Interface Identifier. 260 * 261 * @returns The Mesh Local Interface Identifier. 262 * 263 */ GetMeshLocalIid(void) const264 const Ip6::InterfaceIdentifier &GetMeshLocalIid(void) const { return mMeshLocalIid; } 265 266 /** 267 * Enables range-based `for` loop iteration over all (or a subset of) IPv6 addresses. 268 * 269 * Should be used as follows: to iterate over all addresses 270 * 271 * for (const Ip6::Address &address : child.IterateIp6Addresses()) { ... } 272 * 273 * or to iterate over a subset of IPv6 addresses determined by a given address type filter 274 * 275 * for (const Ip6::Address &address : child.IterateIp6Addresses(Ip6::Address::kTypeMulticast)) { ... } 276 * 277 * @param[in] aFilter An IPv6 address type filter restricting iteration to certain type of addresses (default is 278 * to accept any address type). 279 * 280 * @returns An IteratorBuilder instance. 281 * 282 */ IterateIp6Addresses(Ip6::Address::TypeFilter aFilter=Ip6::Address::kTypeAny) const283 AddressIteratorBuilder IterateIp6Addresses(Ip6::Address::TypeFilter aFilter = Ip6::Address::kTypeAny) const 284 { 285 return AddressIteratorBuilder(*this, aFilter); 286 } 287 288 /** 289 * Adds an IPv6 address to the list. 290 * 291 * @param[in] aAddress A reference to IPv6 address to be added. 292 * 293 * @retval kErrorNone Successfully added the new address. 294 * @retval kErrorAlready Address is already in the list. 295 * @retval kErrorNoBufs Already at maximum number of addresses. No entry available to add the new address. 296 * @retval kErrorInvalidArgs Address is invalid (it is the Unspecified Address). 297 * 298 */ 299 Error AddIp6Address(const Ip6::Address &aAddress); 300 301 /** 302 * Removes an IPv6 address from the list. 303 * 304 * @param[in] aAddress A reference to IPv6 address to be removed. 305 * 306 * @retval kErrorNone Successfully removed the address. 307 * @retval kErrorNotFound Address was not found in the list. 308 * @retval kErrorInvalidArgs Address is invalid (it is the Unspecified Address). 309 * 310 */ 311 Error RemoveIp6Address(const Ip6::Address &aAddress); 312 313 /** 314 * Indicates whether an IPv6 address is in the list of IPv6 addresses of the child. 315 * 316 * @param[in] aAddress A reference to IPv6 address. 317 * 318 * @retval TRUE The address exists on the list. 319 * @retval FALSE Address was not found in the list. 320 * 321 */ 322 bool HasIp6Address(const Ip6::Address &aAddress) const; 323 324 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE 325 /** 326 * Retrieves the Domain Unicast Address registered by the child. 327 * 328 * @returns A pointer to Domain Unicast Address registered by the child if there is. 329 * 330 */ 331 const Ip6::Address *GetDomainUnicastAddress(void) const; 332 #endif 333 334 /** 335 * Gets the child timeout. 336 * 337 * @returns The child timeout. 338 * 339 */ GetTimeout(void) const340 uint32_t GetTimeout(void) const { return mTimeout; } 341 342 /** 343 * Sets the child timeout. 344 * 345 * @param[in] aTimeout The child timeout. 346 * 347 */ SetTimeout(uint32_t aTimeout)348 void SetTimeout(uint32_t aTimeout) { mTimeout = aTimeout; } 349 350 /** 351 * Gets the network data version. 352 * 353 * @returns The network data version. 354 * 355 */ GetNetworkDataVersion(void) const356 uint8_t GetNetworkDataVersion(void) const { return mNetworkDataVersion; } 357 358 /** 359 * Sets the network data version. 360 * 361 * @param[in] aVersion The network data version. 362 * 363 */ SetNetworkDataVersion(uint8_t aVersion)364 void SetNetworkDataVersion(uint8_t aVersion) { mNetworkDataVersion = aVersion; } 365 366 /** 367 * Generates a new challenge value to use during a child attach. 368 * 369 */ GenerateChallenge(void)370 void GenerateChallenge(void) { mAttachChallenge.GenerateRandom(); } 371 372 /** 373 * Gets the current challenge value used during attach. 374 * 375 * @returns The current challenge value. 376 * 377 */ GetChallenge(void) const378 const Mle::TxChallenge &GetChallenge(void) const { return mAttachChallenge; } 379 380 /** 381 * Clears the requested TLV list. 382 * 383 */ ClearRequestTlvs(void)384 void ClearRequestTlvs(void) { memset(mRequestTlvs, Mle::Tlv::kInvalid, sizeof(mRequestTlvs)); } 385 386 /** 387 * Returns the requested TLV at index @p aIndex. 388 * 389 * @param[in] aIndex The index into the requested TLV list. 390 * 391 * @returns The requested TLV at index @p aIndex. 392 * 393 */ GetRequestTlv(uint8_t aIndex) const394 uint8_t GetRequestTlv(uint8_t aIndex) const { return mRequestTlvs[aIndex]; } 395 396 /** 397 * Sets the requested TLV at index @p aIndex. 398 * 399 * @param[in] aIndex The index into the requested TLV list. 400 * @param[in] aType The TLV type. 401 * 402 */ SetRequestTlv(uint8_t aIndex,uint8_t aType)403 void SetRequestTlv(uint8_t aIndex, uint8_t aType) { mRequestTlvs[aIndex] = aType; } 404 405 /** 406 * Returns the supervision interval (in seconds). 407 * 408 * @returns The supervision interval (in seconds). 409 * 410 */ GetSupervisionInterval(void) const411 uint16_t GetSupervisionInterval(void) const { return mSupervisionInterval; } 412 413 /** 414 * Sets the supervision interval. 415 * 416 * @param[in] aInterval The supervision interval (in seconds). 417 * 418 */ SetSupervisionInterval(uint16_t aInterval)419 void SetSupervisionInterval(uint16_t aInterval) { mSupervisionInterval = aInterval; } 420 421 /** 422 * Increments the number of seconds since last supervision of the child. 423 * 424 */ IncrementSecondsSinceLastSupervision(void)425 void IncrementSecondsSinceLastSupervision(void) { mSecondsSinceSupervision++; } 426 427 /** 428 * Returns the number of seconds since last supervision of the child (last message to the child) 429 * 430 * @returns Number of seconds since last supervision of the child. 431 * 432 */ GetSecondsSinceLastSupervision(void) const433 uint16_t GetSecondsSinceLastSupervision(void) const { return mSecondsSinceSupervision; } 434 435 /** 436 * Resets the number of seconds since last supervision of the child to zero. 437 * 438 */ ResetSecondsSinceLastSupervision(void)439 void ResetSecondsSinceLastSupervision(void) { mSecondsSinceSupervision = 0; } 440 441 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE 442 /** 443 * Returns MLR state of an IPv6 multicast address. 444 * 445 * @note The @p aAddress reference MUST be from `IterateIp6Addresses()` or `AddressIterator`. 446 * 447 * @param[in] aAddress The IPv6 multicast address. 448 * 449 * @returns MLR state of the IPv6 multicast address. 450 * 451 */ 452 MlrState GetAddressMlrState(const Ip6::Address &aAddress) const; 453 454 /** 455 * Sets MLR state of an IPv6 multicast address. 456 * 457 * @note The @p aAddress reference MUST be from `IterateIp6Addresses()` or `AddressIterator`. 458 * 459 * @param[in] aAddress The IPv6 multicast address. 460 * @param[in] aState The target MLR state. 461 * 462 */ 463 void SetAddressMlrState(const Ip6::Address &aAddress, MlrState aState); 464 465 /** 466 * Returns if the Child has IPv6 address @p aAddress of MLR state `kMlrStateRegistered`. 467 * 468 * @param[in] aAddress The IPv6 address. 469 * 470 * @retval true If the Child has IPv6 address @p aAddress of MLR state `kMlrStateRegistered`. 471 * @retval false If the Child does not have IPv6 address @p aAddress of MLR state `kMlrStateRegistered`. 472 * 473 */ 474 bool HasMlrRegisteredAddress(const Ip6::Address &aAddress) const; 475 476 /** 477 * Returns if the Child has any IPv6 address of MLR state `kMlrStateRegistered`. 478 * 479 * @retval true If the Child has any IPv6 address of MLR state `kMlrStateRegistered`. 480 * @retval false If the Child does not have any IPv6 address of MLR state `kMlrStateRegistered`. 481 * 482 */ HasAnyMlrRegisteredAddress(void) const483 bool HasAnyMlrRegisteredAddress(void) const { return mMlrRegisteredMask.HasAny(); } 484 485 /** 486 * Returns if the Child has any IPv6 address of MLR state `kMlrStateToRegister`. 487 * 488 * @retval true If the Child has any IPv6 address of MLR state `kMlrStateToRegister`. 489 * @retval false If the Child does not have any IPv6 address of MLR state `kMlrStateToRegister`. 490 * 491 */ HasAnyMlrToRegisterAddress(void) const492 bool HasAnyMlrToRegisterAddress(void) const { return mMlrToRegisterMask.HasAny(); } 493 #endif // OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE 494 495 private: 496 #if OPENTHREAD_CONFIG_MLE_IP_ADDRS_PER_CHILD < 2 497 #error OPENTHREAD_CONFIG_MLE_IP_ADDRS_PER_CHILD should be at least set to 2. 498 #endif 499 500 static constexpr uint16_t kNumIp6Addresses = OPENTHREAD_CONFIG_MLE_IP_ADDRS_PER_CHILD - 1; 501 502 typedef BitVector<kNumIp6Addresses> ChildIp6AddressMask; 503 504 class AddressIteratorBuilder 505 { 506 public: AddressIteratorBuilder(const Child & aChild,Ip6::Address::TypeFilter aFilter)507 AddressIteratorBuilder(const Child &aChild, Ip6::Address::TypeFilter aFilter) 508 : mChild(aChild) 509 , mFilter(aFilter) 510 { 511 } 512 begin(void)513 AddressIterator begin(void) { return AddressIterator(mChild, mFilter); } end(void)514 AddressIterator end(void) { return AddressIterator(mChild, AddressIterator::kEndIterator); } 515 516 private: 517 const Child &mChild; 518 Ip6::Address::TypeFilter mFilter; 519 }; 520 521 Ip6::InterfaceIdentifier mMeshLocalIid; ///< IPv6 address IID for mesh-local address 522 Ip6::Address mIp6Address[kNumIp6Addresses]; ///< Registered IPv6 addresses 523 uint32_t mTimeout; ///< Child timeout 524 525 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE 526 ChildIp6AddressMask mMlrToRegisterMask; 527 ChildIp6AddressMask mMlrRegisteredMask; 528 #endif 529 530 uint8_t mNetworkDataVersion; ///< Current Network Data version 531 532 union 533 { 534 uint8_t mRequestTlvs[kMaxRequestTlvs]; ///< Requested MLE TLVs 535 Mle::TxChallenge mAttachChallenge; ///< The challenge value 536 }; 537 538 uint16_t mSupervisionInterval; // Supervision interval for the child (in sec). 539 uint16_t mSecondsSinceSupervision; // Number of seconds since last supervision of the child. 540 541 static_assert(OPENTHREAD_CONFIG_NUM_MESSAGE_BUFFERS < 8192, "mQueuedMessageCount cannot fit max required!"); 542 }; 543 544 DefineCoreType(otChildInfo, Child::Info); 545 546 #endif // OPENTHREAD_FTD 547 548 } // namespace ot 549 550 #endif // CHILD_HPP_ 551