• 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/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