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