• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2021, 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 definition of Network Data Publisher.
32  */
33 
34 #ifndef NETWORK_DATA_PUBLISHER_HPP_
35 #define NETWORK_DATA_PUBLISHER_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #if OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE
40 
41 #if !OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE && !OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
42 #error "OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE requires either OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE"\
43             "or OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE"
44 #endif
45 
46 #include <openthread/netdata_publisher.h>
47 
48 #include "border_router/routing_manager.hpp"
49 #include "common/callback.hpp"
50 #include "common/clearable.hpp"
51 #include "common/equatable.hpp"
52 #include "common/error.hpp"
53 #include "common/locator.hpp"
54 #include "common/non_copyable.hpp"
55 #include "common/notifier.hpp"
56 #include "common/string.hpp"
57 #include "common/timer.hpp"
58 #include "net/ip6_address.hpp"
59 #include "thread/network_data_service.hpp"
60 #include "thread/network_data_types.hpp"
61 
62 namespace ot {
63 namespace NetworkData {
64 
65 /**
66  * Implements the Network Data Publisher.
67  *
68  * It provides mechanisms to limit the number of similar Service and/or Prefix (on-mesh prefix or external route)
69  * entries in the Thread Network Data by monitoring the Network Data and managing if or when to add or remove entries.
70  */
71 class Publisher : public InstanceLocator, private NonCopyable
72 {
73     friend class ot::Notifier;
74 
75 public:
76     /**
77      * Represents the events reported from the Publisher callbacks.
78      */
79     enum Event : uint8_t
80     {
81         kEventEntryAdded   = OT_NETDATA_PUBLISHER_EVENT_ENTRY_ADDED,   ///< Entry is added to Network Data.
82         kEventEntryRemoved = OT_NETDATA_PUBLISHER_EVENT_ENTRY_REMOVED, ///< Entry is removed from Network Data.
83     };
84 
85     /**
86      * Represents the requester associated with a published prefix.
87      */
88     enum Requester : uint8_t
89     {
90         kFromUser,           ///< Requested by user (public OT API).
91         kFromRoutingManager, ///< Requested by `RoutingManager` module.
92     };
93 
94     /**
95      * Initializes `Publisher` object.
96      *
97      * @param[in]  aInstance     A reference to the OpenThread instance.
98      */
99     explicit Publisher(Instance &aInstance);
100 
101 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
102 
103     /**
104      * Represents the callback function pointer used to notify when a "DNS/SRP Service" entry is added to or
105      * removed from the Thread Network Data.
106      *
107      * On remove the callback is invoked independent of whether the entry is removed by `Publisher` (e.g., when there
108      * are too many similar entries already present in the Network Data) or through an explicit call to unpublish the
109      * entry (i.e., a call to `UnpublishDnsSrpService()`).
110      */
111     typedef otNetDataDnsSrpServicePublisherCallback DnsSrpServiceCallback;
112 
113     /**
114      * Sets a callback for notifying when a published "DNS/SRP Service" is actually added to or removed
115      * from the Thread Network Data.
116      *
117      * A subsequent call to this method replaces any previously set callback function.
118      *
119      * @param[in] aCallback        The callback function pointer (can be NULL if not needed).
120      * @param[in] aContext         A pointer to application-specific context (used when @p aCallback is invoked).
121      */
SetDnsSrpServiceCallback(DnsSrpServiceCallback aCallback,void * aContext)122     void SetDnsSrpServiceCallback(DnsSrpServiceCallback aCallback, void *aContext)
123     {
124         mDnsSrpServiceEntry.SetCallback(aCallback, aContext);
125     }
126 
127     /**
128      * Requests "DNS/SRP Service Anycast Address" to be published in the Thread Network Data.
129      *
130      * A call to this method will remove and replace any previous "DNS/SRP Service" entry that was being published
131      * (from earlier call to any of `PublishDnsSrpService{Type}()` methods).
132      *
133      * @param[in] aSequenceNumber  The sequence number of DNS/SRP Anycast Service.
134      * @param[in] aVersion         The version number of DNS/SRP service.
135      */
PublishDnsSrpServiceAnycast(uint8_t aSequenceNumber,uint8_t aVersion)136     void PublishDnsSrpServiceAnycast(uint8_t aSequenceNumber, uint8_t aVersion)
137     {
138         mDnsSrpServiceEntry.PublishAnycast(aSequenceNumber, aVersion);
139     }
140 
141     /**
142      * Requests "DNS/SRP Service Unicast Address" to be published in the Thread Network Data.
143      *
144      * A call to this method will remove and replace any previous "DNS/SRP Service" entry that was being published
145      * (from earlier call to any of `PublishDnsSrpService{Type}()` methods).
146      *
147      * Publishes the "DNS/SRP Service Unicast Address" by including the address and port info in the
148      * Service TLV data.
149      *
150      * @param[in] aAddress   The DNS/SRP server address to publish.
151      * @param[in] aPort      The SRP server port number to publish.
152      * @param[in] aVersion   The SRP server version to publish.
153      */
PublishDnsSrpServiceUnicast(const Ip6::Address & aAddress,uint16_t aPort,uint8_t aVersion)154     void PublishDnsSrpServiceUnicast(const Ip6::Address &aAddress, uint16_t aPort, uint8_t aVersion)
155     {
156         mDnsSrpServiceEntry.PublishUnicast(aAddress, aPort, aVersion);
157     }
158 
159     /**
160      * Requests "DNS/SRP Service Unicast Address" to be published in the Thread Network Data.
161      *
162      * A call to this method will remove and replace any previous "DNS/SRP Service" entry that was being published
163      * (from earlier call to any of `PublishDnsSrpService{Type}()` methods).
164      *
165      * Unlike the `PublishDnsSrpServiceUnicast(aAddress, aPort)` which requires the published address to be given and
166      * includes the info in the Service TLV data, this method uses the device's mesh-local EID and includes the info
167      * in the Server TLV data.
168      *
169      * @param[in] aPort      The SRP server port number to publish.
170      * @param[in] aVersion   The SRP server version to publish.
171      */
PublishDnsSrpServiceUnicast(uint16_t aPort,uint8_t aVersion)172     void PublishDnsSrpServiceUnicast(uint16_t aPort, uint8_t aVersion)
173     {
174         mDnsSrpServiceEntry.PublishUnicast(aPort, aVersion);
175     }
176 
177     /**
178      * Indicates whether or not currently the "DNS/SRP Service" entry is added to the Thread Network Data.
179      *
180      * @retval TRUE    The published DNS/SRP Service entry is added to the Thread Network Data.
181      * @retval FALSE   The entry is not added to Thread Network Data or there is no entry to publish.
182      */
IsDnsSrpServiceAdded(void) const183     bool IsDnsSrpServiceAdded(void) const { return mDnsSrpServiceEntry.IsAdded(); }
184 
185     /**
186      * Unpublishes any previously added "DNS/SRP (Anycast or Unicast) Service" entry from the Thread
187      * Network Data.
188      */
UnpublishDnsSrpService(void)189     void UnpublishDnsSrpService(void) { mDnsSrpServiceEntry.Unpublish(); }
190 
191 #endif // OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
192 
193 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
194     /**
195      * Represents the callback function pointer used to notify when a prefix (on-mesh or external route)
196      * entry is added to or removed from the Thread Network Data.
197      *
198      * On remove the callback is invoked independent of whether the entry is removed by `Publisher` (e.g., when there
199      * are too many similar entries already present in the Network Data) or through an explicit call to unpublish the
200      * entry.
201      */
202     typedef otNetDataPrefixPublisherCallback PrefixCallback;
203 
204     /**
205      * Sets a callback for notifying when a published prefix entry is actually added to or removed from
206      * the Thread Network Data.
207      *
208      * A subsequent call to this method replaces any previously set callback function.
209      *
210      * @param[in] aCallback        The callback function pointer (can be NULL if not needed).
211      * @param[in] aContext         A pointer to application-specific context (used when @p aCallback is invoked).
212      */
SetPrefixCallback(PrefixCallback aCallback,void * aContext)213     void SetPrefixCallback(PrefixCallback aCallback, void *aContext) { mPrefixCallback.Set(aCallback, aContext); }
214 
215     /**
216      * Requests an on-mesh prefix to be published in the Thread Network Data.
217      *
218      * Only stable entries can be published (i.e.,`aConfig.mStable` MUST be `true`).
219      *
220      * A subsequent call to this method will replace a previous request for the same prefix. In particular if the
221      * new call only changes the flags (e.g., preference level) and the prefix is already added in the Network Data,
222      * the change to flags is immediately reflected in the Network Data. This ensures that existing entries in the
223      * Network Data are not abruptly removed. Note that a change in the preference level can potentially later cause
224      * the entry to be removed from the Network Data after determining there are other nodes that are publishing the
225      * same prefix with the same or higher preference.
226      *
227      * @param[in] aConfig         The on-mesh prefix config to publish.
228      * @param[in] aRequester      The requester (`kFromUser` or `kFromRoutingManager` module).
229      *
230      * @retval kErrorNone         The on-mesh prefix is published successfully.
231      * @retval kErrorInvalidArgs  The @p aConfig is not valid (bad prefix, invalid flag combinations, or not stable).
232      * @retval kErrorAlready      An entry with the same prefix is already in the published list.
233      * @retval kErrorNoBufs       Could not allocate an entry for the new request. Publisher supports a limited number
234      *                            of entries (shared between on-mesh prefix and external route) determined by config
235      *                            `OPENTHREAD_CONFIG_NETDATA_PUBLISHER_MAX_PREFIX_ENTRIES`.
236      */
237     Error PublishOnMeshPrefix(const OnMeshPrefixConfig &aConfig, Requester aRequester);
238 
239     /**
240      * Requests an external route prefix to be published in the Thread Network Data.
241      *
242      * Only stable entries can be published (i.e.,`aConfig.mStable` MUST be `true`).
243      *
244      * A subsequent call to this method will replace a previous request for the same prefix. In particular if the
245      * new call only changes the flags (e.g., preference level) and the prefix is already added in the Network Data,
246      * the change to flags is immediately reflected in the Network Data. This ensures that existing entries in the
247      * Network Data are not abruptly removed. Note that a change in the preference level can potentially later cause
248      * the entry to be removed from the Network Data after determining there are other nodes that are publishing the
249      * same prefix with the same or higher preference.
250      *
251      * @param[in] aConfig         The external route config to publish.
252      * @param[in] aRequester      The requester (`kFromUser` or `kFromRoutingManager` module).
253      *
254      * @retval kErrorNone         The external route is published successfully.
255      * @retval kErrorInvalidArgs  The @p aConfig is not valid (bad prefix, invalid flag combinations, or not stable).
256      * @retval kErrorNoBufs       Could not allocate an entry for the new request. Publisher supports a limited number
257      *                            of entries (shared between on-mesh prefix and external route) determined by config
258      *                            `OPENTHREAD_CONFIG_NETDATA_PUBLISHER_MAX_PREFIX_ENTRIES`.
259      */
260     Error PublishExternalRoute(const ExternalRouteConfig &aConfig, Requester aRequester);
261 
262     /**
263      * Replaces a previously published external route.
264      *
265      * Only stable entries can be published (i.e.,`aConfig.mStable` MUST be `true`).
266      *
267      * If there is no previously published external route matching @p aPrefix, this method behaves similarly to
268      * `PublishExternalRoute()`, i.e., it will start the process of publishing @a aConfig as an external route in the
269      * Thread Network Data.
270      *
271      * If there is a previously published route entry matching @p aPrefix, it will be replaced with the new prefix from
272      * @p aConfig.
273      *
274      * - If the @p aPrefix was already added in the Network Data, the change to the new prefix in @p aConfig is
275      *   immediately reflected in the Network Data. This ensures that route entries in the Network Data are not
276      *   abruptly removed and the transition from aPrefix to the new prefix is smooth.
277      *
278      * - If the old published @p aPrefix was not added in the Network Data, it will be replaced with the new @p aConfig
279      *   prefix but it will not be immediately added. Instead, it will start the process of publishing it in the
280      *   Network Data (monitoring the Network Data to determine when/if to add the prefix, depending on the number of
281      *   similar prefixes present in the Network Data).
282      *
283      * @param[in] aPrefix         The previously published external route prefix to replace.
284      * @param[in] aConfig         The external route config to publish.
285      * @param[in] aRequester      The requester (`kFromUser` or `kFromRoutingManager` module).
286      *
287      * @retval kErrorNone         The external route is published successfully.
288      * @retval kErrorInvalidArgs  The @p aConfig is not valid (bad prefix, invalid flag combinations, or not stable).
289      * @retval kErrorNoBufs       Could not allocate an entry for the new request. Publisher supports a limited number
290      *                            of entries (shared between on-mesh prefix and external route) determined by config
291      *                            `OPENTHREAD_CONFIG_NETDATA_PUBLISHER_MAX_PREFIX_ENTRIES`.
292      */
293     Error ReplacePublishedExternalRoute(const Ip6::Prefix         &aPrefix,
294                                         const ExternalRouteConfig &aConfig,
295                                         Requester                  aRequester);
296 
297     /**
298      * Indicates whether or not currently a published prefix entry (on-mesh or external route) is added to
299      * the Thread Network Data.
300      *
301      * @param[in] aPrefix   The prefix to check.
302      *
303      * @retval TRUE    The published prefix entry is added to the Thread Network Data.
304      * @retval FALSE   The entry is not added to Thread Network Data or there is no matching entry to publish.
305      */
306     bool IsPrefixAdded(const Ip6::Prefix &aPrefix) const;
307 
308     /**
309      * Unpublishes a previously published prefix (on-mesh or external route).
310      *
311      * @param[in] aPrefix       The prefix to unpublish.
312      *
313      * @retval kErrorNone       The prefix was unpublished successfully.
314      * @retval kErrorNotFound   Could not find the prefix in the published list.
315      */
316     Error UnpublishPrefix(const Ip6::Prefix &aPrefix);
317 #endif // OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
318 
319 private:
320     class Entry : public InstanceLocatorInit
321     {
322     protected:
323         enum State : uint8_t
324         {
325             kNoEntry,  // Entry is unused (there is no entry).
326             kToAdd,    // Entry is ready to be added, monitoring network data to decide if/when to add it.
327             kAdding,   // Entry is being added in network data (random wait interval before add).
328             kAdded,    // Entry is added in network data, monitoring to determine if/when to remove.
329             kRemoving, // Entry is being removed from network data (random wait interval before remove).
330         };
331 
332         // All intervals are in milliseconds.
333         static constexpr uint32_t kMaxDelayToAdd    = OPENTHREAD_CONFIG_NETDATA_PUBLISHER_MAX_DELAY_TO_ADD;
334         static constexpr uint32_t kMaxDelayToRemove = OPENTHREAD_CONFIG_NETDATA_PUBLISHER_MAX_DELAY_TO_REMOVE;
335         static constexpr uint32_t kExtraDelayToRemovePreferred =
336             OPENTHREAD_CONFIG_NETDATA_PUBLISHER_EXTRA_DELAY_TIME_TO_REMOVE_PREFERRED;
337 
338         static constexpr uint16_t kInfoStringSize = 60;
339 
340         typedef String<kInfoStringSize> InfoString;
341 
Entry(void)342         Entry(void)
343             : mState(kNoEntry)
344         {
345         }
346 
Init(Instance & aInstance)347         void             Init(Instance &aInstance) { InstanceLocatorInit::Init(aInstance); }
GetState(void) const348         State            GetState(void) const { return mState; }
349         void             SetState(State aState);
GetUpdateTime(void) const350         const TimeMilli &GetUpdateTime(void) const { return mUpdateTime; }
351         bool             IsPreferred(uint16_t aRloc16) const;
352         void             UpdateState(uint8_t aNumEntries, uint8_t aNumPreferredEntries, uint8_t aDesiredNumEntries);
353         void             HandleTimer(void);
354         InfoString       ToString(bool aIncludeState = true) const;
355 
356     public:
IsAdded(void) const357         bool IsAdded(void) const { return (mState == kAdded); }
358 
359     private:
360         void               Add(void);
361         void               Remove(State aNextState);
362         void               LogUpdateTime(void) const;
363         static const char *StateToString(State aState);
364 
365         TimeMilli mUpdateTime;
366         State     mState;
367     };
368 
369 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
370     class DnsSrpServiceEntry : public Entry, private NonCopyable
371     {
372         friend class Entry;
373 
374     public:
375         explicit DnsSrpServiceEntry(Instance &aInstance);
SetCallback(DnsSrpServiceCallback aCallback,void * aContext)376         void SetCallback(DnsSrpServiceCallback aCallback, void *aContext) { mCallback.Set(aCallback, aContext); }
377         void PublishAnycast(uint8_t aSequenceNumber, uint8_t aVersion);
378         void PublishUnicast(const Ip6::Address &aAddress, uint16_t aPort, uint8_t aVersion);
379         void PublishUnicast(uint16_t aPort, uint8_t aVersion);
380         void Unpublish(void);
HandleTimer(void)381         void HandleTimer(void) { Entry::HandleTimer(); }
382         void HandleNotifierEvents(Events aEvents);
383 
384     private:
385         static constexpr uint8_t kDesiredNumAnycast =
386             OPENTHREAD_CONFIG_NETDATA_PUBLISHER_DESIRED_NUM_ANYCAST_DNS_SRP_SERVICE_ENTRIES;
387 
388         static constexpr uint8_t kDesiredNumUnicast =
389             OPENTHREAD_CONFIG_NETDATA_PUBLISHER_DESIRED_NUM_UNICAST_DNS_SRP_SERVICE_ENTRIES;
390 
391         enum Type : uint8_t
392         {
393             kTypeAnycast,
394             kTypeUnicast,
395             kTypeUnicastMeshLocalEid,
396         };
397 
398         class Info : public Clearable<Info>, public Equatable<Info>
399         {
400         public:
Info(void)401             Info(void) { Clear(); }
GetType(void) const402             Type                GetType(void) const { return mType; }
GetSequenceNumber(void) const403             uint8_t             GetSequenceNumber(void) const { return static_cast<uint8_t>(mPortOrSeqNumber); }
GetPort(void) const404             uint16_t            GetPort(void) const { return mPortOrSeqNumber; }
GetVersion(void) const405             uint8_t             GetVersion(void) const { return mVersion; }
GetAddress(void) const406             const Ip6::Address &GetAddress(void) const { return mAddress; }
SetAddress(const Ip6::Address & aAddress)407             void                SetAddress(const Ip6::Address &aAddress) { mAddress = aAddress; }
408 
InfoAnycast(uint8_t aSequenceNumber,uint8_t aVersion)409             static Info InfoAnycast(uint8_t aSequenceNumber, uint8_t aVersion)
410             {
411                 return Info(kTypeAnycast, aSequenceNumber, aVersion);
412             }
InfoUnicast(Type aType,const Ip6::Address & aAddress,uint16_t aPort,uint8_t aVersion)413             static Info InfoUnicast(Type aType, const Ip6::Address &aAddress, uint16_t aPort, uint8_t aVersion)
414             {
415                 return Info(aType, aPort, aVersion, &aAddress);
416             }
417 
418         private:
419             Info(Type aType, uint16_t aPortOrSeqNumber, uint8_t aVersion, const Ip6::Address *aAddress = nullptr);
420 
421             Ip6::Address mAddress;
422             uint16_t     mPortOrSeqNumber;
423             uint8_t      mVersion;
424             Type         mType;
425         };
426 
GetType(void) const427         Type GetType(void) const { return mInfo.GetType(); }
428         void Publish(const Info &aInfo);
429         void Add(void);
430         void Remove(State aNextState);
431         void Notify(Event aEvent) const;
432         void Process(void);
433         void CountAnycastEntries(uint8_t &aNumEntries, uint8_t &aNumPreferredEntries) const;
434         bool HasAnyAnycastEntry(void) const;
435         void CountUnicastEntries(Service::DnsSrpUnicastType aType,
436                                  uint8_t                   &aNumEntries,
437                                  uint8_t                   &aNumPreferredEntries) const;
438         bool HasAnyServiceDataUnicastEntry(void) const;
439 
440         Info                            mInfo;
441         Callback<DnsSrpServiceCallback> mCallback;
442     };
443 #endif // OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
444 
445 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
446 
447     // Max number of prefix (on-mesh or external route) entries.
448     static constexpr uint16_t kMaxUserPrefixEntries = OPENTHREAD_CONFIG_NETDATA_PUBLISHER_MAX_PREFIX_ENTRIES;
449 
450 #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
451     static constexpr uint16_t kMaxRoutingManagerPrefixEntries = BorderRouter::RoutingManager::kMaxPublishedPrefixes;
452 #else
453     static constexpr uint16_t kMaxRoutingManagerPrefixEntries = 0;
454 #endif
455 
456     class PrefixEntry : public Entry, private NonCopyable
457     {
458         friend class Entry;
459 
460     public:
Init(Instance & aInstance)461         void      Init(Instance &aInstance) { Entry::Init(aInstance); }
IsInUse(void) const462         bool      IsInUse(void) const { return GetState() != kNoEntry; }
Matches(const Ip6::Prefix & aPrefix) const463         bool      Matches(const Ip6::Prefix &aPrefix) const { return mPrefix == aPrefix; }
464         void      Publish(const OnMeshPrefixConfig &aConfig, Requester aRequester);
465         void      Publish(const ExternalRouteConfig &aConfig, Requester aRequester);
GetRequester(void) const466         Requester GetRequester(void) const { return mRequester; }
467         void      Unpublish(void);
HandleTimer(void)468         void      HandleTimer(void) { Entry::HandleTimer(); }
469         void      HandleNotifierEvents(Events aEvents);
470 
471     private:
472         static constexpr uint8_t kDesiredNumOnMeshPrefix =
473             OPENTHREAD_CONFIG_NETDATA_PUBLISHER_DESIRED_NUM_ON_MESH_PREFIX_ENTRIES;
474 
475         static constexpr uint8_t kDesiredNumExternalRoute =
476             OPENTHREAD_CONFIG_NETDATA_PUBLISHER_DESIRED_NUM_EXTERNAL_ROUTE_ENTRIES;
477 
478         enum Type : uint8_t
479         {
480             kTypeOnMeshPrefix,
481             kTypeExternalRoute,
482         };
483 
484         void  Publish(const Ip6::Prefix &aPrefix, uint16_t aNewFlags, Type aNewType, Requester aRequester);
485         void  Add(void);
486         Error AddOnMeshPrefix(void);
487         Error AddExternalRoute(void);
488         void  Remove(State aNextState);
489         void  Process(void);
490         void  CountOnMeshPrefixEntries(uint8_t &aNumEntries, uint8_t &aNumPreferredEntries) const;
491         void  CountExternalRouteEntries(uint8_t &aNumEntries, uint8_t &aNumPreferredEntries) const;
492 
493         Type        mType;
494         Requester   mRequester;
495         Ip6::Prefix mPrefix;
496         uint16_t    mFlags;
497     };
498 #endif // OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
499 
500 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
IsADnsSrpServiceEntry(const Entry & aEntry) const501     bool IsADnsSrpServiceEntry(const Entry &aEntry) const { return (&aEntry == &mDnsSrpServiceEntry); }
502 #endif
503 
504 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
505     PrefixEntry       *FindOrAllocatePrefixEntry(const Ip6::Prefix &aPrefix, Requester aRequester);
506     PrefixEntry       *FindMatchingPrefixEntry(const Ip6::Prefix &aPrefix);
507     const PrefixEntry *FindMatchingPrefixEntry(const Ip6::Prefix &aPrefix) const;
508     bool               IsAPrefixEntry(const Entry &aEntry) const;
509     void               NotifyPrefixEntryChange(Event aEvent, const Ip6::Prefix &aPrefix) const;
510 #endif
511 
GetTimer(void)512     TimerMilli &GetTimer(void) { return mTimer; }
513     void        HandleNotifierEvents(Events aEvents);
514     void        HandleTimer(void);
515 
516     using PublisherTimer = TimerMilliIn<Publisher, &Publisher::HandleTimer>;
517 
518 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
519     DnsSrpServiceEntry mDnsSrpServiceEntry;
520 #endif
521 
522 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
523     PrefixEntry              mPrefixEntries[kMaxUserPrefixEntries + kMaxRoutingManagerPrefixEntries];
524     Callback<PrefixCallback> mPrefixCallback;
525 #endif
526 
527     PublisherTimer mTimer;
528 };
529 
530 } // namespace NetworkData
531 } // namespace ot
532 
533 #endif // OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE
534 
535 #endif // NETWORK_DATA_PUBLISHER_HPP_
536