• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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