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 managing Thread Network Data. 32 */ 33 34 #ifndef NETWORK_DATA_HPP_ 35 #define NETWORK_DATA_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #include <openthread/border_router.h> 40 #include <openthread/netdata.h> 41 #include <openthread/server.h> 42 43 #include "coap/coap.hpp" 44 #include "common/clearable.hpp" 45 #include "common/const_cast.hpp" 46 #include "common/equatable.hpp" 47 #include "common/locator.hpp" 48 #include "common/timer.hpp" 49 #include "net/udp6.hpp" 50 #include "thread/lowpan.hpp" 51 #include "thread/mle_router.hpp" 52 #include "thread/network_data_tlvs.hpp" 53 #include "thread/network_data_types.hpp" 54 55 namespace ot { 56 57 /** 58 * @addtogroup core-netdata 59 * @brief 60 * This module includes definitions for generating, processing, and managing Thread Network Data. 61 * 62 * @{ 63 * 64 * @defgroup core-netdata-core Core 65 * @defgroup core-netdata-leader Leader 66 * @defgroup core-netdata-local Local 67 * @defgroup core-netdata-tlvs TLVs 68 * 69 * @} 70 */ 71 72 /** 73 * @namespace ot::NetworkData 74 * 75 * @brief 76 * This namespace includes definitions for managing Thread Network Data. 77 */ 78 namespace NetworkData { 79 80 namespace Service { 81 class Manager; 82 } 83 84 /** 85 * @addtogroup core-netdata-core 86 * 87 * @brief 88 * This module includes definitions for managing Thread Network Data. 89 * 90 * @{ 91 */ 92 93 class Leader; 94 class Publisher; 95 class MutableNetworkData; 96 97 /** 98 * Represents a Iterator used to iterate through Network Data info (e.g., see `GetNextOnMeshPrefix()`) 99 */ 100 typedef otNetworkDataIterator Iterator; 101 102 constexpr Iterator kIteratorInit = OT_NETWORK_DATA_ITERATOR_INIT; ///< Initializer for `Iterator` type. 103 104 /** 105 * Represents an immutable Network Data. 106 */ 107 class NetworkData : public InstanceLocator 108 { 109 friend class Leader; 110 friend class Publisher; 111 friend class MutableNetworkData; 112 friend class Service::Manager; 113 114 public: 115 static constexpr uint8_t kMaxSize = 254; ///< Maximum size of Thread Network Data in bytes. 116 117 /** 118 * Initializes the `NetworkData` from a given pointer to a buffer and length. 119 * 120 * @param[in] aInstance A reference to the OpenThread instance. 121 * @param[in] aTlvs A pointer to the buffer containing the TLVs. 122 * @param[in] aLength The length (number of bytes) of @p aTlvs buffer. 123 */ NetworkData(Instance & aInstance,const uint8_t * aTlvs=nullptr,uint8_t aLength=0)124 explicit NetworkData(Instance &aInstance, const uint8_t *aTlvs = nullptr, uint8_t aLength = 0) 125 : InstanceLocator(aInstance) 126 , mTlvs(aTlvs) 127 , mLength(aLength) 128 { 129 } 130 131 /** 132 * Initializes the `NetworkData` from a range of TLVs (given as pair of start and end pointers). 133 * 134 * @param[in] aInstance A reference to the OpenThread instance. 135 * @param[in] aStartTlv A pointer to the start of the TLVs buffer. 136 * @param[in] aEndTlv A pointer to the end of the TLVs buffer. 137 */ NetworkData(Instance & aInstance,const NetworkDataTlv * aStartTlv,const NetworkDataTlv * aEndTlv)138 NetworkData(Instance &aInstance, const NetworkDataTlv *aStartTlv, const NetworkDataTlv *aEndTlv) 139 : InstanceLocator(aInstance) 140 , mTlvs(reinterpret_cast<const uint8_t *>(aStartTlv)) 141 , mLength(static_cast<uint8_t>(reinterpret_cast<const uint8_t *>(aEndTlv) - 142 reinterpret_cast<const uint8_t *>(aStartTlv))) 143 { 144 } 145 146 /** 147 * Returns the length of `NetworkData` (number of bytes). 148 * 149 * @returns The length of `NetworkData` (number of bytes). 150 */ GetLength(void) const151 uint8_t GetLength(void) const { return mLength; } 152 153 /** 154 * Returns a pointer to the start of the TLVs in `NetworkData`. 155 * 156 * @returns A pointer to the start of the TLVs. 157 */ GetBytes(void) const158 const uint8_t *GetBytes(void) const { return mTlvs; } 159 160 /** 161 * Provides full or stable copy of the Thread Network Data. 162 * 163 * @param[in] aType The Network Data type to copy, the full set or stable subset. 164 * @param[out] aData A pointer to the data buffer to copy the Network Data into. 165 * @param[in,out] aDataLength On entry, size of the data buffer pointed to by @p aData. 166 * On exit, number of copied bytes. 167 * 168 * @retval kErrorNone Successfully copied Thread Network Data. 169 * @retval kErrorNoBufs Not enough space in @p aData to fully copy Thread Network Data. 170 */ 171 Error CopyNetworkData(Type aType, uint8_t *aData, uint8_t &aDataLength) const; 172 173 /** 174 * Provides full or stable copy of the Thread Network Data. 175 * 176 * @param[in] aType The Network Data type to copy, the full set or stable subset. 177 * @param[out] aNetworkData A reference to a `MutableNetworkData` to copy the Network Data into. 178 * 179 * @retval kErrorNone Successfully copied Thread Network Data. 180 * @retval kErrorNoBufs Not enough space in @p aNetworkData to fully copy Thread Network Data. 181 */ 182 Error CopyNetworkData(Type aType, MutableNetworkData &aNetworkData) const; 183 184 /** 185 * Provides the next On Mesh prefix in the Thread Network Data. 186 * 187 * @param[in,out] aIterator A reference to the Network Data iterator. 188 * @param[out] aConfig A reference to a config variable where the On Mesh Prefix information will be placed. 189 * 190 * @retval kErrorNone Successfully found the next On Mesh prefix. 191 * @retval kErrorNotFound No subsequent On Mesh prefix exists in the Thread Network Data. 192 */ 193 Error GetNextOnMeshPrefix(Iterator &aIterator, OnMeshPrefixConfig &aConfig) const; 194 195 /** 196 * Provides the next On Mesh prefix in the Thread Network Data for a given RLOC16. 197 * 198 * @param[in,out] aIterator A reference to the Network Data iterator. 199 * @param[in] aRloc16 The RLOC16 value. 200 * @param[out] aConfig A reference to a config variable where the On Mesh Prefix information will be placed. 201 * 202 * @retval kErrorNone Successfully found the next On Mesh prefix. 203 * @retval kErrorNotFound No subsequent On Mesh prefix exists in the Thread Network Data. 204 */ 205 Error GetNextOnMeshPrefix(Iterator &aIterator, uint16_t aRloc16, OnMeshPrefixConfig &aConfig) const; 206 207 /** 208 * Provides the next external route in the Thread Network Data. 209 * 210 * @param[in,out] aIterator A reference to the Network Data iterator. 211 * @param[out] aConfig A reference to a config variable where the external route information will be placed. 212 * 213 * @retval kErrorNone Successfully found the next external route. 214 * @retval kErrorNotFound No subsequent external route exists in the Thread Network Data. 215 */ 216 Error GetNextExternalRoute(Iterator &aIterator, ExternalRouteConfig &aConfig) const; 217 218 /** 219 * Provides the next external route in the Thread Network Data for a given RLOC16. 220 * 221 * @param[in,out] aIterator A reference to the Network Data iterator. 222 * @param[in] aRloc16 The RLOC16 value. 223 * @param[out] aConfig A reference to a config variable where the external route information will be placed. 224 * 225 * @retval kErrorNone Successfully found the next external route. 226 * @retval kErrorNotFound No subsequent external route exists in the Thread Network Data. 227 */ 228 Error GetNextExternalRoute(Iterator &aIterator, uint16_t aRloc16, ExternalRouteConfig &aConfig) const; 229 230 /** 231 * Provides the next service in the Thread Network Data. 232 * 233 * @param[in,out] aIterator A reference to the Network Data iterator. 234 * @param[out] aConfig A reference to a config variable where the service information will be placed. 235 * 236 * @retval kErrorNone Successfully found the next service. 237 * @retval kErrorNotFound No subsequent service exists in the Thread Network Data. 238 */ 239 Error GetNextService(Iterator &aIterator, ServiceConfig &aConfig) const; 240 241 /** 242 * Provides the next service in the Thread Network Data for a given RLOC16. 243 * 244 * @param[in,out] aIterator A reference to the Network Data iterator. 245 * @param[in] aRloc16 The RLOC16 value. 246 * @param[out] aConfig A reference to a config variable where the service information will be placed. 247 * 248 * @retval kErrorNone Successfully found the next service. 249 * @retval kErrorNotFound No subsequent service exists in the Thread Network Data. 250 */ 251 Error GetNextService(Iterator &aIterator, uint16_t aRloc16, ServiceConfig &aConfig) const; 252 253 /** 254 * Gets the next 6LoWPAN Context ID info in the Thread Network Data. 255 * 256 * @param[in,out] aIterator A reference to the Network Data iterator. 257 * @param[out] aContextInfo A reference to where the retrieved 6LoWPAN Context ID information will be placed. 258 * 259 * @retval kErrorNone Successfully found the next 6LoWPAN Context ID info. 260 * @retval kErrorNotFound No subsequent 6LoWPAN Context info exists in the partition's Network Data. 261 */ 262 Error GetNextLowpanContextInfo(Iterator &aIterator, LowpanContextInfo &aContextInfo) const; 263 264 /** 265 * Indicates whether or not the Thread Network Data contains a given on mesh prefix entry. 266 * 267 * @param[in] aPrefix The on mesh prefix config to check. 268 * 269 * @retval TRUE if Network Data contains an on mesh prefix matching @p aPrefix. 270 * @retval FALSE if Network Data does not contain an on mesh prefix matching @p aPrefix. 271 */ 272 bool ContainsOnMeshPrefix(const OnMeshPrefixConfig &aPrefix) const; 273 274 /** 275 * Indicates whether or not the Thread Network Data contains a given external route entry. 276 * 277 * @param[in] aRoute The external route config to check. 278 * 279 * @retval TRUE if Network Data contains an external route matching @p aRoute. 280 * @retval FALSE if Network Data does not contain an external route matching @p aRoute. 281 */ 282 bool ContainsExternalRoute(const ExternalRouteConfig &aRoute) const; 283 284 /** 285 * Indicates whether or not the Thread Network Data contains a given service entry. 286 * 287 * @param[in] aService The service config to check. 288 * 289 * @retval TRUE if Network Data contains a service matching @p aService. 290 * @retval FALSE if Network Data does not contain a service matching @p aService. 291 */ 292 bool ContainsService(const ServiceConfig &aService) const; 293 294 /** 295 * Indicates whether or not the Thread Network Data contains all the on mesh prefixes, external 296 * routes, and service entries as in another given Network Data associated with a given RLOC16. 297 * 298 * @param[in] aCompare The Network Data to compare with. 299 * @param[in] aRloc16 The RLOC16 to consider. 300 * 301 * @retval TRUE if Network Data contains all the same entries as in @p aCompare for @p aRloc16. 302 * @retval FALSE if Network Data does not contains all the same entries as in @p aCompare for @p aRloc16. 303 */ 304 bool ContainsEntriesFrom(const NetworkData &aCompare, uint16_t aRloc16) const; 305 306 /** 307 * Finds and returns Domain ID associated with a given prefix in the Thread Network data. 308 * 309 * @param[in] aPrefix The prefix to search for. 310 * @param[out] aDomainId A reference to return the Domain ID. 311 * 312 * @retval kErrorNone Successfully found @p aPrefix in the Network Data and updated @p aDomainId. 313 * @retval kErrorNotFound Could not find @p aPrefix in the Network Data. 314 */ 315 Error FindDomainIdFor(const Ip6::Prefix &aPrefix, uint8_t &aDomainId) const; 316 317 /** 318 * Finds border routers and servers in the Network Data matching specified filters, returning their RLOC16s. 319 * 320 * @p aBrFilter can be used to filter the type of BRs. It can be set to `kAnyBrOrServer` to include all BRs and 321 * servers. `kBrProvidingExternalIpConn` restricts it to BRs providing external IP connectivity where at least one 322 * the below conditions hold: 323 * 324 * - It has added at least one external route entry. 325 * - It has added at least one prefix entry with default-route and on-mesh flags set. 326 * - It has added at least one domain prefix (domain and on-mesh flags set). 327 * 328 * Should be used when the RLOC16s are present in the Network Data (when the Network Data contains the 329 * full set and not the stable subset). 330 * 331 * @param[in] aBrFilter Indicates BR filter. 332 * @param[in] aRoleFilter Indicates role filter (any role, router role only, or child only). 333 * @param[out] aRlocs Array to output the list of RLOC16s. 334 */ 335 void FindRlocs(BorderRouterFilter aBrFilter, RoleFilter aRoleFilter, Rlocs &aRlocs) const; 336 337 /** 338 * Counts the number of border routers providing external IP connectivity. 339 * 340 * A border router is considered to provide external IP connectivity if at least one of the below conditions hold: 341 * 342 * - It has added at least one external route entry. 343 * - It has added at least one prefix entry with default-route and on-mesh flags set. 344 * - It has added at least one domain prefix (domain and on-mesh flags set). 345 * 346 * Should be used when the RLOC16s are present in the Network Data (when the Network Data contains the 347 * full set and not the stable subset). 348 * 349 * @param[in] aRoleFilter Indicates which RLOCs to include (any role, router only, or child only). 350 * 351 * @returns The number of border routers in Thread Network Data matching @p aRoleFilter. 352 */ 353 uint8_t CountBorderRouters(RoleFilter aRoleFilter) const; 354 355 /** 356 * Indicates whether the network data contains a border providing external IP connectivity with a given 357 * RLOC16. 358 * 359 * A border router is considered to provide external IP connectivity if at least one of the below conditions hold 360 * 361 * - It has added at least one external route entry. 362 * - It has added at least one prefix entry with default-route and on-mesh flags set. 363 * - It has added at least one domain prefix (domain and on-mesh flags set). 364 * 365 * Should be used when the RLOC16s are present in the Network Data (when the Network Data contains the 366 * full set and not the stable subset). 367 * 368 * @param[in] aRloc16 The RLOC16 to check. 369 * 370 * @returns TRUE If the network data contains a border router with @p aRloc16 providing IP connectivity. 371 * @returns FALSE If the network data does not contain a border router with @p aRloc16 providing IP connectivity. 372 */ 373 bool ContainsBorderRouterWithRloc(uint16_t aRloc16) const; 374 375 protected: 376 /** 377 * Defines Service Data match mode. 378 */ 379 enum ServiceMatchMode : uint8_t 380 { 381 kServicePrefixMatch, ///< Match the Service Data by prefix. 382 kServiceExactMatch, ///< Match the full Service Data exactly. 383 }; 384 385 /** 386 * Returns a pointer to the start of Network Data TLV sequence. 387 * 388 * @returns A pointer to the start of Network Data TLV sequence. 389 */ GetTlvsStart(void) const390 const NetworkDataTlv *GetTlvsStart(void) const { return reinterpret_cast<const NetworkDataTlv *>(mTlvs); } 391 392 /** 393 * Returns a pointer to the end of Network Data TLV sequence. 394 * 395 * @returns A pointer to the end of Network Data TLV sequence. 396 */ GetTlvsEnd(void) const397 const NetworkDataTlv *GetTlvsEnd(void) const { return reinterpret_cast<const NetworkDataTlv *>(mTlvs + mLength); } 398 399 /** 400 * Returns a pointer to a Prefix TLV. 401 * 402 * @param[in] aPrefix A pointer to an IPv6 prefix. 403 * @param[in] aPrefixLength The prefix length pointed to by @p aPrefix (in bits). 404 * 405 * @returns A pointer to the Prefix TLV if one is found or `nullptr` if no matching Prefix TLV exists. 406 */ 407 const PrefixTlv *FindPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength) const; 408 409 /** 410 * Returns a pointer to a Prefix TLV. 411 * 412 * @param[in] aPrefix An IPv6 prefix. 413 * 414 * @returns A pointer to the Prefix TLV if one is found or `nullptr` if no matching Prefix TLV exists. 415 */ FindPrefix(const Ip6::Prefix & aPrefix) const416 const PrefixTlv *FindPrefix(const Ip6::Prefix &aPrefix) const 417 { 418 return FindPrefix(aPrefix.GetBytes(), aPrefix.GetLength()); 419 } 420 421 /** 422 * Returns a pointer to a matching Service TLV. 423 * 424 * @param[in] aEnterpriseNumber Enterprise Number. 425 * @param[in] aServiceData A Service Data. 426 * @param[in] aServiceMatchMode The Service Data match mode. 427 * 428 * @returns A pointer to the Service TLV if one is found or `nullptr` if no matching Service TLV exists. 429 */ 430 const ServiceTlv *FindService(uint32_t aEnterpriseNumber, 431 const ServiceData &aServiceData, 432 ServiceMatchMode aServiceMatchMode) const; 433 434 /** 435 * Returns the next pointer to a matching Service TLV. 436 * 437 * Can be used to iterate over all Service TLVs that start with a given Service Data. 438 * 439 * @param[in] aPrevServiceTlv Set to `nullptr` to start from the beginning of the TLVs (finding the first 440 * matching Service TLV), or a pointer to the previous Service TLV returned from 441 * this method to iterate to the next matching Service TLV. 442 * @param[in] aEnterpriseNumber Enterprise Number. 443 * @param[in] aServiceData A Service Data to match with Service TLVs. 444 * @param[in] aServiceMatchMode The Service Data match mode. 445 * 446 * @returns A pointer to the next matching Service TLV if one is found or `nullptr` if it cannot be found. 447 */ 448 const ServiceTlv *FindNextService(const ServiceTlv *aPrevServiceTlv, 449 uint32_t aEnterpriseNumber, 450 const ServiceData &aServiceData, 451 ServiceMatchMode aServiceMatchMode) const; 452 453 /** 454 * Returns the next pointer to a matching Thread Service TLV (with Thread Enterprise number). 455 * 456 * Can be used to iterate over all Thread Service TLVs that start with a given Service Data. 457 * 458 * @param[in] aPrevServiceTlv Set to `nullptr` to start from the beginning of the TLVs (finding the first 459 * matching Service TLV), or a pointer to the previous Service TLV returned from 460 * this method to iterate to the next matching Service TLV. 461 * @param[in] aServiceData A Service Data to match with Service TLVs. 462 * @param[in] aServiceMatchMode The Service Data match mode. 463 * 464 * @returns A pointer to the next matching Thread Service TLV if one is found or `nullptr` if it cannot be found. 465 */ 466 const ServiceTlv *FindNextThreadService(const ServiceTlv *aPrevServiceTlv, 467 const ServiceData &aServiceData, 468 ServiceMatchMode aServiceMatchMode) const; 469 470 private: 471 class NetworkDataIterator 472 { 473 public: NetworkDataIterator(Iterator & aIterator)474 explicit NetworkDataIterator(Iterator &aIterator) 475 : mIteratorBuffer(reinterpret_cast<uint8_t *>(&aIterator)) 476 { 477 } 478 GetTlv(const uint8_t * aTlvs) const479 const NetworkDataTlv *GetTlv(const uint8_t *aTlvs) const 480 { 481 return reinterpret_cast<const NetworkDataTlv *>(aTlvs + GetTlvOffset()); 482 } 483 AdvanceTlv(const uint8_t * aTlvs)484 void AdvanceTlv(const uint8_t *aTlvs) 485 { 486 SaveTlvOffset(GetTlv(aTlvs)->GetNext(), aTlvs); 487 SetSubTlvOffset(0); 488 SetEntryIndex(0); 489 } 490 GetSubTlv(const NetworkDataTlv * aSubTlvs) const491 const NetworkDataTlv *GetSubTlv(const NetworkDataTlv *aSubTlvs) const 492 { 493 return reinterpret_cast<const NetworkDataTlv *>(reinterpret_cast<const uint8_t *>(aSubTlvs) + 494 GetSubTlvOffset()); 495 } 496 AdvanceSubTlv(const NetworkDataTlv * aSubTlvs)497 void AdvanceSubTlv(const NetworkDataTlv *aSubTlvs) 498 { 499 SaveSubTlvOffset(GetSubTlv(aSubTlvs)->GetNext(), aSubTlvs); 500 SetEntryIndex(0); 501 } 502 GetAndAdvanceIndex(void)503 uint8_t GetAndAdvanceIndex(void) { return mIteratorBuffer[kEntryPosition]++; } 504 IsNewEntry(void) const505 bool IsNewEntry(void) const { return GetEntryIndex() == 0; } MarkEntryAsNotNew(void)506 void MarkEntryAsNotNew(void) { SetEntryIndex(1); } 507 508 private: 509 static constexpr uint8_t kTlvPosition = 0; 510 static constexpr uint8_t kSubTlvPosition = 1; 511 static constexpr uint8_t kEntryPosition = 2; 512 GetTlvOffset(void) const513 uint8_t GetTlvOffset(void) const { return mIteratorBuffer[kTlvPosition]; } GetSubTlvOffset(void) const514 uint8_t GetSubTlvOffset(void) const { return mIteratorBuffer[kSubTlvPosition]; } SetSubTlvOffset(uint8_t aOffset)515 void SetSubTlvOffset(uint8_t aOffset) { mIteratorBuffer[kSubTlvPosition] = aOffset; } SetTlvOffset(uint8_t aOffset)516 void SetTlvOffset(uint8_t aOffset) { mIteratorBuffer[kTlvPosition] = aOffset; } GetEntryIndex(void) const517 uint8_t GetEntryIndex(void) const { return mIteratorBuffer[kEntryPosition]; } SetEntryIndex(uint8_t aIndex)518 void SetEntryIndex(uint8_t aIndex) { mIteratorBuffer[kEntryPosition] = aIndex; } 519 SaveTlvOffset(const NetworkDataTlv * aTlv,const uint8_t * aTlvs)520 void SaveTlvOffset(const NetworkDataTlv *aTlv, const uint8_t *aTlvs) 521 { 522 SetTlvOffset(static_cast<uint8_t>(reinterpret_cast<const uint8_t *>(aTlv) - aTlvs)); 523 } 524 SaveSubTlvOffset(const NetworkDataTlv * aSubTlv,const NetworkDataTlv * aSubTlvs)525 void SaveSubTlvOffset(const NetworkDataTlv *aSubTlv, const NetworkDataTlv *aSubTlvs) 526 { 527 SetSubTlvOffset(static_cast<uint8_t>(reinterpret_cast<const uint8_t *>(aSubTlv) - 528 reinterpret_cast<const uint8_t *>(aSubTlvs))); 529 } 530 531 uint8_t *mIteratorBuffer; 532 }; 533 534 struct Config 535 { 536 OnMeshPrefixConfig *mOnMeshPrefix; 537 ExternalRouteConfig *mExternalRoute; 538 ServiceConfig *mService; 539 LowpanContextInfo *mLowpanContext; 540 }; 541 542 Error Iterate(Iterator &aIterator, uint16_t aRloc16, Config &aConfig) const; 543 544 static bool MatchService(const ServiceTlv &aServiceTlv, 545 uint32_t aEnterpriseNumber, 546 const ServiceData &aServiceData, 547 ServiceMatchMode aServiceMatchMode); 548 549 static void AddRloc16ToRlocs(uint16_t aRloc16, Rlocs &aRlocs, RoleFilter aRoleFilter); 550 551 const uint8_t *mTlvs; 552 uint8_t mLength; 553 }; 554 555 /** 556 * Represents mutable Network Data. 557 */ 558 class MutableNetworkData : public NetworkData 559 { 560 friend class NetworkData; 561 friend class Service::Manager; 562 friend class Publisher; 563 564 public: 565 /** 566 * Initializes the `MutableNetworkData` 567 * 568 * @param[in] aInstance A reference to the OpenThread instance. 569 * @param[in] aTlvs A pointer to the buffer to store the TLVs. 570 * @param[in] aLength The current length of the Network Data. 571 * @param[in] aSize Size of the buffer @p aTlvs (maximum length). 572 */ MutableNetworkData(Instance & aInstance,uint8_t * aTlvs,uint8_t aLength,uint8_t aSize)573 MutableNetworkData(Instance &aInstance, uint8_t *aTlvs, uint8_t aLength, uint8_t aSize) 574 : NetworkData(aInstance, aTlvs, aLength) 575 , mSize(aSize) 576 { 577 } 578 579 using NetworkData::GetBytes; 580 using NetworkData::GetLength; 581 582 /** 583 * Returns the size of the buffer to store the mutable Network Data. 584 * 585 * @returns The size of the buffer. 586 */ GetSize(void) const587 uint8_t GetSize(void) const { return mSize; } 588 589 /** 590 * Returns a pointer to start of the TLVs in `NetworkData`. 591 * 592 * @returns A pointer to start of the TLVs. 593 */ GetBytes(void)594 uint8_t *GetBytes(void) { return AsNonConst(AsConst(this)->GetBytes()); } 595 596 /** 597 * Clears the network data. 598 */ Clear(void)599 void Clear(void) { mLength = 0; } 600 601 protected: 602 /** 603 * Sets the Network Data length. 604 * 605 * @param[in] aLength The length. 606 */ SetLength(uint8_t aLength)607 void SetLength(uint8_t aLength) { mLength = aLength; } 608 609 using NetworkData::GetTlvsStart; 610 611 /** 612 * Returns a pointer to the start of Network Data TLV sequence. 613 * 614 * @returns A pointer to the start of Network Data TLV sequence. 615 */ GetTlvsStart(void)616 NetworkDataTlv *GetTlvsStart(void) { return AsNonConst(AsConst(this)->GetTlvsStart()); } 617 618 using NetworkData::GetTlvsEnd; 619 620 /** 621 * Returns a pointer to the end of Network Data TLV sequence. 622 * 623 * @returns A pointer to the end of Network Data TLV sequence. 624 */ GetTlvsEnd(void)625 NetworkDataTlv *GetTlvsEnd(void) { return AsNonConst(AsConst(this)->GetTlvsEnd()); } 626 627 using NetworkData::FindPrefix; 628 629 /** 630 * Returns a pointer to a Prefix TLV. 631 * 632 * @param[in] aPrefix A pointer to an IPv6 prefix. 633 * @param[in] aPrefixLength The prefix length pointed to by @p aPrefix (in bits). 634 * 635 * @returns A pointer to the Prefix TLV if one is found or `nullptr` if no matching Prefix TLV exists. 636 */ FindPrefix(const uint8_t * aPrefix,uint8_t aPrefixLength)637 PrefixTlv *FindPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength) 638 { 639 return AsNonConst(AsConst(this)->FindPrefix(aPrefix, aPrefixLength)); 640 } 641 642 /** 643 * Returns a pointer to a Prefix TLV. 644 * 645 * @param[in] aPrefix An IPv6 prefix. 646 * 647 * @returns A pointer to the Prefix TLV if one is found or `nullptr` if no matching Prefix TLV exists. 648 */ FindPrefix(const Ip6::Prefix & aPrefix)649 PrefixTlv *FindPrefix(const Ip6::Prefix &aPrefix) { return FindPrefix(aPrefix.GetBytes(), aPrefix.GetLength()); } 650 651 using NetworkData::FindService; 652 653 /** 654 * Returns a pointer to a matching Service TLV. 655 * 656 * @param[in] aEnterpriseNumber Enterprise Number. 657 * @param[in] aServiceData A Service Data. 658 * @param[in] aServiceMatchMode The Service Data match mode. 659 * 660 * @returns A pointer to the Service TLV if one is found or `nullptr` if no matching Service TLV exists. 661 */ FindService(uint32_t aEnterpriseNumber,const ServiceData & aServiceData,ServiceMatchMode aServiceMatchMode)662 ServiceTlv *FindService(uint32_t aEnterpriseNumber, 663 const ServiceData &aServiceData, 664 ServiceMatchMode aServiceMatchMode) 665 { 666 return AsNonConst(AsConst(this)->FindService(aEnterpriseNumber, aServiceData, aServiceMatchMode)); 667 } 668 669 /** 670 * Indicates whether there is space in Network Data to insert/append new info and grow it by a given 671 * number of bytes. 672 * 673 * @param[in] aSize The number of bytes to grow the Network Data. 674 * 675 * @retval TRUE There is space to grow Network Data by @p aSize bytes. 676 * @retval FALSE There is no space left to grow Network Data by @p aSize bytes. 677 */ CanInsert(uint16_t aSize) const678 bool CanInsert(uint16_t aSize) const { return (mLength + aSize <= mSize); } 679 680 /** 681 * Grows the Network Data to append a TLV with a requested size. 682 * 683 * On success, the returned TLV is not initialized (i.e., the TLV Length field is not set) but the requested 684 * size for it (@p aTlvSize number of bytes) is reserved in the Network Data. 685 * 686 * @param[in] aTlvSize The size of TLV (total number of bytes including Type, Length, and Value fields) 687 * 688 * @returns A pointer to the TLV if there is space to grow Network Data, or `nullptr` if no space to grow the 689 * Network Data with requested @p aTlvSize number of bytes. 690 */ 691 NetworkDataTlv *AppendTlv(uint16_t aTlvSize); 692 693 /** 694 * Inserts bytes into the Network Data. 695 * 696 * @param[in] aStart A pointer to the beginning of the insertion. 697 * @param[in] aLength The number of bytes to insert. 698 */ 699 void Insert(void *aStart, uint8_t aLength); 700 701 /** 702 * Removes bytes from the Network Data. 703 * 704 * @param[in] aRemoveStart A pointer to the beginning of the removal. 705 * @param[in] aRemoveLength The number of bytes to remove. 706 */ 707 void Remove(void *aRemoveStart, uint8_t aRemoveLength); 708 709 /** 710 * Removes a TLV from the Network Data. 711 * 712 * @param[in] aTlv The TLV to remove. 713 */ 714 void RemoveTlv(NetworkDataTlv *aTlv); 715 716 /** 717 * Strips non-stable data from the Thread Network Data. 718 */ 719 void RemoveTemporaryData(void); 720 721 private: 722 bool RemoveTemporaryDataIn(PrefixTlv &aPrefix); 723 bool RemoveTemporaryDataIn(ServiceTlv &aService); 724 725 uint8_t mSize; 726 }; 727 728 } // namespace NetworkData 729 730 /** 731 * @} 732 */ 733 734 } // namespace ot 735 736 #endif // NETWORK_DATA_HPP_ 737