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 indicates whether or not the Thread Network Data contains a given on mesh prefix entry. 271 * 272 * @param[in] aPrefix The on mesh prefix config to check. 273 * 274 * @retval TRUE if Network Data contains an on mesh prefix matching @p aPrefix. 275 * @retval FALSE if Network Data does not contain an on mesh prefix matching @p aPrefix. 276 * 277 */ 278 bool ContainsOnMeshPrefix(const OnMeshPrefixConfig &aPrefix) const; 279 280 /** 281 * This method indicates whether or not the Thread Network Data contains a given external route entry. 282 * 283 * @param[in] aRoute The external route config to check. 284 * 285 * @retval TRUE if Network Data contains an external route matching @p aRoute. 286 * @retval FALSE if Network Data does not contain an external route matching @p aRoute. 287 * 288 */ 289 bool ContainsExternalRoute(const ExternalRouteConfig &aRoute) const; 290 291 /** 292 * This method indicates whether or not the Thread Network Data contains a given service entry. 293 * 294 * @param[in] aService The service config to check. 295 * 296 * @retval TRUE if Network Data contains a service matching @p aService. 297 * @retval FALSE if Network Data does not contain a service matching @p aService. 298 * 299 */ 300 bool ContainsService(const ServiceConfig &aService) const; 301 302 /** 303 * This method indicates whether or not the Thread Network Data contains all the on mesh prefixes, external 304 * routes, and service entries as in another given Network Data associated with a given RLOC16. 305 * 306 * @param[in] aCompare The Network Data to compare with. 307 * @param[in] aRloc16 The RLOC16 to consider. 308 * 309 * @retval TRUE if Network Data contains all the same entries as in @p aCompare for @p aRloc16. 310 * @retval FALSE if Network Data does not contains all the same entries as in @p aCompare for @p aRloc16. 311 * 312 */ 313 bool ContainsEntriesFrom(const NetworkData &aCompare, uint16_t aRloc16) const; 314 315 /** 316 * This method provides the next server RLOC16 in the Thread Network Data. 317 * 318 * @param[in,out] aIterator A reference to the Network Data iterator. 319 * @param[out] aRloc16 The RLOC16 value. 320 * 321 * @retval kErrorNone Successfully found the next server. 322 * @retval kErrorNotFound No subsequent server exists in the Thread Network Data. 323 * 324 */ 325 Error GetNextServer(Iterator &aIterator, uint16_t &aRloc16) const; 326 327 /** 328 * This method finds and returns the list of RLOCs of border routers providing external IP connectivity. 329 * 330 * A border router is considered to provide external IP connectivity if it has added at least one external route 331 * entry, or an on-mesh prefix with default-route and on-mesh flags set. 332 * 333 * This method should be used when the RLOC16s are present in the Network Data (when the Network Data contains the 334 * full set and not the stable subset). 335 * 336 * @param[in] aRoleFilter Indicates which devices to include (any role, router role only, or child only). 337 * @param[out] aRlocs Array to output the list of RLOCs. 338 * @param[in,out] aRlocsLength On entry, @p aRlocs array length (max number of elements). 339 * On exit, number RLOC16 entries added in @p aRlocs. 340 * 341 * @retval kErrorNone Successfully found all RLOC16s and updated @p aRlocs and @p aRlocsLength. 342 * @retval kErrorNoBufs Ran out of space in @p aRlocs array. @p aRlocs and @p aRlocsLength are still updated up 343 * to the maximum array length. 344 * 345 */ 346 Error FindBorderRouters(RoleFilter aRoleFilter, uint16_t aRlocs[], uint8_t &aRlocsLength) const; 347 348 /** 349 * This method counts the number of border routers providing external IP connectivity. 350 * 351 * A border router is considered to provide external IP connectivity if at least one of the below conditions hold 352 * 353 * - It has added at least one external route entry. 354 * - It has added at least one prefix entry with default-route and on-mesh flags set. 355 * - It has added at least one domain prefix (domain and on-mesh flags set). 356 * 357 * This method should be used when the RLOC16s are present in the Network Data (when the Network Data contains the 358 * full set and not the stable subset). 359 * 360 * @param[in] aRoleFilter Indicates which RLOCs to include (any role, router only, or child only). 361 * 362 * @returns The number of border routers in Thread Network Data matching @p aRoleFilter. 363 * 364 */ 365 uint8_t CountBorderRouters(RoleFilter aRoleFilter) const; 366 367 /** 368 * This method indicates whether the network data contains a border providing external IP connectivity with a given 369 * RLOC16. 370 * 371 * A border router is considered to provide external IP connectivity if at least one of the below conditions hold 372 * 373 * - It has added at least one external route entry. 374 * - It has added at least one prefix entry with default-route and on-mesh flags set. 375 * - It has added at least one domain prefix (domain and on-mesh flags set). 376 * 377 * This method should be used when the RLOC16s are present in the Network Data (when the Network Data contains the 378 * full set and not the stable subset). 379 * 380 * @param[in] aRloc16 The RLOC16 to check. 381 * 382 * @returns TRUE If the network data contains a border router with @p aRloc16 providing IP connectivity. 383 * @returns FALSE If the network data does not contain a border router with @p aRloc16 providing IP connectivity. 384 * 385 */ 386 bool ContainsBorderRouterWithRloc(uint16_t aRloc16) const; 387 388 protected: 389 /** 390 * This enumeration defines Service Data match mode. 391 * 392 */ 393 enum ServiceMatchMode : uint8_t 394 { 395 kServicePrefixMatch, ///< Match the Service Data by prefix. 396 kServiceExactMatch, ///< Match the full Service Data exactly. 397 }; 398 399 /** 400 * This method returns a pointer to the start of Network Data TLV sequence. 401 * 402 * @returns A pointer to the start of Network Data TLV sequence. 403 * 404 */ GetTlvsStart(void) const405 const NetworkDataTlv *GetTlvsStart(void) const { return reinterpret_cast<const NetworkDataTlv *>(mTlvs); } 406 407 /** 408 * This method returns a pointer to the end of Network Data TLV sequence. 409 * 410 * @returns A pointer to the end of Network Data TLV sequence. 411 * 412 */ GetTlvsEnd(void) const413 const NetworkDataTlv *GetTlvsEnd(void) const { return reinterpret_cast<const NetworkDataTlv *>(mTlvs + mLength); } 414 415 /** 416 * This method returns a pointer to a Prefix TLV. 417 * 418 * @param[in] aPrefix A pointer to an IPv6 prefix. 419 * @param[in] aPrefixLength The prefix length pointed to by @p aPrefix (in bits). 420 * 421 * @returns A pointer to the Prefix TLV if one is found or `nullptr` if no matching Prefix TLV exists. 422 * 423 */ 424 const PrefixTlv *FindPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength) const; 425 426 /** 427 * This method returns a pointer to a Prefix TLV. 428 * 429 * @param[in] aPrefix An IPv6 prefix. 430 * 431 * @returns A pointer to the Prefix TLV if one is found or `nullptr` if no matching Prefix TLV exists. 432 * 433 */ FindPrefix(const Ip6::Prefix & aPrefix) const434 const PrefixTlv *FindPrefix(const Ip6::Prefix &aPrefix) const 435 { 436 return FindPrefix(aPrefix.GetBytes(), aPrefix.GetLength()); 437 } 438 439 /** 440 * This method returns a pointer to a matching Service TLV. 441 * 442 * @param[in] aEnterpriseNumber Enterprise Number. 443 * @param[in] aServiceData A Service Data. 444 * @param[in] aServiceMatchMode The Service Data match mode. 445 * 446 * @returns A pointer to the Service TLV if one is found or `nullptr` if no matching Service TLV exists. 447 * 448 */ 449 const ServiceTlv *FindService(uint32_t aEnterpriseNumber, 450 const ServiceData &aServiceData, 451 ServiceMatchMode aServiceMatchMode) const; 452 453 /** 454 * This method returns the next pointer to a matching Service TLV. 455 * 456 * This method can be used to iterate over all 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] aEnterpriseNumber Enterprise Number. 462 * @param[in] aServiceData A Service Data to match with Service TLVs. 463 * @param[in] aServiceMatchMode The Service Data match mode. 464 * 465 * @returns A pointer to the next matching Service TLV if one is found or `nullptr` if it cannot be found. 466 * 467 */ 468 const ServiceTlv *FindNextService(const ServiceTlv * aPrevServiceTlv, 469 uint32_t aEnterpriseNumber, 470 const ServiceData &aServiceData, 471 ServiceMatchMode aServiceMatchMode) const; 472 473 /** 474 * This method returns the next pointer to a matching Thread Service TLV (with Thread Enterprise number). 475 * 476 * This method can be used to iterate over all Thread Service TLVs that start with a given Service Data. 477 * 478 * @param[in] aPrevServiceTlv Set to `nullptr` to start from the beginning of the TLVs (finding the first 479 * matching Service TLV), or a pointer to the previous Service TLV returned from 480 * this method to iterate to the next matching Service TLV. 481 * @param[in] aServiceData A Service Data to match with Service TLVs. 482 * @param[in] aServiceMatchMode The Service Data match mode. 483 * 484 * @returns A pointer to the next matching Thread Service TLV if one is found or `nullptr` if it cannot be found. 485 * 486 */ 487 const ServiceTlv *FindNextThreadService(const ServiceTlv * aPrevServiceTlv, 488 const ServiceData &aServiceData, 489 ServiceMatchMode aServiceMatchMode) const; 490 491 /** 492 * This method sends a Server Data Notification message to the Leader. 493 * 494 * @param[in] aRloc16 The old RLOC16 value that was previously registered. 495 * @param[in] aAppendNetDataTlv Indicates whether or not to append Thread Network Data TLV to the message. 496 * @param[in] aHandler A function pointer that is called when the transaction ends. 497 * @param[in] aContext A pointer to arbitrary context information. 498 * 499 * @retval kErrorNone Successfully enqueued the notification message. 500 * @retval kErrorNoBufs Insufficient message buffers to generate the notification message. 501 * 502 */ 503 Error SendServerDataNotification(uint16_t aRloc16, 504 bool aAppendNetDataTlv, 505 Coap::ResponseHandler aHandler, 506 void * aContext) const; 507 508 private: 509 class NetworkDataIterator 510 { 511 public: NetworkDataIterator(Iterator & aIterator)512 explicit NetworkDataIterator(Iterator &aIterator) 513 : mIteratorBuffer(reinterpret_cast<uint8_t *>(&aIterator)) 514 { 515 } 516 GetTlv(const uint8_t * aTlvs) const517 const NetworkDataTlv *GetTlv(const uint8_t *aTlvs) const 518 { 519 return reinterpret_cast<const NetworkDataTlv *>(aTlvs + GetTlvOffset()); 520 } 521 AdvanceTlv(const uint8_t * aTlvs)522 void AdvanceTlv(const uint8_t *aTlvs) 523 { 524 SaveTlvOffset(GetTlv(aTlvs)->GetNext(), aTlvs); 525 SetSubTlvOffset(0); 526 SetEntryIndex(0); 527 } 528 GetSubTlv(const NetworkDataTlv * aSubTlvs) const529 const NetworkDataTlv *GetSubTlv(const NetworkDataTlv *aSubTlvs) const 530 { 531 return reinterpret_cast<const NetworkDataTlv *>(reinterpret_cast<const uint8_t *>(aSubTlvs) + 532 GetSubTlvOffset()); 533 } 534 AdvaceSubTlv(const NetworkDataTlv * aSubTlvs)535 void AdvaceSubTlv(const NetworkDataTlv *aSubTlvs) 536 { 537 SaveSubTlvOffset(GetSubTlv(aSubTlvs)->GetNext(), aSubTlvs); 538 SetEntryIndex(0); 539 } 540 GetAndAdvanceIndex(void)541 uint8_t GetAndAdvanceIndex(void) { return mIteratorBuffer[kEntryPosition]++; } 542 IsNewEntry(void) const543 bool IsNewEntry(void) const { return GetEntryIndex() == 0; } MarkEntryAsNotNew(void)544 void MarkEntryAsNotNew(void) { SetEntryIndex(1); } 545 546 private: 547 static constexpr uint8_t kTlvPosition = 0; 548 static constexpr uint8_t kSubTlvPosition = 1; 549 static constexpr uint8_t kEntryPosition = 2; 550 GetTlvOffset(void) const551 uint8_t GetTlvOffset(void) const { return mIteratorBuffer[kTlvPosition]; } GetSubTlvOffset(void) const552 uint8_t GetSubTlvOffset(void) const { return mIteratorBuffer[kSubTlvPosition]; } SetSubTlvOffset(uint8_t aOffset)553 void SetSubTlvOffset(uint8_t aOffset) { mIteratorBuffer[kSubTlvPosition] = aOffset; } SetTlvOffset(uint8_t aOffset)554 void SetTlvOffset(uint8_t aOffset) { mIteratorBuffer[kTlvPosition] = aOffset; } GetEntryIndex(void) const555 uint8_t GetEntryIndex(void) const { return mIteratorBuffer[kEntryPosition]; } SetEntryIndex(uint8_t aIndex)556 void SetEntryIndex(uint8_t aIndex) { mIteratorBuffer[kEntryPosition] = aIndex; } 557 SaveTlvOffset(const NetworkDataTlv * aTlv,const uint8_t * aTlvs)558 void SaveTlvOffset(const NetworkDataTlv *aTlv, const uint8_t *aTlvs) 559 { 560 SetTlvOffset(static_cast<uint8_t>(reinterpret_cast<const uint8_t *>(aTlv) - aTlvs)); 561 } 562 SaveSubTlvOffset(const NetworkDataTlv * aSubTlv,const NetworkDataTlv * aSubTlvs)563 void SaveSubTlvOffset(const NetworkDataTlv *aSubTlv, const NetworkDataTlv *aSubTlvs) 564 { 565 SetSubTlvOffset(static_cast<uint8_t>(reinterpret_cast<const uint8_t *>(aSubTlv) - 566 reinterpret_cast<const uint8_t *>(aSubTlvs))); 567 } 568 569 uint8_t *mIteratorBuffer; 570 }; 571 572 struct Config 573 { 574 OnMeshPrefixConfig * mOnMeshPrefix; 575 ExternalRouteConfig *mExternalRoute; 576 ServiceConfig * mService; 577 }; 578 579 Error Iterate(Iterator &aIterator, uint16_t aRloc16, Config &aConfig) const; 580 581 static bool MatchService(const ServiceTlv & aServiceTlv, 582 uint32_t aEnterpriseNumber, 583 const ServiceData &aServiceData, 584 ServiceMatchMode aServiceMatchMode); 585 586 const uint8_t *mTlvs; 587 uint8_t mLength; 588 }; 589 590 /** 591 * This class represents mutable Network Data. 592 * 593 */ 594 class MutableNetworkData : public NetworkData 595 { 596 friend class NetworkData; 597 friend class Service::Manager; 598 friend class Publisher; 599 600 public: 601 /** 602 * This constructor initializes the `MutableNetworkData` 603 * 604 * @param[in] aInstance A reference to the OpenThread instance. 605 * @param[in] aTlvs A pointer to the buffer to store the TLVs. 606 * @param[in] aLength The current length of the Network Data. 607 * @param[in] aSize Size of the buffer @p aTlvs (maximum length). 608 * 609 */ MutableNetworkData(Instance & aInstance,uint8_t * aTlvs,uint8_t aLength,uint8_t aSize)610 MutableNetworkData(Instance &aInstance, uint8_t *aTlvs, uint8_t aLength, uint8_t aSize) 611 : NetworkData(aInstance, aTlvs, aLength) 612 , mSize(aSize) 613 { 614 } 615 616 using NetworkData::GetBytes; 617 using NetworkData::GetLength; 618 619 /** 620 * This method returns the size of the buffer to store the mutable Network Data. 621 * 622 * @returns The size of the buffer. 623 * 624 */ GetSize(void) const625 uint8_t GetSize(void) const { return mSize; } 626 627 /** 628 * This method returns a pointer to start of the TLVs in `NetworkData`. 629 * 630 * @returns A pointer to start of the TLVs. 631 * 632 */ GetBytes(void)633 uint8_t *GetBytes(void) { return AsNonConst(AsConst(this)->GetBytes()); } 634 635 /** 636 * This method clears the network data. 637 * 638 */ Clear(void)639 void Clear(void) { mLength = 0; } 640 641 protected: 642 /** 643 * This method sets the Network Data length. 644 * 645 * @param[in] aLength The length. 646 * 647 */ SetLength(uint8_t aLength)648 void SetLength(uint8_t aLength) { mLength = aLength; } 649 650 using NetworkData::GetTlvsStart; 651 652 /** 653 * This method returns a pointer to the start of Network Data TLV sequence. 654 * 655 * @returns A pointer to the start of Network Data TLV sequence. 656 * 657 */ GetTlvsStart(void)658 NetworkDataTlv *GetTlvsStart(void) { return AsNonConst(AsConst(this)->GetTlvsStart()); } 659 660 using NetworkData::GetTlvsEnd; 661 662 /** 663 * This method returns a pointer to the end of Network Data TLV sequence. 664 * 665 * @returns A pointer to the end of Network Data TLV sequence. 666 * 667 */ GetTlvsEnd(void)668 NetworkDataTlv *GetTlvsEnd(void) { return AsNonConst(AsConst(this)->GetTlvsEnd()); } 669 670 using NetworkData::FindPrefix; 671 672 /** 673 * This method returns a pointer to a Prefix TLV. 674 * 675 * @param[in] aPrefix A pointer to an IPv6 prefix. 676 * @param[in] aPrefixLength The prefix length pointed to by @p aPrefix (in bits). 677 * 678 * @returns A pointer to the Prefix TLV if one is found or `nullptr` if no matching Prefix TLV exists. 679 * 680 */ FindPrefix(const uint8_t * aPrefix,uint8_t aPrefixLength)681 PrefixTlv *FindPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength) 682 { 683 return AsNonConst(AsConst(this)->FindPrefix(aPrefix, aPrefixLength)); 684 } 685 686 /** 687 * This method returns a pointer to a Prefix TLV. 688 * 689 * @param[in] aPrefix An IPv6 prefix. 690 * 691 * @returns A pointer to the Prefix TLV if one is found or `nullptr` if no matching Prefix TLV exists. 692 * 693 */ FindPrefix(const Ip6::Prefix & aPrefix)694 PrefixTlv *FindPrefix(const Ip6::Prefix &aPrefix) { return FindPrefix(aPrefix.GetBytes(), aPrefix.GetLength()); } 695 696 using NetworkData::FindService; 697 698 /** 699 * This method returns a pointer to a matching Service TLV. 700 * 701 * @param[in] aEnterpriseNumber Enterprise Number. 702 * @param[in] aServiceData A Service Data. 703 * @param[in] aServiceMatchMode The Service Data match mode. 704 * 705 * @returns A pointer to the Service TLV if one is found or `nullptr` if no matching Service TLV exists. 706 * 707 */ FindService(uint32_t aEnterpriseNumber,const ServiceData & aServiceData,ServiceMatchMode aServiceMatchMode)708 ServiceTlv *FindService(uint32_t aEnterpriseNumber, 709 const ServiceData &aServiceData, 710 ServiceMatchMode aServiceMatchMode) 711 { 712 return AsNonConst(AsConst(this)->FindService(aEnterpriseNumber, aServiceData, aServiceMatchMode)); 713 } 714 715 /** 716 * This method indicates whether there is space in Network Data to insert/append new info and grow it by a given 717 * number of bytes. 718 * 719 * @param[in] aSize The number of bytes to grow the Network Data. 720 * 721 * @retval TRUE There is space to grow Network Data by @p aSize bytes. 722 * @retval FALSE There is no space left to grow Network Data by @p aSize bytes. 723 * 724 */ CanInsert(uint16_t aSize) const725 bool CanInsert(uint16_t aSize) const { return (mLength + aSize <= mSize); } 726 727 /** 728 * This method grows the Network Data to append a TLV with a requested size. 729 * 730 * On success, the returned TLV is not initialized (i.e., the TLV Length field is not set) but the requested 731 * size for it (@p aTlvSize number of bytes) is reserved in the Network Data. 732 * 733 * @param[in] aTlvSize The size of TLV (total number of bytes including Type, Length, and Value fields) 734 * 735 * @returns A pointer to the TLV if there is space to grow Network Data, or `nullptr` if no space to grow the 736 * Network Data with requested @p aTlvSize number of bytes. 737 * 738 */ 739 NetworkDataTlv *AppendTlv(uint16_t aTlvSize); 740 741 /** 742 * This method inserts bytes into the Network Data. 743 * 744 * @param[in] aStart A pointer to the beginning of the insertion. 745 * @param[in] aLength The number of bytes to insert. 746 * 747 */ 748 void Insert(void *aStart, uint8_t aLength); 749 750 /** 751 * This method removes bytes from the Network Data. 752 * 753 * @param[in] aRemoveStart A pointer to the beginning of the removal. 754 * @param[in] aRemoveLength The number of bytes to remove. 755 * 756 */ 757 void Remove(void *aRemoveStart, uint8_t aRemoveLength); 758 759 /** 760 * This method removes a TLV from the Network Data. 761 * 762 * @param[in] aTlv The TLV to remove. 763 * 764 */ 765 void RemoveTlv(NetworkDataTlv *aTlv); 766 767 /** 768 * This method strips non-stable data from the Thread Network Data. 769 * 770 */ 771 void RemoveTemporaryData(void); 772 773 private: 774 void RemoveTemporaryDataIn(PrefixTlv &aPrefix); 775 void RemoveTemporaryDataIn(ServiceTlv &aService); 776 777 uint8_t mSize; 778 }; 779 780 } // namespace NetworkData 781 782 /** 783 * @} 784 */ 785 786 } // namespace ot 787 788 #endif // NETWORK_DATA_HPP_ 789