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 manipulating Thread Network Data managed by the Thread Leader.
32  */
33 
34 #ifndef NETWORK_DATA_LEADER_HPP_
35 #define NETWORK_DATA_LEADER_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include <stdint.h>
40 
41 #include "coap/coap.hpp"
42 #include "common/const_cast.hpp"
43 #include "common/non_copyable.hpp"
44 #include "common/numeric_limits.hpp"
45 #include "common/timer.hpp"
46 #include "net/ip6_address.hpp"
47 #include "thread/mle_router.hpp"
48 #include "thread/network_data.hpp"
49 #include "thread/tmf.hpp"
50 
51 namespace ot {
52 
53 namespace NetworkData {
54 
55 /**
56  * @addtogroup core-netdata-leader
57  *
58  * @brief
59  *   This module includes definitions for manipulating Thread Network Data managed by the Thread Leader.
60  *
61  * @{
62  *
63  */
64 
65 /**
66  * Implements the Thread Network Data maintained by the Leader.
67  *
68  */
69 class Leader : public MutableNetworkData, private NonCopyable
70 {
71     friend class Tmf::Agent;
72     friend class Notifier;
73 
74 public:
75     /**
76      * Initializes the object.
77      *
78      * @param[in]  aInstance     A reference to the OpenThread instance.
79      *
80      */
81     explicit Leader(Instance &aInstance);
82 
83     /**
84      * Reset the Thread Network Data.
85      *
86      */
87     void Reset(void);
88 
89     /**
90      * Returns the maximum observed Network Data length since OT stack initialization or since the last
91      * call to `ResetMaxLength()`.
92      *
93      * @returns The maximum observed Network Data length (high water mark for Network Data length).
94      *
95      */
GetMaxLength(void) const96     uint8_t GetMaxLength(void) const { return mMaxLength; }
97 
98     /**
99      * Resets the tracked maximum Network Data Length.
100      *
101      * @sa GetMaxLength
102      *
103      */
ResetMaxLength(void)104     void ResetMaxLength(void) { mMaxLength = GetLength(); }
105 
106     /**
107      * Returns the Data Version value for a type (full set or stable subset).
108      *
109      * @param[in] aType   The Network Data type (full set or stable subset).
110      *
111      * @returns The Data Version value for @p aType.
112      *
113      */
GetVersion(Type aType) const114     uint8_t GetVersion(Type aType) const { return (aType == kFullSet) ? mVersion : mStableVersion; }
115 
116     /**
117      * Retrieves the 6LoWPAN Context information based on a given IPv6 address.
118      *
119      * @param[in]   aAddress  A reference to an IPv6 address.
120      * @param[out]  aContext  A reference to 6LoWPAN Context information.
121      *
122      * @retval kErrorNone       Successfully retrieved 6LoWPAN Context information.
123      * @retval kErrorNotFound   Could not find the 6LoWPAN Context information.
124      *
125      */
126     Error GetContext(const Ip6::Address &aAddress, Lowpan::Context &aContext) const;
127 
128     /**
129      * Retrieves the 6LoWPAN Context information based on a given Context ID.
130      *
131      * @param[in]   aContextId  The Context ID value.
132      * @param[out]  aContext    A reference to the 6LoWPAN Context information.
133      *
134      * @retval kErrorNone       Successfully retrieved 6LoWPAN Context information.
135      * @retval kErrorNotFound   Could not find the 6LoWPAN Context information.
136      *
137      */
138     Error GetContext(uint8_t aContextId, Lowpan::Context &aContext) const;
139 
140     /**
141      * Indicates whether or not the given IPv6 address is on-mesh.
142      *
143      * @param[in]  aAddress  A reference to an IPv6 address.
144      *
145      * @retval TRUE   If @p aAddress is on-link.
146      * @retval FALSE  If @p aAddress if not on-link.
147      *
148      */
149     bool IsOnMesh(const Ip6::Address &aAddress) const;
150 
151     /**
152      * Performs a route lookup using the Network Data.
153      *
154      * @param[in]   aSource             A reference to the IPv6 source address.
155      * @param[in]   aDestination        A reference to the IPv6 destination address.
156      * @param[out]  aRloc16             A reference to return the RLOC16 for the selected route.
157      *
158      * @retval kErrorNone      Successfully found a route. @p aRloc16 is updated.
159      * @retval kErrorNoRoute   No valid route was found.
160      *
161      */
162     Error RouteLookup(const Ip6::Address &aSource, const Ip6::Address &aDestination, uint16_t &aRloc16) const;
163 
164     /**
165      * Is used by non-Leader devices to set Network Data by reading it from a message from Leader.
166      *
167      * @param[in]  aVersion        The Version value.
168      * @param[in]  aStableVersion  The Stable Version value.
169      * @param[in]  aType           The Network Data type to set, the full set or stable subset.
170      * @param[in]  aMessage        A reference to the message.
171      * @param[in]  aOffsetRange    The offset range in @p aMessage to read from.
172      *
173      * @retval kErrorNone   Successfully set the network data.
174      * @retval kErrorParse  Network Data in @p aMessage is not valid.
175      *
176      */
177     Error SetNetworkData(uint8_t            aVersion,
178                          uint8_t            aStableVersion,
179                          Type               aType,
180                          const Message     &aMessage,
181                          const OffsetRange &aOffsetRange);
182 
183     /**
184      * Gets the Commissioning Dataset from Network Data.
185      *
186      * @param[out] aDataset    A reference to a `MeshCoP::CommissioningDataset` to populate.
187      *
188      */
189     void GetCommissioningDataset(MeshCoP::CommissioningDataset &aDataset) const;
190 
191     /**
192      * Processes a MGMT_COMMISSIONER_GET request message and prepares the response.
193      *
194      * @param[in] aRequest   The MGMT_COMMISSIONER_GET request message.
195      *
196      * @returns The prepared response, or `nullptr` if fails to parse the request or cannot allocate message.
197      *
198      */
199     Coap::Message *ProcessCommissionerGetRequest(const Coap::Message &aMessage) const;
200 
201     /**
202      * Searches for given sub-TLV in Commissioning Data TLV.
203      *
204      * @tparam SubTlvType    The sub-TLV type to search for.
205      *
206      * @returns A pointer to the Commissioning Data Sub-TLV or `nullptr` if no such sub-TLV exists.
207      *
208      */
FindInCommissioningData(void) const209     template <typename SubTlvType> const SubTlvType *FindInCommissioningData(void) const
210     {
211         return As<SubTlvType>(FindCommissioningDataSubTlv(SubTlvType::kType));
212     }
213 
214     /**
215      * Searches for given sub-TLV in Commissioning Data TLV.
216      *
217      * @tparam SubTlvType    The sub-TLV type to search for.
218      *
219      * @returns A pointer to the Commissioning Data Sub-TLV or `nullptr` if no such sub-TLV exists.
220      *
221      */
FindInCommissioningData(void)222     template <typename SubTlvType> SubTlvType *FindInCommissioningData(void)
223     {
224         return As<SubTlvType>(FindCommissioningDataSubTlv(SubTlvType::kType));
225     }
226 
227     /**
228      * Finds and reads the Commissioning Session ID in Commissioning Data TLV.
229      *
230      * @param[out] aSessionId  A reference to return the read session ID.
231      *
232      * @retval kErrorNone       Successfully read the session ID, @p aSessionId is updated.
233      * @retval kErrorNotFound   Did not find Session ID sub-TLV.
234      * @retval kErrorParse      Failed to parse Commissioning Data TLV (invalid format).
235      *
236      */
237     Error FindCommissioningSessionId(uint16_t &aSessionId) const;
238 
239     /**
240      * Finds and reads the Border Agent RLOC16 in Commissioning Data TLV.
241      *
242      * @param[out] aRloc16  A reference to return the read RLOC16.
243      *
244      * @retval kErrorNone       Successfully read the Border Agent RLOC16, @p aRloc16 is updated.
245      * @retval kErrorNotFound   Did not find Border Agent RLOC16 sub-TLV.
246      * @retval kErrorParse      Failed to parse Commissioning Data TLV (invalid format).
247      *
248      */
249     Error FindBorderAgentRloc(uint16_t &aRloc16) const;
250 
251     /**
252      * Finds and reads the Joiner UDP Port in Commissioning Data TLV.
253      *
254      * @param[out] aPort  A reference to return the read port number.
255      *
256      * @retval kErrorNone       Successfully read the Joiner UDP port, @p aPort is updated.
257      * @retval kErrorNotFound   Did not find Joiner UDP Port sub-TLV.
258      * @retval kErrorParse      Failed to parse Commissioning Data TLV (invalid format).
259      *
260      */
261     Error FindJoinerUdpPort(uint16_t &aPort) const;
262 
263     /**
264      * Finds and read the Steering Data in Commissioning Data TLV.
265      *
266      * @param[out] aSteeringData  A reference to return the read Steering Data.
267      *
268      * @retval kErrorNone       Successfully read the Steering Data, @p aSteeringData is updated.
269      * @retval kErrorNotFound   Did not find Steering Data sub-TLV.
270      *
271      */
272     Error FindSteeringData(MeshCoP::SteeringData &aSteeringData) const;
273 
274     /**
275      * Indicates whether or not the Commissioning Data TLV indicates Joining is allowed.
276      *
277      * Joining is allowed if a Border Agent Locator TLV exist and the Steering Data TLV is non-zero.
278      *
279      * @retval TRUE    If joining is allowed.
280      * @retval FALSE   If joining is not allowed.
281      *
282      */
283     bool IsJoiningAllowed(void) const;
284 
285     /**
286      * Checks if the steering data includes a Joiner.
287      *
288      * @param[in]  aEui64             A reference to the Joiner's IEEE EUI-64.
289      *
290      * @retval kErrorNone          @p aEui64 is in the bloom filter.
291      * @retval kErrorInvalidState  No steering data present.
292      * @retval kErrorNotFound      @p aEui64 is not in the bloom filter.
293      *
294      */
295     Error SteeringDataCheckJoiner(const Mac::ExtAddress &aEui64) const;
296 
297     /**
298      * Checks if the steering data includes a Joiner with a given discerner value.
299      *
300      * @param[in]  aDiscerner         A reference to the Joiner Discerner.
301      *
302      * @retval kErrorNone          @p aDiscerner is in the bloom filter.
303      * @retval kErrorInvalidState  No steering data present.
304      * @retval kErrorNotFound      @p aDiscerner is not in the bloom filter.
305      *
306      */
307     Error SteeringDataCheckJoiner(const MeshCoP::JoinerDiscerner &aDiscerner) const;
308 
309     /**
310      * Gets the Service ID for the specified service.
311      *
312      * @param[in]  aEnterpriseNumber  Enterprise Number (IANA-assigned) for Service TLV
313      * @param[in]  aServiceData       The Service Data.
314      * @param[in]  aServerStable      The Stable flag value for Server TLV.
315      * @param[out] aServiceId         A reference where to put the Service ID.
316      *
317      * @retval kErrorNone       Successfully got the Service ID.
318      * @retval kErrorNotFound   The specified service was not found.
319      *
320      */
321     Error GetServiceId(uint32_t           aEnterpriseNumber,
322                        const ServiceData &aServiceData,
323                        bool               aServerStable,
324                        uint8_t           &aServiceId) const;
325 
326     /**
327      * Gets the preferred NAT64 prefix from network data.
328      *
329      * The returned prefix is the highest preference external route entry in Network Data with NAT64 flag set. If there
330      * are multiple such entries the first one is returned.
331      *
332      * @param[out] aConfig      A reference to an `ExternalRouteConfig` to return the prefix.
333      *
334      * @retval kErrorNone       Found the NAT64 prefix and updated @p aConfig.
335      * @retval kErrorNotFound   Could not find any NAT64 entry.
336      *
337      */
338     Error GetPreferredNat64Prefix(ExternalRouteConfig &aConfig) const;
339 
340     /**
341      * Indicates whether or not the given IPv6 address matches any NAT64 prefixes.
342      *
343      * @param[in]  aAddress  An IPv6 address to check.
344      *
345      * @retval TRUE   If @p aAddress matches a NAT64 prefix.
346      * @retval FALSE  If @p aAddress does not match a NAT64 prefix.
347      *
348      */
349     bool IsNat64(const Ip6::Address &aAddress) const;
350 
351 #if OPENTHREAD_FTD
352     /**
353      * Defines the match mode constants to compare two RLOC16 values.
354      *
355      */
356     enum MatchMode : uint8_t
357     {
358         kMatchModeRloc16,   ///< Perform exact RLOC16 match.
359         kMatchModeRouterId, ///< Perform Router ID match (match the router and any of its children).
360     };
361 
362     /**
363      * Starts the Leader services.
364      *
365      * The start mode indicates whether device is starting normally as leader or restoring its role as leader after
366      * reset. In the latter case, we do not accept any new registrations (`HandleServerData()`) and wait for
367      * `HandleNetworkDataRestoredAfterReset()` to indicate that the leader has successfully recovered the Network Data
368      * before allowing new Network Data registrations.
369      *
370      * @param[in] aStartMode   The start mode.
371      *
372      */
373     void Start(Mle::LeaderStartMode aStartMode);
374 
375     /**
376      * Increments the Thread Network Data version.
377      *
378      */
379     void IncrementVersion(void);
380 
381     /**
382      * Increments both the Thread Network Data version and stable version.
383      *
384      */
385     void IncrementVersionAndStableVersion(void);
386 
387     /**
388      * Performs anycast ALOC route lookup using the Network Data.
389      *
390      * @param[in]   aAloc16     The ALOC16 destination to lookup.
391      * @param[out]  aRloc16     A reference to return the RLOC16 for the selected route.
392      *
393      * @retval kErrorNone      Successfully lookup best option for @p aAloc16. @p aRloc16 is updated.
394      * @retval kErrorNoRoute   No valid route was found.
395      * @retval kErrorDrop      The @p aAloc16 is not valid.
396      *
397      */
398     Error AnycastLookup(uint16_t aAloc16, uint16_t &aRloc16) const;
399 
400     /**
401      * Returns CONTEXT_ID_RESUSE_DELAY value.
402      *
403      * @returns The CONTEXT_ID_REUSE_DELAY value (in seconds).
404      *
405      */
GetContextIdReuseDelay(void) const406     uint32_t GetContextIdReuseDelay(void) const { return mContextIds.GetReuseDelay(); }
407 
408     /**
409      * Sets CONTEXT_ID_RESUSE_DELAY value.
410      *
411      * @warning This method should only be used for testing.
412      *
413      * @param[in]  aDelay  The CONTEXT_ID_REUSE_DELAY value (in seconds).
414      *
415      */
SetContextIdReuseDelay(uint32_t aDelay)416     void SetContextIdReuseDelay(uint32_t aDelay) { mContextIds.SetReuseDelay(aDelay); }
417 
418     /**
419      * Removes Network Data entries matching with a given RLOC16.
420      *
421      * @param[in]  aRloc16    A RLOC16 value.
422      * @param[in]  aMatchMode A match mode (@sa MatchMode).
423      *
424      */
425     void RemoveBorderRouter(uint16_t aRloc16, MatchMode aMatchMode);
426 
427     /**
428      * Updates Commissioning Data in Network Data.
429      *
430      * @param[in]  aData        A pointer to the Commissioning Data.
431      * @param[in]  aDataLength  The length of @p aData.
432      *
433      * @retval kErrorNone     Successfully updated the Commissioning Data.
434      * @retval kErrorNoBufs   Insufficient space to add the Commissioning Data.
435      *
436      */
437     Error SetCommissioningData(const void *aData, uint8_t aDataLength);
438 
439     /**
440      * Synchronizes internal 6LoWPAN Context ID Set with recently obtained Thread Network Data.
441      *
442      * Note that this method should be called only by the Leader once after reset.
443      *
444      */
445     void HandleNetworkDataRestoredAfterReset(void);
446 
447 #endif // OPENTHREAD_FTD
448 
449 #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
450     /**
451      * Indicates whether Network Data contains a valid OMR prefix.
452      *
453      * If the given @p aPrefix is itself not a valid OMR prefix, this method will return `false`, regardless of
454      * whether the prefix is present in the Network Data.
455      *
456      * @param[in]  aPrefix   The OMR prefix to check.
457      *
458      * @retval TRUE   Network Data contains a valid OMR prefix entry matching @p aPrefix.
459      * @retval FALSE  Network Data does not contain a valid OMR prefix entry matching @p aPrefix.
460      *
461      */
462     bool ContainsOmrPrefix(const Ip6::Prefix &aPrefix) const;
463 #endif
464 
465 private:
466     using FilterIndexes = MeshCoP::SteeringData::HashBitIndexes;
467 
468     typedef bool (&EntryChecker)(const BorderRouterEntry &aEntry);
469 
470     const PrefixTlv *FindNextMatchingPrefixTlv(const Ip6::Address &aAddress, const PrefixTlv *aPrevTlv) const;
471     const PrefixTlv *FindPrefixTlvForContextId(uint8_t aContextId, const ContextTlv *&aContextTlv) const;
472 
473     int CompareRouteEntries(const BorderRouterEntry &aFirst, const BorderRouterEntry &aSecond) const;
474     int CompareRouteEntries(const HasRouteEntry &aFirst, const HasRouteEntry &aSecond) const;
475     int CompareRouteEntries(const ServerTlv &aFirst, const ServerTlv &aSecond) const;
476     int CompareRouteEntries(int8_t   aFirstPreference,
477                             uint16_t aFirstRloc,
478                             int8_t   aSecondPreference,
479                             uint16_t aSecondRloc) const;
480 
481     static bool IsEntryDefaultRoute(const BorderRouterEntry &aEntry);
482 
483     Error ExternalRouteLookup(uint8_t aDomainId, const Ip6::Address &aDestination, uint16_t &aRloc16) const;
484     Error DefaultRouteLookup(const PrefixTlv &aPrefix, uint16_t &aRloc16) const;
485     Error LookupRouteIn(const PrefixTlv &aPrefixTlv, EntryChecker aEntryChecker, uint16_t &aRloc16) const;
486     Error SteeringDataCheck(const FilterIndexes &aFilterIndexes) const;
487     void  GetContextForMeshLocalPrefix(Lowpan::Context &aContext) const;
488     Error ReadCommissioningDataUint16SubTlv(MeshCoP::Tlv::Type aType, uint16_t &aValue) const;
489     void  SignalNetDataChanged(void);
490     const CommissioningDataTlv *FindCommissioningData(void) const;
FindCommissioningData(void)491     CommissioningDataTlv *FindCommissioningData(void) { return AsNonConst(AsConst(this)->FindCommissioningData()); }
492     const MeshCoP::Tlv   *FindCommissioningDataSubTlv(uint8_t aType) const;
FindCommissioningDataSubTlv(uint8_t aType)493     MeshCoP::Tlv         *FindCommissioningDataSubTlv(uint8_t aType)
494     {
495         return AsNonConst(AsConst(this)->FindCommissioningDataSubTlv(aType));
496     }
497 
498 #if OPENTHREAD_FTD
499     static constexpr uint32_t kMaxNetDataSyncWait = 60 * 1000; // Maximum time to wait for netdata sync in msec.
500     static constexpr uint8_t  kMinServiceId       = 0x00;
501     static constexpr uint8_t  kMaxServiceId       = 0x0f;
502 
503     class ChangedFlags
504     {
505     public:
ChangedFlags(void)506         ChangedFlags(void)
507             : mChanged(false)
508             , mStableChanged(false)
509         {
510         }
511 
Update(const NetworkDataTlv & aTlv)512         void Update(const NetworkDataTlv &aTlv)
513         {
514             mChanged       = true;
515             mStableChanged = (mStableChanged || aTlv.IsStable());
516         }
517 
DidChange(void) const518         bool DidChange(void) const { return mChanged; }
DidStableChange(void) const519         bool DidStableChange(void) const { return mStableChanged; }
520 
521     private:
522         bool mChanged;       // Any (stable or not) network data change (add/remove).
523         bool mStableChanged; // Stable network data change (add/remove).
524     };
525 
526     enum UpdateStatus : uint8_t
527     {
528         kTlvRemoved, // TLV contained no sub TLVs and therefore is removed.
529         kTlvUpdated, // TLV stable flag is updated based on its sub TLVs.
530     };
531 
532     class ContextIds : public InstanceLocator
533     {
534     public:
535         // This class tracks Context IDs. A Context ID can be in one
536         // of the 3 states: It is unallocated, or it is allocated
537         // and in-use, or it scheduled to be removed (after reuse delay
538         // interval is passed).
539 
540         static constexpr uint8_t kInvalidId = NumericLimits<uint8_t>::kMax;
541 
542         explicit ContextIds(Instance &aInstance);
543 
544         void     Clear(void);
545         Error    GetUnallocatedId(uint8_t &aId);
MarkAsInUse(uint8_t aId)546         void     MarkAsInUse(uint8_t aId) { mRemoveTimes[aId - kMinId].SetValue(kInUse); }
547         void     ScheduleToRemove(uint8_t aId);
GetReuseDelay(void) const548         uint32_t GetReuseDelay(void) const { return mReuseDelay; }
SetReuseDelay(uint32_t aDelay)549         void     SetReuseDelay(uint32_t aDelay) { mReuseDelay = aDelay; }
550         void     HandleTimer(void);
551 #if OPENTHREAD_CONFIG_BORDER_ROUTER_SIGNAL_NETWORK_DATA_FULL
MarkAsClone(void)552         void MarkAsClone(void) { mIsClone = true; }
553 #endif
554 
555     private:
556         static constexpr uint32_t kReuseDelay = 5 * 60; // 5 minutes (in seconds).
557 
558         static constexpr uint8_t kMinId = 1;
559         static constexpr uint8_t kMaxId = 15;
560 
561         // The `mRemoveTimes[id]` is used to track the state of a
562         // Context ID and its remove time. Two specific values
563         // `kUnallocated` and `kInUse` are used to indicate ID is in
564         // unallocated or in-use states. Other values indicate we
565         // are in remove state waiting to remove it at `mRemoveTime`.
566 
567         static constexpr uint32_t kUnallocated = 0;
568         static constexpr uint32_t kInUse       = 1;
569 
IsUnallocated(uint8_t aId) const570         bool      IsUnallocated(uint8_t aId) const { return mRemoveTimes[aId - kMinId].GetValue() == kUnallocated; }
IsInUse(uint8_t aId) const571         bool      IsInUse(uint8_t aId) const { return mRemoveTimes[aId - kMinId].GetValue() == kInUse; }
GetRemoveTime(uint8_t aId) const572         TimeMilli GetRemoveTime(uint8_t aId) const { return mRemoveTimes[aId - kMinId]; }
573         void      SetRemoveTime(uint8_t aId, TimeMilli aTime);
MarkAsUnallocated(uint8_t aId)574         void      MarkAsUnallocated(uint8_t aId) { mRemoveTimes[aId - kMinId].SetValue(kUnallocated); }
575 
576         TimeMilli mRemoveTimes[kMaxId - kMinId + 1];
577         uint32_t  mReuseDelay;
578 #if OPENTHREAD_CONFIG_BORDER_ROUTER_SIGNAL_NETWORK_DATA_FULL
579         bool mIsClone;
580 #endif
581     };
582 
583     template <Uri kUri> void HandleTmf(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
584 
585     void HandleTimer(void);
586 
587     static bool IsEntryForDhcp6Agent(const BorderRouterEntry &aEntry);
588     static bool IsEntryForNdAgent(const BorderRouterEntry &aEntry);
589 
590     Error LookupRouteForServiceAloc(uint16_t aAloc16, uint16_t &aRloc16) const;
591     Error LookupRouteForAgentAloc(uint8_t aContextId, EntryChecker aEntryChecker, uint16_t &aRloc16) const;
592 
593     void RegisterNetworkData(uint16_t aRloc16, const NetworkData &aNetworkData);
594 
595     Error AddPrefix(const PrefixTlv &aPrefix, ChangedFlags &aChangedFlags);
596     Error AddHasRoute(const HasRouteTlv &aHasRoute, PrefixTlv &aDstPrefix, ChangedFlags &aChangedFlags);
597     Error AddBorderRouter(const BorderRouterTlv &aBorderRouter, PrefixTlv &aDstPrefix, ChangedFlags &aChangedFlags);
598     Error AddService(const ServiceTlv &aService, ChangedFlags &aChangedFlags);
599     Error AddServer(const ServerTlv &aServer, ServiceTlv &aDstService, ChangedFlags &aChangedFlags);
600 
601     Error             AllocateServiceId(uint8_t &aServiceId) const;
602     const ServiceTlv *FindServiceById(uint8_t aServiceId) const;
603 
604     void RemoveContext(uint8_t aContextId);
605     void RemoveContext(PrefixTlv &aPrefix, uint8_t aContextId);
606 
607     void RemoveCommissioningData(void);
608 
609     void RemoveRloc(uint16_t aRloc16, MatchMode aMatchMode, ChangedFlags &aChangedFlags);
610     void RemoveRloc(uint16_t           aRloc16,
611                     MatchMode          aMatchMode,
612                     const NetworkData &aExcludeNetworkData,
613                     ChangedFlags      &aChangedFlags);
614     void RemoveRlocInPrefix(PrefixTlv       &aPrefix,
615                             uint16_t         aRloc16,
616                             MatchMode        aMatchMode,
617                             const PrefixTlv *aExcludePrefix,
618                             ChangedFlags    &aChangedFlags);
619     void RemoveRlocInService(ServiceTlv       &aService,
620                              uint16_t          aRloc16,
621                              MatchMode         aMatchMode,
622                              const ServiceTlv *aExcludeService,
623                              ChangedFlags     &aChangedFlags);
624     void RemoveRlocInHasRoute(PrefixTlv       &aPrefix,
625                               HasRouteTlv     &aHasRoute,
626                               uint16_t         aRloc16,
627                               MatchMode        aMatchMode,
628                               const PrefixTlv *aExcludePrefix,
629                               ChangedFlags    &aChangedFlags);
630     void RemoveRlocInBorderRouter(PrefixTlv       &aPrefix,
631                                   BorderRouterTlv &aBorderRouter,
632                                   uint16_t         aRloc16,
633                                   MatchMode        aMatchMode,
634                                   const PrefixTlv *aExcludePrefix,
635                                   ChangedFlags    &aChangedFlags);
636 
637     static bool RlocMatch(uint16_t aFirstRloc16, uint16_t aSecondRloc16, MatchMode aMatchMode);
638 
639     static Error Validate(const NetworkData &aNetworkData, uint16_t aRloc16);
640     static Error ValidatePrefix(const PrefixTlv &aPrefix, uint16_t aRloc16);
641     static Error ValidateService(const ServiceTlv &aService, uint16_t aRloc16);
642 
643     static bool ContainsMatchingEntry(const PrefixTlv *aPrefix, bool aStable, const HasRouteEntry &aEntry);
644     static bool ContainsMatchingEntry(const HasRouteTlv *aHasRoute, const HasRouteEntry &aEntry);
645     static bool ContainsMatchingEntry(const PrefixTlv *aPrefix, bool aStable, const BorderRouterEntry &aEntry);
646     static bool ContainsMatchingEntry(const BorderRouterTlv *aBorderRouter, const BorderRouterEntry &aEntry);
647     static bool ContainsMatchingServer(const ServiceTlv *aService, const ServerTlv &aServer);
648 
649     UpdateStatus UpdatePrefix(PrefixTlv &aPrefix);
650     UpdateStatus UpdateService(ServiceTlv &aService);
651     UpdateStatus UpdateTlv(NetworkDataTlv &aTlv, const NetworkDataTlv *aSubTlvs);
652 
653     Error UpdateCommissioningData(uint16_t aDataLength, CommissioningDataTlv *&aDataTlv);
654     Error SetCommissioningData(const Message &aMessage);
655 
656     void SendCommissioningSetResponse(const Coap::Message     &aRequest,
657                                       const Ip6::MessageInfo  &aMessageInfo,
658                                       MeshCoP::StateTlv::State aState);
659     void IncrementVersions(bool aIncludeStable);
660     void IncrementVersions(const ChangedFlags &aFlags);
661 
662 #if OPENTHREAD_CONFIG_BORDER_ROUTER_SIGNAL_NETWORK_DATA_FULL
663     void CheckForNetDataGettingFull(const NetworkData &aNetworkData, uint16_t aOldRloc16);
664     void MarkAsClone(void);
665 #endif
666 
667     using UpdateTimer = TimerMilliIn<Leader, &Leader::HandleTimer>;
668 #endif // OPENTHREAD_FTD
669 
670     uint8_t mStableVersion;
671     uint8_t mVersion;
672     uint8_t mTlvBuffer[kMaxSize];
673     uint8_t mMaxLength;
674 
675 #if OPENTHREAD_FTD
676 #if OPENTHREAD_CONFIG_BORDER_ROUTER_SIGNAL_NETWORK_DATA_FULL
677     bool mIsClone;
678 #endif
679     bool        mWaitingForNetDataSync;
680     ContextIds  mContextIds;
681     UpdateTimer mTimer;
682 #endif
683 };
684 
685 #if OPENTHREAD_FTD
686 DeclareTmfHandler(Leader, kUriServerData);
687 DeclareTmfHandler(Leader, kUriCommissionerGet);
688 DeclareTmfHandler(Leader, kUriCommissionerSet);
689 #endif
690 
691 /**
692  * @}
693  */
694 
695 } // namespace NetworkData
696 } // namespace ot
697 
698 #endif // NETWORK_DATA_LEADER_HPP_
699