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