• 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 definitions to support History Tracker module.
32  */
33 
34 #ifndef HISTORY_TRACKER_HPP_
35 #define HISTORY_TRACKER_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
40 
41 #include <openthread/history_tracker.h>
42 #include <openthread/platform/radio.h>
43 
44 #include "common/as_core_type.hpp"
45 #include "common/clearable.hpp"
46 #include "common/locator.hpp"
47 #include "common/non_copyable.hpp"
48 #include "common/notifier.hpp"
49 #include "common/timer.hpp"
50 #include "net/netif.hpp"
51 #include "net/socket.hpp"
52 #include "thread/mesh_forwarder.hpp"
53 #include "thread/mle.hpp"
54 #include "thread/mle_types.hpp"
55 #include "thread/neighbor_table.hpp"
56 #include "thread/network_data.hpp"
57 #include "thread/router_table.hpp"
58 
59 namespace ot {
60 namespace Utils {
61 
62 #ifdef OPENTHREAD_CONFIG_HISTORY_TRACKER_NET_DATA
63 #error "OPENTHREAD_CONFIG_HISTORY_TRACKER_NET_DATA should not be defined directly." \
64        "It is derived from other configs: on-mesh prefix and external route history list sizes"
65 #endif
66 
67 #define OPENTHREAD_CONFIG_HISTORY_TRACKER_NET_DATA                       \
68     ((OPENTHREAD_CONFIG_HISTORY_TRACKER_ON_MESH_PREFIX_LIST_SIZE > 0) || \
69      (OPENTHREAD_CONFIG_HISTORY_TRACKER_EXTERNAL_ROUTE_LIST_SIZE > 0))
70 
71 /**
72  * Implements History Tracker.
73  */
74 class HistoryTracker : public InstanceLocator, private NonCopyable
75 {
76     friend class ot::MeshForwarder;
77     friend class ot::Notifier;
78     friend class ot::Mle::Mle;
79     friend class ot::NeighborTable;
80     friend class ot::Ip6::Netif;
81 #if OPENTHREAD_FTD
82     friend class ot::RouterTable;
83 #endif
84 
85 public:
86     /**
87      * This constant specifies the maximum age of entries which is 49 days (value in msec).
88      *
89      * Entries older than the max age will give this value as their age.
90      */
91     static constexpr uint32_t kMaxAge = OT_HISTORY_TRACKER_MAX_AGE;
92 
93     /**
94      * This constant specifies the recommend string size to represent an entry age
95      */
96     static constexpr uint16_t kEntryAgeStringSize = OT_HISTORY_TRACKER_ENTRY_AGE_STRING_SIZE;
97 
98     /**
99      * This constants specified no next hop.
100      *
101      * Used for `mNextHop` in `RouteInfo` structure.
102      */
103     static constexpr uint8_t kNoNextHop = OT_HISTORY_TRACKER_NO_NEXT_HOP;
104 
105     /**
106      * Represents an iterator to iterate through a history list.
107      */
108     class Iterator : public otHistoryTrackerIterator
109     {
110         friend class HistoryTracker;
111 
112     public:
113         /**
114          * Initializes an `Iterator`
115          *
116          * An iterator MUST be initialized before it is used. An iterator can be initialized again to start from
117          * the beginning of the list.
118          */
Init(void)119         void Init(void) { ResetEntryNumber(), SetInitTime(); }
120 
121     private:
GetEntryNumber(void) const122         uint16_t  GetEntryNumber(void) const { return mData16; }
ResetEntryNumber(void)123         void      ResetEntryNumber(void) { mData16 = 0; }
IncrementEntryNumber(void)124         void      IncrementEntryNumber(void) { mData16++; }
GetInitTime(void) const125         TimeMilli GetInitTime(void) const { return TimeMilli(mData32); }
SetInitTime(void)126         void      SetInitTime(void) { mData32 = TimerMilli::GetNow().GetValue(); }
127     };
128 
129     typedef otHistoryTrackerNetworkInfo          NetworkInfo;          ///< Thread network info.
130     typedef otHistoryTrackerUnicastAddressInfo   UnicastAddressInfo;   ///< Unicast IPv6 address info.
131     typedef otHistoryTrackerMulticastAddressInfo MulticastAddressInfo; ///< Multicast IPv6 address info.
132     typedef otHistoryTrackerMessageInfo          MessageInfo;          ///< RX/TX IPv6 message info.
133     typedef otHistoryTrackerNeighborInfo         NeighborInfo;         ///< Neighbor info.
134     typedef otHistoryTrackerRouterInfo           RouterInfo;           ///< Router info.
135     typedef otHistoryTrackerOnMeshPrefixInfo     OnMeshPrefixInfo;     ///< Network Data on mesh prefix info.
136     typedef otHistoryTrackerExternalRouteInfo    ExternalRouteInfo;    ///< Network Data external route info
137 
138     /**
139      * Initializes the `HistoryTracker`.
140      *
141      * @param[in]  aInstance     A reference to the OpenThread instance.
142      */
143     explicit HistoryTracker(Instance &aInstance);
144 
145     /**
146      * Iterates over the entries in the network info history list.
147      *
148      * @param[in,out] aIterator  An iterator. MUST be initialized.
149      * @param[out]    aEntryAge  A reference to a variable to output the entry's age.
150      *                           Age is provided as the duration (in milliseconds) from when entry was recorded to
151      *                           @p aIterator initialization time. It is set to `kMaxAge` for entries older than max
152      *                           age.
153      *
154      * @returns A pointer to `NetworkInfo` entry or `nullptr` if no more entries in the list.
155      */
IterateNetInfoHistory(Iterator & aIterator,uint32_t & aEntryAge) const156     const NetworkInfo *IterateNetInfoHistory(Iterator &aIterator, uint32_t &aEntryAge) const
157     {
158         return mNetInfoHistory.Iterate(aIterator, aEntryAge);
159     }
160 
161     /**
162      * Iterates over the entries in the unicast address history list.
163      *
164      * @param[in,out] aIterator  An iterator. MUST be initialized.
165      * @param[out]    aEntryAge  A reference to a variable to output the entry's age.
166      *                           Age is provided as the duration (in milliseconds) from when entry was recorded to
167      *                           @p aIterator initialization time. It is set to `kMaxAge` for entries older than max
168      *                           age.
169      *
170      * @returns A pointer to `UnicastAddress` entry or `nullptr` if no more entries in the list.
171      */
IterateUnicastAddressHistory(Iterator & aIterator,uint32_t & aEntryAge) const172     const UnicastAddressInfo *IterateUnicastAddressHistory(Iterator &aIterator, uint32_t &aEntryAge) const
173     {
174         return mUnicastAddressHistory.Iterate(aIterator, aEntryAge);
175     }
176 
177     /**
178      * Iterates over the entries in the multicast address history list.
179      *
180      * @param[in,out] aIterator  An iterator. MUST be initialized.
181      * @param[out]    aEntryAge  A reference to a variable to output the entry's age.
182      *                           Age is provided as the duration (in milliseconds) from when entry was recorded to
183      *                           @p aIterator initialization time. It is set to `kMaxAge` for entries older than max
184      *                           age.
185      *
186      * @returns A pointer to `MulticastAddress` entry or `nullptr` if no more entries in the list.
187      */
IterateMulticastAddressHistory(Iterator & aIterator,uint32_t & aEntryAge) const188     const MulticastAddressInfo *IterateMulticastAddressHistory(Iterator &aIterator, uint32_t &aEntryAge) const
189     {
190         return mMulticastAddressHistory.Iterate(aIterator, aEntryAge);
191     }
192 
193     /**
194      * Iterates over the entries in the RX history list.
195      *
196      * @param[in,out] aIterator  An iterator. MUST be initialized.
197      * @param[out]    aEntryAge  A reference to a variable to output the entry's age.
198      *                           Age is provided as the duration (in milliseconds) from when entry was recorded to
199      *                           @p aIterator initialization time. It is set to `kMaxAge` for entries older than max
200      *                           age.
201      *
202      * @returns A pointer to `MessageInfo` entry or `nullptr` if no more entries in the list.
203      */
IterateRxHistory(Iterator & aIterator,uint32_t & aEntryAge) const204     const MessageInfo *IterateRxHistory(Iterator &aIterator, uint32_t &aEntryAge) const
205     {
206         return mRxHistory.Iterate(aIterator, aEntryAge);
207     }
208 
209     /**
210      * Iterates over the entries in the TX history list.
211      *
212      * @param[in,out] aIterator  An iterator. MUST be initialized.
213      * @param[out]    aEntryAge  A reference to a variable to output the entry's age.
214      *                           Age is provided as the duration (in milliseconds) from when entry was recorded to
215      *                           @p aIterator initialization time. It is set to `kMaxAge` for entries older than max
216      *                           age.
217      *
218      * @returns A pointer to `MessageInfo` entry or `nullptr` if no more entries in the list.
219      */
IterateTxHistory(Iterator & aIterator,uint32_t & aEntryAge) const220     const MessageInfo *IterateTxHistory(Iterator &aIterator, uint32_t &aEntryAge) const
221     {
222         return mTxHistory.Iterate(aIterator, aEntryAge);
223     }
224 
IterateNeighborHistory(Iterator & aIterator,uint32_t & aEntryAge) const225     const NeighborInfo *IterateNeighborHistory(Iterator &aIterator, uint32_t &aEntryAge) const
226     {
227         return mNeighborHistory.Iterate(aIterator, aEntryAge);
228     }
229 
IterateRouterHistory(Iterator & aIterator,uint32_t & aEntryAge) const230     const RouterInfo *IterateRouterHistory(Iterator &aIterator, uint32_t &aEntryAge) const
231     {
232         return mRouterHistory.Iterate(aIterator, aEntryAge);
233     }
234 
IterateOnMeshPrefixHistory(Iterator & aIterator,uint32_t & aEntryAge) const235     const OnMeshPrefixInfo *IterateOnMeshPrefixHistory(Iterator &aIterator, uint32_t &aEntryAge) const
236     {
237         return mOnMeshPrefixHistory.Iterate(aIterator, aEntryAge);
238     }
239 
IterateExternalRouteHistory(Iterator & aIterator,uint32_t & aEntryAge) const240     const ExternalRouteInfo *IterateExternalRouteHistory(Iterator &aIterator, uint32_t &aEntryAge) const
241     {
242         return mExternalRouteHistory.Iterate(aIterator, aEntryAge);
243     }
244 
245     /**
246      * Converts a given entry age to a human-readable string.
247      *
248      * The entry age string follows the format "<hh>:<mm>:<ss>.<mmmm>" for hours, minutes, seconds and millisecond
249      * (if shorter than one day) or "<dd> days <hh>:<mm>:<ss>.<mmmm>" (if longer than one day).
250      *
251      * If the resulting string does not fit in @p aBuffer (within its @p aSize characters), the string will be
252      * truncated but the outputted string is always null-terminated.
253      *
254      * @param[in]  aEntryAge The entry age (duration in msec).
255      * @param[out] aBuffer   A pointer to a char array to output the string (MUST NOT be NULL).
256      * @param[in]  aSize     The size of @p aBuffer (in bytes). Recommended to use `OT_IP6_ADDRESS_STRING_SIZE`.
257      */
258     static void EntryAgeToString(uint32_t aEntryAge, char *aBuffer, uint16_t aSize);
259 
260 private:
261     // `Timestamp` uses `uint32_t` value. `2^32` msec is 49 days, 17
262     // hours, 2 minutes and 47 seconds and 296 msec. We use 49 days
263     // as `kMaxAge` and check for aged entries every 16 hours.
264 
265     static constexpr uint32_t kAgeCheckPeriod = 16 * Time::kOneHourInMsec;
266 
267     static constexpr uint16_t kNetInfoListSize       = OPENTHREAD_CONFIG_HISTORY_TRACKER_NET_INFO_LIST_SIZE;
268     static constexpr uint16_t kUnicastAddrListSize   = OPENTHREAD_CONFIG_HISTORY_TRACKER_UNICAST_ADDRESS_LIST_SIZE;
269     static constexpr uint16_t kMulticastAddrListSize = OPENTHREAD_CONFIG_HISTORY_TRACKER_MULTICAST_ADDRESS_LIST_SIZE;
270     static constexpr uint16_t kRxListSize            = OPENTHREAD_CONFIG_HISTORY_TRACKER_RX_LIST_SIZE;
271     static constexpr uint16_t kTxListSize            = OPENTHREAD_CONFIG_HISTORY_TRACKER_TX_LIST_SIZE;
272     static constexpr uint16_t kNeighborListSize      = OPENTHREAD_CONFIG_HISTORY_TRACKER_NEIGHBOR_LIST_SIZE;
273     static constexpr uint16_t kRouterListSize        = OPENTHREAD_CONFIG_HISTORY_TRACKER_ROUTER_LIST_SIZE;
274     static constexpr uint16_t kOnMeshPrefixListSize  = OPENTHREAD_CONFIG_HISTORY_TRACKER_ON_MESH_PREFIX_LIST_SIZE;
275     static constexpr uint16_t kExternalRouteListSize = OPENTHREAD_CONFIG_HISTORY_TRACKER_EXTERNAL_ROUTE_LIST_SIZE;
276 
277     typedef otHistoryTrackerAddressEvent AddressEvent;
278 
279     static constexpr AddressEvent kAddressAdded   = OT_HISTORY_TRACKER_ADDRESS_EVENT_ADDED;
280     static constexpr AddressEvent kAddressRemoved = OT_HISTORY_TRACKER_ADDRESS_EVENT_REMOVED;
281 
282     static constexpr uint16_t kInvalidRloc16 = Mle::kInvalidRloc16;
283 
284     typedef otHistoryTrackerNeighborEvent NeighborEvent;
285 
286     static constexpr NeighborEvent kNeighborAdded     = OT_HISTORY_TRACKER_NEIGHBOR_EVENT_ADDED;
287     static constexpr NeighborEvent kNeighborRemoved   = OT_HISTORY_TRACKER_NEIGHBOR_EVENT_REMOVED;
288     static constexpr NeighborEvent kNeighborChanged   = OT_HISTORY_TRACKER_NEIGHBOR_EVENT_CHANGED;
289     static constexpr NeighborEvent kNeighborRestoring = OT_HISTORY_TRACKER_NEIGHBOR_EVENT_RESTORING;
290 
291     typedef otHistoryTrackerRouterEvent RouterEvent;
292 
293     static constexpr RouterEvent kRouterAdded          = OT_HISTORY_TRACKER_ROUTER_EVENT_ADDED;
294     static constexpr RouterEvent kRouterRemoved        = OT_HISTORY_TRACKER_ROUTER_EVENT_REMOVED;
295     static constexpr RouterEvent kRouterNextHopChanged = OT_HISTORY_TRACKER_ROUTER_EVENT_NEXT_HOP_CHANGED;
296     static constexpr RouterEvent kRouterCostChanged    = OT_HISTORY_TRACKER_ROUTER_EVENT_COST_CHANGED;
297 
298     typedef otHistoryTrackerNetDataEvent NetDataEvent;
299 
300     static constexpr NetDataEvent kNetDataEntryAdded   = OT_HISTORY_TRACKER_NET_DATA_ENTRY_ADDED;
301     static constexpr NetDataEvent kNetDataEntryRemoved = OT_HISTORY_TRACKER_NET_DATA_ENTRY_REMOVED;
302 
303     class Timestamp
304     {
305     public:
306         void     SetToNow(void);
307         uint32_t GetDurationTill(TimeMilli aTime) const;
IsDistantPast(void) const308         bool     IsDistantPast(void) const { return (mTime.GetValue() == kDistantPast); }
MarkAsDistantPast(void)309         void     MarkAsDistantPast(void) { return mTime.SetValue(kDistantPast); }
310 
311     private:
312         static constexpr uint32_t kDistantPast = 0;
313 
314         TimeMilli mTime;
315     };
316 
317     // An ordered list of timestamped items (base class of `EntryList<Entry, kSize>`).
318     class List : private NonCopyable
319     {
320     public:
321         void     Clear(void);
GetSize(void) const322         uint16_t GetSize(void) const { return mSize; }
323 
324     protected:
325         List(void);
326         uint16_t Add(uint16_t aMaxSize, Timestamp aTimestamps[]);
327         void     UpdateAgedEntries(uint16_t aMaxSize, Timestamp aTimestamps[]);
328         uint16_t MapEntryNumberToListIndex(uint16_t aEntryNumber, uint16_t aMaxSize) const;
329         Error    Iterate(uint16_t        aMaxSize,
330                          const Timestamp aTimestamps[],
331                          Iterator       &aIterator,
332                          uint16_t       &aListIndex,
333                          uint32_t       &aEntryAge) const;
334 
335     private:
336         uint16_t mStartIndex;
337         uint16_t mSize;
338     };
339 
340     // A history list (with given max size) of timestamped `Entry` items.
341     template <typename Entry, uint16_t kMaxSize> class EntryList : public List
342     {
343     public:
344         // Adds a new entry to the list or overwrites the oldest entry
345         // if list is full. First version returns a pointer to the
346         // new `Entry` (for caller to populate). Second version copies
347         // the given `aEntry`.
AddNewEntry(void)348         Entry *AddNewEntry(void) { return &mEntries[Add(kMaxSize, mTimestamps)]; }
AddNewEntry(const Entry & aEntry)349         void   AddNewEntry(const Entry &aEntry) { mEntries[Add(kMaxSize, mTimestamps)] = aEntry; }
350 
UpdateAgedEntries(void)351         void UpdateAgedEntries(void) { List::UpdateAgedEntries(kMaxSize, mTimestamps); }
352 
Iterate(Iterator & aIterator,uint32_t & aEntryAge) const353         const Entry *Iterate(Iterator &aIterator, uint32_t &aEntryAge) const
354         {
355             uint16_t index;
356 
357             return (List::Iterate(kMaxSize, mTimestamps, aIterator, index, aEntryAge) == kErrorNone) ? &mEntries[index]
358                                                                                                      : nullptr;
359         }
360 
361     private:
362         Timestamp mTimestamps[kMaxSize];
363         Entry     mEntries[kMaxSize];
364     };
365 
366     // Partial specialization for `kMaxSize` zero.
367     template <typename Entry> class EntryList<Entry, 0> : private NonCopyable
368     {
369     public:
Clear(void)370         void         Clear(void) {}
GetSize(void) const371         uint16_t     GetSize(void) const { return 0; }
AddNewEntry(void)372         Entry       *AddNewEntry(void) { return nullptr; }
AddNewEntry(const Entry &)373         void         AddNewEntry(const Entry &) {}
Iterate(Iterator &,uint32_t &) const374         const Entry *Iterate(Iterator &, uint32_t &) const { return nullptr; }
RemoveAgedEntries(void)375         void         RemoveAgedEntries(void) {}
376     };
377 
378     enum MessageType : uint8_t
379     {
380         kRxMessage,
381         kTxMessage,
382     };
383 
RecordRxMessage(const Message & aMessage,const Mac::Address & aMacSource)384     void RecordRxMessage(const Message &aMessage, const Mac::Address &aMacSource)
385     {
386         RecordMessage(aMessage, aMacSource, kRxMessage);
387     }
388 
RecordTxMessage(const Message & aMessage,const Mac::Address & aMacDest)389     void RecordTxMessage(const Message &aMessage, const Mac::Address &aMacDest)
390     {
391         RecordMessage(aMessage, aMacDest, kTxMessage);
392     }
393 
394     void RecordNetworkInfo(void);
395     void RecordMessage(const Message &aMessage, const Mac::Address &aMacAddress, MessageType aType);
396     void RecordNeighborEvent(NeighborTable::Event aEvent, const NeighborTable::EntryInfo &aInfo);
397     void RecordAddressEvent(Ip6::Netif::AddressEvent aEvent, const Ip6::Netif::UnicastAddress &aUnicastAddress);
398     void RecordAddressEvent(Ip6::Netif::AddressEvent            aEvent,
399                             const Ip6::Netif::MulticastAddress &aMulticastAddress,
400                             Ip6::Netif::AddressOrigin           aAddressOrigin);
401     void HandleNotifierEvents(Events aEvents);
402     void HandleTimer(void);
403 #if OPENTHREAD_FTD
404     void RecordRouterTableChange(void);
405 #endif
406 #if OPENTHREAD_CONFIG_HISTORY_TRACKER_NET_DATA
407     void RecordNetworkDataChange(void);
408     void RecordOnMeshPrefixEvent(NetDataEvent aEvent, const NetworkData::OnMeshPrefixConfig &aPrefix);
409     void RecordExternalRouteEvent(NetDataEvent aEvent, const NetworkData::ExternalRouteConfig &aRoute);
410 #endif
411 
412     using TrackerTimer = TimerMilliIn<HistoryTracker, &HistoryTracker::HandleTimer>;
413 
414     EntryList<NetworkInfo, kNetInfoListSize>                mNetInfoHistory;
415     EntryList<UnicastAddressInfo, kUnicastAddrListSize>     mUnicastAddressHistory;
416     EntryList<MulticastAddressInfo, kMulticastAddrListSize> mMulticastAddressHistory;
417     EntryList<MessageInfo, kRxListSize>                     mRxHistory;
418     EntryList<MessageInfo, kTxListSize>                     mTxHistory;
419     EntryList<NeighborInfo, kNeighborListSize>              mNeighborHistory;
420     EntryList<RouterInfo, kRouterListSize>                  mRouterHistory;
421     EntryList<OnMeshPrefixInfo, kOnMeshPrefixListSize>      mOnMeshPrefixHistory;
422     EntryList<ExternalRouteInfo, kExternalRouteListSize>    mExternalRouteHistory;
423 
424     TrackerTimer mTimer;
425 
426 #if OPENTHREAD_FTD && (OPENTHREAD_CONFIG_HISTORY_TRACKER_ROUTER_LIST_SIZE > 0)
427     struct RouterEntry
428     {
429         bool    mIsAllocated : 1;
430         uint8_t mNextHop : 6;
431         uint8_t mPathCost : 4;
432     };
433 
434     RouterEntry mRouterEntries[Mle::kMaxRouterId + 1];
435 #endif
436 
437 #if OPENTHREAD_CONFIG_HISTORY_TRACKER_NET_DATA
438     NetworkData::MutableNetworkData mPreviousNetworkData;
439 
440     uint8_t mNetworkDataTlvBuffer[NetworkData::NetworkData::kMaxSize];
441 #endif
442 };
443 
444 } // namespace Utils
445 
446 DefineCoreType(otHistoryTrackerIterator, Utils::HistoryTracker::Iterator);
447 DefineCoreType(otHistoryTrackerNetworkInfo, Utils::HistoryTracker::NetworkInfo);
448 DefineCoreType(otHistoryTrackerMessageInfo, Utils::HistoryTracker::MessageInfo);
449 DefineCoreType(otHistoryTrackerNeighborInfo, Utils::HistoryTracker::NeighborInfo);
450 DefineCoreType(otHistoryTrackerRouterInfo, Utils::HistoryTracker::RouterInfo);
451 DefineCoreType(otHistoryTrackerOnMeshPrefixInfo, Utils::HistoryTracker::OnMeshPrefixInfo);
452 DefineCoreType(otHistoryTrackerExternalRouteInfo, Utils::HistoryTracker::ExternalRouteInfo);
453 
454 } // namespace ot
455 
456 #endif // OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
457 
458 #endif // HISTORY_TRACKER_HPP_
459