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/equatable.hpp"
45 #include "common/locator.hpp"
46 #include "common/timer.hpp"
47 #include "net/udp6.hpp"
48 #include "thread/lowpan.hpp"
49 #include "thread/mle_router.hpp"
50 #include "thread/network_data_tlvs.hpp"
51 #include "thread/network_data_types.hpp"
52 
53 namespace ot {
54 
55 /**
56  * @addtogroup core-netdata
57  * @brief
58  *   This module includes definitions for generating, processing, and managing Thread Network Data.
59  *
60  * @{
61  *
62  * @defgroup core-netdata-core Core
63  * @defgroup core-netdata-leader Leader
64  * @defgroup core-netdata-local Local
65  * @defgroup core-netdata-tlvs TLVs
66  *
67  * @}
68  *
69  */
70 
71 /**
72  * @namespace ot::NetworkData
73  *
74  * @brief
75  *   This namespace includes definitions for managing Thread Network Data.
76  *
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 
94 /**
95  * This type represents a Iterator used to iterate through Network Data info (e.g., see `GetNextOnMeshPrefix()`)
96  *
97  */
98 typedef otNetworkDataIterator Iterator;
99 
100 constexpr Iterator kIteratorInit = OT_NETWORK_DATA_ITERATOR_INIT; ///< Initializer for `Iterator` type.
101 
102 /**
103  * This class implements Network Data processing.
104  *
105  */
106 class NetworkData : public InstanceLocator
107 {
108     friend class Service::Manager;
109     friend class Publisher;
110 
111 public:
112     static constexpr uint8_t kMaxSize = 254; ///< Maximum size of Thread Network Data in bytes.
113 
114     /**
115      * This enumeration specifies the type of Network Data (local or leader).
116      *
117      */
118     enum Type : uint8_t
119     {
120         kTypeLocal,  ///< Local Network Data.
121         kTypeLeader, ///< Leader Network Data.
122     };
123 
124     /**
125      * This constructor initializes the object.
126      *
127      * @param[in]  aInstance     A reference to the OpenThread instance.
128      * @param[in]  aType         Network data type
129      *
130      */
131     NetworkData(Instance &aInstance, Type aType);
132 
133     /**
134      * This method clears the network data.
135      *
136      */
Clear(void)137     void Clear(void) { mLength = 0; }
138 
139     /**
140      * This method provides a full or stable copy of the Thread Network Data.
141      *
142      * @param[in]     aStable      TRUE when copying the stable version, FALSE when copying the full version.
143      * @param[out]    aData        A pointer to the data buffer.
144      * @param[inout]  aDataLength  On entry, size of the data buffer pointed to by @p aData.
145      *                             On exit, number of copied bytes.
146      *
147      * @retval kErrorNone       Successfully copied full Thread Network Data.
148      * @retval kErrorNoBufs     Not enough space to fully copy Thread Network Data.
149      *
150      */
151     Error GetNetworkData(bool aStable, uint8_t *aData, uint8_t &aDataLength) const;
152 
153     /**
154      * This method provides the next On Mesh prefix in the Thread Network Data.
155      *
156      * @param[inout]  aIterator  A reference to the Network Data iterator.
157      * @param[out]    aConfig    A reference to a config variable where the On Mesh Prefix information will be placed.
158      *
159      * @retval kErrorNone       Successfully found the next On Mesh prefix.
160      * @retval kErrorNotFound   No subsequent On Mesh prefix exists in the Thread Network Data.
161      *
162      */
163     Error GetNextOnMeshPrefix(Iterator &aIterator, OnMeshPrefixConfig &aConfig) const;
164 
165     /**
166      * This method provides the next On Mesh prefix in the Thread Network Data for a given RLOC16.
167      *
168      * @param[inout]  aIterator  A reference to the Network Data iterator.
169      * @param[in]     aRloc16    The RLOC16 value.
170      * @param[out]    aConfig    A reference to a config variable where the On Mesh Prefix information will be placed.
171      *
172      * @retval kErrorNone       Successfully found the next On Mesh prefix.
173      * @retval kErrorNotFound   No subsequent On Mesh prefix exists in the Thread Network Data.
174      *
175      */
176     Error GetNextOnMeshPrefix(Iterator &aIterator, uint16_t aRloc16, OnMeshPrefixConfig &aConfig) const;
177 
178     /**
179      * This method provides the next external route in the Thread Network Data.
180      *
181      * @param[inout]  aIterator  A reference to the Network Data iterator.
182      * @param[out]    aConfig    A reference to a config variable where the external route information will be placed.
183      *
184      * @retval kErrorNone       Successfully found the next external route.
185      * @retval kErrorNotFound   No subsequent external route exists in the Thread Network Data.
186      *
187      */
188     Error GetNextExternalRoute(Iterator &aIterator, ExternalRouteConfig &aConfig) const;
189 
190     /**
191      * This method provides the next external route in the Thread Network Data for a given RLOC16.
192      *
193      * @param[inout]  aIterator  A reference to the Network Data iterator.
194      * @param[in]     aRloc16    The RLOC16 value.
195      * @param[out]    aConfig    A reference to a config variable where the external route information will be placed.
196      *
197      * @retval kErrorNone       Successfully found the next external route.
198      * @retval kErrorNotFound   No subsequent external route exists in the Thread Network Data.
199      *
200      */
201     Error GetNextExternalRoute(Iterator &aIterator, uint16_t aRloc16, ExternalRouteConfig &aConfig) const;
202 
203     /**
204      * This method provides the next service in the Thread Network Data.
205      *
206      * @param[inout]  aIterator  A reference to the Network Data iterator.
207      * @param[out]    aConfig    A reference to a config variable where the service information will be placed.
208      *
209      * @retval kErrorNone       Successfully found the next service.
210      * @retval kErrorNotFound   No subsequent service exists in the Thread Network Data.
211      *
212      */
213     Error GetNextService(Iterator &aIterator, ServiceConfig &aConfig) const;
214 
215     /**
216      * This method provides the next service in the Thread Network Data for a given RLOC16.
217      *
218      * @param[inout]  aIterator  A reference to the Network Data iterator.
219      * @param[in]     aRloc16    The RLOC16 value.
220      * @param[out]    aConfig    A reference to a config variable where the service information will be placed.
221      *
222      * @retval kErrorNone       Successfully found the next service.
223      * @retval kErrorNotFound   No subsequent service exists in the Thread Network Data.
224      *
225      */
226     Error GetNextService(Iterator &aIterator, uint16_t aRloc16, ServiceConfig &aConfig) const;
227 
228     /**
229      * This method provides the next Service ID in the Thread Network Data for a given RLOC16.
230      *
231      * @param[inout]  aIterator  A reference to the Network Data iterator.
232      * @param[in]     aRloc16    The RLOC16 value.
233      * @param[out]    aServiceId A reference to variable where the Service ID will be placed.
234      *
235      * @retval kErrorNone       Successfully found the next service.
236      * @retval kErrorNotFound   No subsequent service exists in the Thread Network Data.
237      *
238      */
239     Error GetNextServiceId(Iterator &aIterator, uint16_t aRloc16, uint8_t &aServiceId) const;
240 
241     /**
242      * This method indicates whether or not the Thread Network Data contains all of the on mesh prefix information
243      * in @p aCompare associated with @p aRloc16.
244      *
245      * @param[in]  aCompare  The Network Data to use for the query.
246      * @param[in]  aRloc16   The RLOC16 to consider.
247      *
248      * @returns TRUE if this object contains all on mesh prefix information in @p aCompare associated with @p aRloc16,
249      *          FALSE otherwise.
250      *
251      */
252     bool ContainsOnMeshPrefixes(const NetworkData &aCompare, uint16_t aRloc16) const;
253 
254     /**
255      * This method indicates whether or not the Thread Network Data contains all of the external route information
256      * in @p aCompare associated with @p aRloc16.
257      *
258      * @param[in]  aCompare  The Network Data to use for the query.
259      * @param[in]  aRloc16   The RLOC16 to consider.
260      *
261      * @returns TRUE if this object contains all external route information in @p aCompare associated with @p aRloc16,
262      *          FALSE otherwise.
263      *
264      */
265     bool ContainsExternalRoutes(const NetworkData &aCompare, uint16_t aRloc16) const;
266 
267     /**
268      * This method indicates whether or not the Thread Network Data contains all of the service information
269      * in @p aCompare associated with @p aRloc16.
270      *
271      * @param[in]  aCompare  The Network Data to use for the query.
272      * @param[in]  aRloc16   The RLOC16 to consider.
273      *
274      * @returns TRUE if this object contains all service information in @p aCompare associated with @p aRloc16,
275      *          FALSE otherwise.
276      *
277      */
278     bool ContainsServices(const NetworkData &aCompare, uint16_t aRloc16) const;
279 
280     /**
281      * This method indicates whether or not the Thread Network Data contains the service with given Service ID
282      * associated with @p aRloc16.
283      *
284      * @param[in]  aServiceId The Service ID to search for.
285      * @param[in]  aRloc16    The RLOC16 to consider.
286      *
287      * @returns TRUE if this object contains the service with given ID associated with @p aRloc16,
288      *          FALSE otherwise.
289      *
290      */
291     bool ContainsService(uint8_t aServiceId, uint16_t aRloc16) const;
292 
293     /**
294      * This method provides the next server RLOC16 in the Thread Network Data.
295      *
296      * @param[inout]  aIterator  A reference to the Network Data iterator.
297      * @param[out]    aRloc16    The RLOC16 value.
298      *
299      * @retval kErrorNone       Successfully found the next server.
300      * @retval kErrorNotFound   No subsequent server exists in the Thread Network Data.
301      *
302      */
303     Error GetNextServer(Iterator &aIterator, uint16_t &aRloc16) const;
304 
305 protected:
306     /**
307      * This enumeration defines Service Data match mode.
308      *
309      */
310     enum ServiceMatchMode : uint8_t
311     {
312         kServicePrefixMatch, ///< Match the Service Data by prefix.
313         kServiceExactMatch,  ///< Match the full Service Data exactly.
314     };
315 
316     /**
317      * This method returns a pointer to the start of Network Data TLV sequence.
318      *
319      * @returns A pointer to the start of Network Data TLV sequence.
320      *
321      */
GetTlvsStart(void)322     NetworkDataTlv *GetTlvsStart(void) { return reinterpret_cast<NetworkDataTlv *>(mTlvs); }
323 
324     /**
325      * This method returns a pointer to the start of Network Data TLV sequence.
326      *
327      * @returns A pointer to the start of Network Data TLV sequence.
328      *
329      */
GetTlvsStart(void) const330     const NetworkDataTlv *GetTlvsStart(void) const { return reinterpret_cast<const NetworkDataTlv *>(mTlvs); }
331 
332     /**
333      * This method returns a pointer to the end of Network Data TLV sequence.
334      *
335      * @returns A pointer to the end of Network Data TLV sequence.
336      *
337      */
GetTlvsEnd(void)338     NetworkDataTlv *GetTlvsEnd(void) { return reinterpret_cast<NetworkDataTlv *>(mTlvs + mLength); }
339 
340     /**
341      * This method returns a pointer to the end of Network Data TLV sequence.
342      *
343      * @returns A pointer to the end of Network Data TLV sequence.
344      *
345      */
GetTlvsEnd(void) const346     const NetworkDataTlv *GetTlvsEnd(void) const { return reinterpret_cast<const NetworkDataTlv *>(mTlvs + mLength); }
347 
348     /**
349      * This method returns a pointer to a Prefix TLV.
350      *
351      * @param[in]  aPrefix        A pointer to an IPv6 prefix.
352      * @param[in]  aPrefixLength  The prefix length pointed to by @p aPrefix (in bits).
353      *
354      * @returns A pointer to the Prefix TLV if one is found or nullptr if no matching Prefix TLV exists.
355      *
356      */
FindPrefix(const uint8_t * aPrefix,uint8_t aPrefixLength)357     PrefixTlv *FindPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength)
358     {
359         return const_cast<PrefixTlv *>(const_cast<const NetworkData *>(this)->FindPrefix(aPrefix, aPrefixLength));
360     }
361 
362     /**
363      * This method returns a pointer to a Prefix TLV.
364      *
365      * @param[in]  aPrefix        A pointer to an IPv6 prefix.
366      * @param[in]  aPrefixLength  The prefix length pointed to by @p aPrefix (in bits).
367      *
368      * @returns A pointer to the Prefix TLV if one is found or nullptr if no matching Prefix TLV exists.
369      *
370      */
371     const PrefixTlv *FindPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength) const;
372 
373     /**
374      * This method returns a pointer to a Prefix TLV.
375      *
376      * @param[in]  aPrefix        An IPv6 prefix.
377      *
378      * @returns A pointer to the Prefix TLV if one is found or nullptr if no matching Prefix TLV exists.
379      *
380      */
FindPrefix(const Ip6::Prefix & aPrefix)381     PrefixTlv *FindPrefix(const Ip6::Prefix &aPrefix) { return FindPrefix(aPrefix.GetBytes(), aPrefix.GetLength()); }
382 
383     /**
384      * This method returns a pointer to a Prefix TLV.
385      *
386      * @param[in]  aPrefix        An IPv6 prefix.
387      *
388      * @returns A pointer to the Prefix TLV if one is found or nullptr if no matching Prefix TLV exists.
389      *
390      */
FindPrefix(const Ip6::Prefix & aPrefix) const391     const PrefixTlv *FindPrefix(const Ip6::Prefix &aPrefix) const
392     {
393         return FindPrefix(aPrefix.GetBytes(), aPrefix.GetLength());
394     }
395 
396     /**
397      * This method returns a pointer to a Prefix TLV in a specified tlvs buffer.
398      *
399      * @param[in]  aPrefix        A pointer to an IPv6 prefix.
400      * @param[in]  aPrefixLength  The prefix length pointed to by @p aPrefix (in bits).
401      * @param[in]  aTlvs          A pointer to a specified tlvs buffer.
402      * @param[in]  aTlvsLength    The specified tlvs buffer length pointed to by @p aTlvs.
403      *
404      * @returns A pointer to the Prefix TLV if one is found or nullptr if no matching Prefix TLV exists.
405      *
406      */
FindPrefix(const uint8_t * aPrefix,uint8_t aPrefixLength,uint8_t * aTlvs,uint8_t aTlvsLength)407     static PrefixTlv *FindPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength, uint8_t *aTlvs, uint8_t aTlvsLength)
408     {
409         return const_cast<PrefixTlv *>(
410             FindPrefix(aPrefix, aPrefixLength, const_cast<const uint8_t *>(aTlvs), aTlvsLength));
411     }
412 
413     /**
414      * This method returns a pointer to a Prefix TLV in a specified tlvs buffer.
415      *
416      * @param[in]  aPrefix        A pointer to an IPv6 prefix.
417      * @param[in]  aPrefixLength  The prefix length pointed to by @p aPrefix (in bits).
418      * @param[in]  aTlvs          A pointer to a specified tlvs buffer.
419      * @param[in]  aTlvsLength    The specified tlvs buffer length pointed to by @p aTlvs.
420      *
421      * @returns A pointer to the Prefix TLV if one is found or nullptr if no matching Prefix TLV exists.
422      *
423      */
424     static const PrefixTlv *FindPrefix(const uint8_t *aPrefix,
425                                        uint8_t        aPrefixLength,
426                                        const uint8_t *aTlvs,
427                                        uint8_t        aTlvsLength);
428 
429     /**
430      * This method returns a pointer to a matching Service TLV.
431      *
432      * @param[in]  aEnterpriseNumber  Enterprise Number.
433      * @param[in]  aServiceData       A pointer to a Service Data.
434      * @param[in]  aServiceDataLength The Service Data length pointed to by @p aServiceData.
435      * @param[in]  aServiceMatchMode  The Service Data match mode.
436      *
437      * @returns A pointer to the Service TLV if one is found or nullptr if no matching Service TLV exists.
438      *
439      */
FindService(uint32_t aEnterpriseNumber,const uint8_t * aServiceData,uint8_t aServiceDataLength,ServiceMatchMode aServiceMatchMode)440     ServiceTlv *FindService(uint32_t         aEnterpriseNumber,
441                             const uint8_t *  aServiceData,
442                             uint8_t          aServiceDataLength,
443                             ServiceMatchMode aServiceMatchMode)
444     {
445         return const_cast<ServiceTlv *>(const_cast<const NetworkData *>(this)->FindService(
446             aEnterpriseNumber, aServiceData, aServiceDataLength, aServiceMatchMode));
447     }
448 
449     /**
450      * This method returns a pointer to a matching Service TLV.
451      *
452      * @param[in]  aEnterpriseNumber  Enterprise Number.
453      * @param[in]  aServiceData       A pointer to a Service Data.
454      * @param[in]  aServiceDataLength The Service Data length pointed to by @p aServiceData.
455      * @param[in]  aServiceMatchMode  The Service Data match mode.
456      *
457      * @returns A pointer to the Service TLV if one is found or nullptr if no matching Service TLV exists.
458      *
459      */
460     const ServiceTlv *FindService(uint32_t         aEnterpriseNumber,
461                                   const uint8_t *  aServiceData,
462                                   uint8_t          aServiceDataLength,
463                                   ServiceMatchMode aServiceMatchMode) const;
464 
465     /**
466      * This method returns a pointer to a Service TLV in a specified tlvs buffer.
467      *
468      * @param[in]  aEnterpriseNumber  Enterprise Number.
469      * @param[in]  aServiceData       A pointer to a Service Data.
470      * @param[in]  aServiceDataLength The Service Data length pointed to by @p aServiceData.
471      * @param[in]  aServiceMatchMode  The Service Data match mode.
472      * @param[in]  aTlvs              A pointer to a specified tlvs buffer.
473      * @param[in]  aTlvsLength        The specified tlvs buffer length pointed to by @p aTlvs.
474      *
475      * @returns A pointer to the Service TLV if one is found or nullptr if no matching Service TLV exists.
476      *
477      */
FindService(uint32_t aEnterpriseNumber,const uint8_t * aServiceData,uint8_t aServiceDataLength,ServiceMatchMode aServiceMatchMode,uint8_t * aTlvs,uint8_t aTlvsLength)478     static ServiceTlv *FindService(uint32_t         aEnterpriseNumber,
479                                    const uint8_t *  aServiceData,
480                                    uint8_t          aServiceDataLength,
481                                    ServiceMatchMode aServiceMatchMode,
482                                    uint8_t *        aTlvs,
483                                    uint8_t          aTlvsLength)
484     {
485         return const_cast<ServiceTlv *>(FindService(aEnterpriseNumber, aServiceData, aServiceDataLength,
486                                                     aServiceMatchMode, const_cast<const uint8_t *>(aTlvs),
487                                                     aTlvsLength));
488     }
489 
490     /**
491      * This method returns a pointer to a Service TLV in a specified tlvs buffer.
492      *
493      * @param[in]  aEnterpriseNumber  Enterprise Number.
494      * @param[in]  aServiceData       A pointer to a Service Data.
495      * @param[in]  aServiceDataLength The Service Data length pointed to by @p aServiceData.
496      * @param[in]  aServiceMatchMode  The Service Data match mode.
497      * @param[in]  aTlvs              A pointer to a specified tlvs buffer.
498      * @param[in]  aTlvsLength        The specified tlvs buffer length pointed to by @p aTlvs.
499      *
500      * @returns A pointer to the Service TLV if one is found or nullptr if no matching Service TLV exists.
501      *
502      */
503     static const ServiceTlv *FindService(uint32_t         aEnterpriseNumber,
504                                          const uint8_t *  aServiceData,
505                                          uint8_t          aServiceDataLength,
506                                          ServiceMatchMode aServiceMatchMode,
507                                          const uint8_t *  aTlvs,
508                                          uint8_t          aTlvsLength);
509 
510     /**
511      * This method returns the next pointer to a matching Service TLV.
512      *
513      * This method can be used to iterate over all Service TLVs that start with a given Service Data.
514      *
515      * @param[in]  aPrevServiceTlv    Set to nullptr to start from the beginning of the TLVs (finding the first matching
516      *                                Service TLV), or a pointer to the previous Service TLV returned from this method
517      *                                to iterate to the next matching Service TLV.
518      * @param[in]  aEnterpriseNumber  Enterprise Number.
519      * @param[in]  aServiceData       A pointer to a Service Data to match with Service TLVs.
520      * @param[in]  aServiceDataLength The Service Data length pointed to by @p aServiceData.
521      * @param[in]  aServiceMatchMode  The Service Data match mode.
522      *
523      * @returns A pointer to the next matching Service TLV if one is found or nullptr if it cannot be found.
524      *
525      */
526     const ServiceTlv *FindNextService(const ServiceTlv *aPrevServiceTlv,
527                                       uint32_t          aEnterpriseNumber,
528                                       const uint8_t *   aServiceData,
529                                       uint8_t           aServiceDataLength,
530                                       ServiceMatchMode  aServiceMatchMode) const;
531 
532     /**
533      * This method indicates whether there is space in Network Data to insert/append new info and grow it by a given
534      * number of bytes.
535      *
536      * @param[in]  aSize  The number of bytes to grow the Network Data.
537      *
538      * @retval TRUE   There is space to grow Network Data by @p aSize bytes.
539      * @retval FALSE  There is no space left to grow Network Data by @p aSize bytes.
540      *
541      */
CanInsert(uint16_t aSize) const542     bool CanInsert(uint16_t aSize) const { return (mLength + aSize <= kMaxSize); }
543 
544     /**
545      * This method grows the Network Data to append a TLV with a requested size.
546      *
547      * On success, the returned TLV is not initialized (i.e., the TLV Length field is not set) but the requested
548      * size for it (@p aTlvSize number of bytes) is reserved in the Network Data.
549      *
550      * @param[in]  aTlvSize  The size of TLV (total number of bytes including Type, Length, and Value fields)
551      *
552      * @returns A pointer to the TLV if there is space to grow Network Data, or nullptr if no space to grow the Network
553      *          Data with requested @p aTlvSize number of bytes.
554      *
555      */
556     NetworkDataTlv *AppendTlv(uint16_t aTlvSize);
557 
558     /**
559      * This method inserts bytes into the Network Data.
560      *
561      * @param[in]  aStart   A pointer to the beginning of the insertion.
562      * @param[in]  aLength  The number of bytes to insert.
563      *
564      */
565     void Insert(void *aStart, uint8_t aLength);
566 
567     /**
568      * This method removes bytes from the Network Data.
569      *
570      * @param[in]  aRemoveStart   A pointer to the beginning of the removal.
571      * @param[in]  aRemoveLength  The number of bytes to remove.
572      *
573      */
574     void Remove(void *aRemoveStart, uint8_t aRemoveLength);
575 
576     /**
577      * This method removes a TLV from the Network Data.
578      *
579      * @param[in]  aTlv   The TLV to remove.
580      *
581      */
582     void RemoveTlv(NetworkDataTlv *aTlv);
583 
584     /**
585      * This method strips non-stable data from the Thread Network Data.
586      *
587      * @param[inout]  aData        A pointer to the Network Data to modify.
588      * @param[inout]  aDataLength  On entry, the size of the Network Data in bytes.  On exit, the size of the
589      *                             resulting Network Data in bytes.
590      *
591      */
592     static void RemoveTemporaryData(uint8_t *aData, uint8_t &aDataLength);
593 
594     /**
595      * This method sends a Server Data Notification message to the Leader.
596      *
597      * @param[in]  aRloc16   The old RLOC16 value that was previously registered.
598      * @param[in]  aHandler  A function pointer that is called when the transaction ends.
599      * @param[in]  aContext  A pointer to arbitrary context information.
600      *
601      * @retval kErrorNone     Successfully enqueued the notification message.
602      * @retval kErrorNoBufs   Insufficient message buffers to generate the notification message.
603      *
604      */
605     Error SendServerDataNotification(uint16_t aRloc16, Coap::ResponseHandler aHandler, void *aContext);
606 
607     uint8_t mTlvs[kMaxSize]; ///< The Network Data buffer.
608     uint8_t mLength;         ///< The number of valid bytes in @var mTlvs.
609 
610 private:
611     class NetworkDataIterator
612     {
613     public:
NetworkDataIterator(Iterator & aIterator)614         explicit NetworkDataIterator(Iterator &aIterator)
615             : mIteratorBuffer(reinterpret_cast<uint8_t *>(&aIterator))
616         {
617         }
618 
GetTlv(const uint8_t * aTlvs) const619         const NetworkDataTlv *GetTlv(const uint8_t *aTlvs) const
620         {
621             return reinterpret_cast<const NetworkDataTlv *>(aTlvs + GetTlvOffset());
622         }
623 
AdvanceTlv(const uint8_t * aTlvs)624         void AdvanceTlv(const uint8_t *aTlvs)
625         {
626             SaveTlvOffset(GetTlv(aTlvs)->GetNext(), aTlvs);
627             SetSubTlvOffset(0);
628             SetEntryIndex(0);
629         }
630 
GetSubTlv(const NetworkDataTlv * aSubTlvs) const631         const NetworkDataTlv *GetSubTlv(const NetworkDataTlv *aSubTlvs) const
632         {
633             return reinterpret_cast<const NetworkDataTlv *>(reinterpret_cast<const uint8_t *>(aSubTlvs) +
634                                                             GetSubTlvOffset());
635         }
636 
AdvaceSubTlv(const NetworkDataTlv * aSubTlvs)637         void AdvaceSubTlv(const NetworkDataTlv *aSubTlvs)
638         {
639             SaveSubTlvOffset(GetSubTlv(aSubTlvs)->GetNext(), aSubTlvs);
640             SetEntryIndex(0);
641         }
642 
GetAndAdvanceIndex(void)643         uint8_t GetAndAdvanceIndex(void) { return mIteratorBuffer[kEntryPosition]++; }
644 
IsNewEntry(void) const645         bool IsNewEntry(void) const { return GetEntryIndex() == 0; }
MarkEntryAsNotNew(void)646         void MarkEntryAsNotNew(void) { SetEntryIndex(1); }
647 
648     private:
649         static constexpr uint8_t kTlvPosition    = 0;
650         static constexpr uint8_t kSubTlvPosition = 1;
651         static constexpr uint8_t kEntryPosition  = 2;
652 
GetTlvOffset(void) const653         uint8_t GetTlvOffset(void) const { return mIteratorBuffer[kTlvPosition]; }
GetSubTlvOffset(void) const654         uint8_t GetSubTlvOffset(void) const { return mIteratorBuffer[kSubTlvPosition]; }
SetSubTlvOffset(uint8_t aOffset)655         void    SetSubTlvOffset(uint8_t aOffset) { mIteratorBuffer[kSubTlvPosition] = aOffset; }
SetTlvOffset(uint8_t aOffset)656         void    SetTlvOffset(uint8_t aOffset) { mIteratorBuffer[kTlvPosition] = aOffset; }
GetEntryIndex(void) const657         uint8_t GetEntryIndex(void) const { return mIteratorBuffer[kEntryPosition]; }
SetEntryIndex(uint8_t aIndex)658         void    SetEntryIndex(uint8_t aIndex) { mIteratorBuffer[kEntryPosition] = aIndex; }
659 
SaveTlvOffset(const NetworkDataTlv * aTlv,const uint8_t * aTlvs)660         void SaveTlvOffset(const NetworkDataTlv *aTlv, const uint8_t *aTlvs)
661         {
662             SetTlvOffset(static_cast<uint8_t>(reinterpret_cast<const uint8_t *>(aTlv) - aTlvs));
663         }
664 
SaveSubTlvOffset(const NetworkDataTlv * aSubTlv,const NetworkDataTlv * aSubTlvs)665         void SaveSubTlvOffset(const NetworkDataTlv *aSubTlv, const NetworkDataTlv *aSubTlvs)
666         {
667             SetSubTlvOffset(static_cast<uint8_t>(reinterpret_cast<const uint8_t *>(aSubTlv) -
668                                                  reinterpret_cast<const uint8_t *>(aSubTlvs)));
669         }
670 
671         uint8_t *mIteratorBuffer;
672     };
673 
674     struct Config
675     {
676         OnMeshPrefixConfig * mOnMeshPrefix;
677         ExternalRouteConfig *mExternalRoute;
678         ServiceConfig *      mService;
679     };
680 
681     Error Iterate(Iterator &aIterator, uint16_t aRloc16, Config &aConfig) const;
682 
683     static void RemoveTemporaryData(uint8_t *aData, uint8_t &aDataLength, PrefixTlv &aPrefix);
684     static void RemoveTemporaryData(uint8_t *aData, uint8_t &aDataLength, ServiceTlv &aService);
685 
686     static void Remove(uint8_t *aData, uint8_t &aDataLength, uint8_t *aRemoveStart, uint8_t aRemoveLength);
687     static void RemoveTlv(uint8_t *aData, uint8_t &aDataLength, NetworkDataTlv *aTlv);
688 
689     static bool MatchService(const ServiceTlv &aServiceTlv,
690                              uint32_t          aEnterpriseNumber,
691                              const uint8_t *   aServiceData,
692                              uint8_t           aServiceDataLength,
693                              ServiceMatchMode  aServiceMatchMode);
694 
695     const Type mType;
696 };
697 
698 } // namespace NetworkData
699 
700 /**
701  * @}
702  */
703 
704 } // namespace ot
705 
706 #endif // NETWORK_DATA_HPP_
707