• 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  */
26 
27 #ifndef OPENTHREAD_HISTORY_TRACKER_H_
28 #define OPENTHREAD_HISTORY_TRACKER_H_
29 
30 #include <openthread/instance.h>
31 #include <openthread/ip6.h>
32 #include <openthread/netdata.h>
33 #include <openthread/thread.h>
34 
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38 
39 /**
40  * @addtogroup api-history-tracker
41  *
42  * @brief
43  *   Records the history of different events, for example RX and TX messages or network info changes. All tracked
44  *   entries are timestamped.
45  *
46  * The functions in this module are available when `OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE` is enabled.
47  *
48  * @{
49  */
50 
51 /**
52  * This constant specifies the maximum age of entries which is 49 days (in msec).
53  *
54  * Entries older than the max age will give this value as their age.
55  */
56 #define OT_HISTORY_TRACKER_MAX_AGE (49 * 24 * 60 * 60 * 1000u)
57 
58 #define OT_HISTORY_TRACKER_ENTRY_AGE_STRING_SIZE 21 ///< Recommended size for string representation of an entry age.
59 
60 /**
61  * Represents an iterator to iterate through a history list.
62  *
63  * The fields in this type are opaque (intended for use by OpenThread core) and therefore should not be accessed/used
64  * by caller.
65  *
66  * Before using an iterator, it MUST be initialized using `otHistoryTrackerInitIterator()`,
67  */
68 typedef struct otHistoryTrackerIterator
69 {
70     uint32_t mData32;
71     uint16_t mData16;
72 } otHistoryTrackerIterator;
73 
74 /**
75  * Represents Thread network info.
76  */
77 typedef struct otHistoryTrackerNetworkInfo
78 {
79     otDeviceRole     mRole;        ///< Device Role.
80     otLinkModeConfig mMode;        ///< Device Mode.
81     uint16_t         mRloc16;      ///< Device RLOC16.
82     uint32_t         mPartitionId; ///< Partition ID (valid when attached).
83 } otHistoryTrackerNetworkInfo;
84 
85 /**
86  * Defines the events for an IPv6 (unicast or multicast) address info (i.e., whether address is added
87  * or removed).
88  */
89 typedef enum
90 {
91     OT_HISTORY_TRACKER_ADDRESS_EVENT_ADDED   = 0, ///< Address is added.
92     OT_HISTORY_TRACKER_ADDRESS_EVENT_REMOVED = 1, ///< Address is removed.
93 } otHistoryTrackerAddressEvent;
94 
95 /**
96  * Represent a unicast IPv6 address info.
97  */
98 typedef struct otHistoryTrackerUnicastAddressInfo
99 {
100     otIp6Address                 mAddress;       ///< The unicast IPv6 address.
101     uint8_t                      mPrefixLength;  ///< The Prefix length (in bits).
102     uint8_t                      mAddressOrigin; ///< The address origin (`OT_ADDRESS_ORIGIN_*` constants).
103     otHistoryTrackerAddressEvent mEvent;         ///< Indicates the event (address is added/removed).
104     uint8_t                      mScope : 4;     ///< The IPv6 scope.
105     bool                         mPreferred : 1; ///< If the address is preferred.
106     bool                         mValid : 1;     ///< If the address is valid.
107     bool                         mRloc : 1;      ///< If the address is an RLOC.
108 } otHistoryTrackerUnicastAddressInfo;
109 
110 /**
111  * Represent an IPv6 multicast address info.
112  */
113 typedef struct otHistoryTrackerMulticastAddressInfo
114 {
115     otIp6Address                 mAddress;       ///< The IPv6 multicast address.
116     uint8_t                      mAddressOrigin; ///< The address origin (`OT_ADDRESS_ORIGIN_*` constants).
117     otHistoryTrackerAddressEvent mEvent;         ///< Indicates the event (address is added/removed).
118 } otHistoryTrackerMulticastAddressInfo;
119 
120 /**
121  * Constants representing message priority used in `otHistoryTrackerMessageInfo` struct.
122  */
123 enum
124 {
125     OT_HISTORY_TRACKER_MSG_PRIORITY_LOW    = OT_MESSAGE_PRIORITY_LOW,      ///< Low priority level.
126     OT_HISTORY_TRACKER_MSG_PRIORITY_NORMAL = OT_MESSAGE_PRIORITY_NORMAL,   ///< Normal priority level.
127     OT_HISTORY_TRACKER_MSG_PRIORITY_HIGH   = OT_MESSAGE_PRIORITY_HIGH,     ///< High priority level.
128     OT_HISTORY_TRACKER_MSG_PRIORITY_NET    = OT_MESSAGE_PRIORITY_HIGH + 1, ///< Network Control priority level.
129 };
130 
131 /**
132  * Represents a RX/TX IPv6 message info.
133  *
134  * Some of the fields in this struct are applicable to a RX message or a TX message only, e.g., `mAveRxRss` is the
135  * average RSS of all fragment frames that form a received message and is only applicable for a RX message.
136  */
137 typedef struct otHistoryTrackerMessageInfo
138 {
139     uint16_t   mPayloadLength;       ///< IPv6 payload length (exclude IP6 header itself).
140     uint16_t   mNeighborRloc16;      ///< RLOC16 of neighbor which sent/received the msg (`0xfffe` if no RLOC16).
141     otSockAddr mSource;              ///< Source IPv6 address and port (if UDP/TCP)
142     otSockAddr mDestination;         ///< Destination IPv6 address and port (if UDP/TCP).
143     uint16_t   mChecksum;            ///< Message checksum (valid only for UDP/TCP/ICMP6).
144     uint8_t    mIpProto;             ///< IP Protocol number (`OT_IP6_PROTO_*` enumeration).
145     uint8_t    mIcmp6Type;           ///< ICMP6 type if msg is ICMP6, zero otherwise (`OT_ICMP6_TYPE_*` enumeration).
146     int8_t     mAveRxRss;            ///< RSS of received message or OT_RADIO_INVALID_RSSI if not known.
147     bool       mLinkSecurity : 1;    ///< Indicates whether msg used link security.
148     bool       mTxSuccess : 1;       ///< Indicates TX success (e.g., ack received). Applicable for TX msg only.
149     uint8_t    mPriority : 2;        ///< Message priority (`OT_HISTORY_TRACKER_MSG_PRIORITY_*` enumeration).
150     bool       mRadioIeee802154 : 1; ///< Indicates whether msg was sent/received over a 15.4 radio link.
151     bool       mRadioTrelUdp6 : 1;   ///< Indicates whether msg was sent/received over a TREL radio link.
152 } otHistoryTrackerMessageInfo;
153 
154 /**
155  * Defines the events in a neighbor info (i.e. whether neighbor is added, removed, or changed).
156  *
157  * Event `OT_HISTORY_TRACKER_NEIGHBOR_EVENT_RESTORING` is applicable to child neighbors only. It is triggered after
158  * the device (re)starts and when the previous children list is retrieved from non-volatile settings and the device
159  * tries to restore connection to them.
160  */
161 typedef enum
162 {
163     OT_HISTORY_TRACKER_NEIGHBOR_EVENT_ADDED     = 0, ///< Neighbor is added.
164     OT_HISTORY_TRACKER_NEIGHBOR_EVENT_REMOVED   = 1, ///< Neighbor is removed.
165     OT_HISTORY_TRACKER_NEIGHBOR_EVENT_CHANGED   = 2, ///< Neighbor changed (e.g., device mode flags changed).
166     OT_HISTORY_TRACKER_NEIGHBOR_EVENT_RESTORING = 3, ///< Neighbor is being restored (applicable to child only).
167 } otHistoryTrackerNeighborEvent;
168 
169 /**
170  * Represents a neighbor info.
171  */
172 typedef struct otHistoryTrackerNeighborInfo
173 {
174     otExtAddress mExtAddress;           ///< Neighbor's Extended Address.
175     uint16_t     mRloc16;               ///< Neighbor's RLOC16.
176     int8_t       mAverageRssi;          ///< Average RSSI of rx frames from neighbor at the time of recording entry.
177     uint8_t      mEvent : 2;            ///< Indicates the event (`OT_HISTORY_TRACKER_NEIGHBOR_EVENT_*` enumeration).
178     bool         mRxOnWhenIdle : 1;     ///< Rx-on-when-idle.
179     bool         mFullThreadDevice : 1; ///< Full Thread Device.
180     bool         mFullNetworkData : 1;  ///< Full Network Data.
181     bool         mIsChild : 1;          ///< Indicates whether or not the neighbor is a child.
182 } otHistoryTrackerNeighborInfo;
183 
184 /**
185  * Defines the events in a router info (i.e. whether router is added, removed, or changed).
186  */
187 typedef enum
188 {
189     OT_HISTORY_TRACKER_ROUTER_EVENT_ADDED            = 0, ///< Router is added (router ID allocated).
190     OT_HISTORY_TRACKER_ROUTER_EVENT_REMOVED          = 1, ///< Router entry is removed (router ID released).
191     OT_HISTORY_TRACKER_ROUTER_EVENT_NEXT_HOP_CHANGED = 2, ///< Router entry next hop and cost changed.
192     OT_HISTORY_TRACKER_ROUTER_EVENT_COST_CHANGED     = 3, ///< Router entry path cost changed (next hop as before).
193 } otHistoryTrackerRouterEvent;
194 
195 #define OT_HISTORY_TRACKER_NO_NEXT_HOP 63 ///< No next hop - For `mNextHop` in `otHistoryTrackerRouterInfo`.
196 
197 #define OT_HISTORY_TRACKER_INFINITE_PATH_COST 0 ///< Infinite path cost - used in `otHistoryTrackerRouterInfo`.
198 
199 /**
200  * Represents a router table entry event.
201  */
202 typedef struct otHistoryTrackerRouterInfo
203 {
204     uint8_t mEvent : 2;       ///< Router entry event (`OT_HISTORY_TRACKER_ROUTER_EVENT_*` enumeration).
205     uint8_t mRouterId : 6;    ///< Router ID.
206     uint8_t mNextHop;         ///< Next Hop Router ID - `OT_HISTORY_TRACKER_NO_NEXT_HOP` if no next hop.
207     uint8_t mOldPathCost : 4; ///< Old path cost - `OT_HISTORY_TRACKER_INFINITE_PATH_COST` if infinite or unknown.
208     uint8_t mPathCost : 4;    ///< New path cost - `OT_HISTORY_TRACKER_INFINITE_PATH_COST` if infinite or unknown.
209 } otHistoryTrackerRouterInfo;
210 
211 /**
212  * Defines the events for a Network Data entry (i.e., whether an entry is added or removed).
213  */
214 typedef enum
215 {
216     OT_HISTORY_TRACKER_NET_DATA_ENTRY_ADDED   = 0, ///< Network data entry is added.
217     OT_HISTORY_TRACKER_NET_DATA_ENTRY_REMOVED = 1, ///< Network data entry is removed.
218 } otHistoryTrackerNetDataEvent;
219 
220 /**
221  * Represent a Network Data on mesh prefix info.
222  */
223 typedef struct otHistoryTrackerOnMeshPrefixInfo
224 {
225     otBorderRouterConfig         mPrefix; ///< The on mesh prefix entry.
226     otHistoryTrackerNetDataEvent mEvent;  ///< Indicates the event (added/removed).
227 } otHistoryTrackerOnMeshPrefixInfo;
228 
229 /**
230  * Represent a Network Data extern route info.
231  */
232 typedef struct otHistoryTrackerExternalRouteInfo
233 {
234     otExternalRouteConfig        mRoute; ///< The external route entry.
235     otHistoryTrackerNetDataEvent mEvent; ///< Indicates the event (added/removed).
236 } otHistoryTrackerExternalRouteInfo;
237 
238 /**
239  * Initializes an `otHistoryTrackerIterator`.
240  *
241  * An iterator MUST be initialized before it is used.
242  *
243  * An iterator can be initialized again to start from the beginning of the list.
244  *
245  * When iterating over entries in a list, to ensure the entry ages are consistent, the age is given relative to the
246  * time the iterator was initialized, i.e., the entry age is provided as the duration (in milliseconds) from the event
247  * (when entry was recorded) to the iterator initialization time.
248  *
249  * @param[in] aIterator  A pointer to the iterator to initialize (MUST NOT be NULL).
250  */
251 void otHistoryTrackerInitIterator(otHistoryTrackerIterator *aIterator);
252 
253 /**
254  * Iterates over the entries in the network info history list.
255  *
256  * @param[in]     aInstance   A pointer to the OpenThread instance.
257  * @param[in,out] aIterator   A pointer to an iterator. MUST be initialized or the behavior is undefined.
258  * @param[out]    aEntryAge   A pointer to a variable to output the entry's age. MUST NOT be NULL.
259  *                            Age is provided as the duration (in milliseconds) from when entry was recorded to
260  *                            @p aIterator initialization time. It is set to `OT_HISTORY_TRACKER_MAX_AGE` for entries
261  *                            older than max age.
262  *
263  * @returns A pointer to `otHistoryTrackerNetworkInfo` entry or `NULL` if no more entries in the list.
264  */
265 const otHistoryTrackerNetworkInfo *otHistoryTrackerIterateNetInfoHistory(otInstance               *aInstance,
266                                                                          otHistoryTrackerIterator *aIterator,
267                                                                          uint32_t                 *aEntryAge);
268 
269 /**
270  * Iterates over the entries in the unicast address history list.
271  *
272  * @param[in]     aInstance  A pointer to the OpenThread instance.
273  * @param[in,out] aIterator  A pointer to an iterator. MUST be initialized or the behavior is undefined.
274  * @param[out]    aEntryAge  A pointer to a variable to output the entry's age. MUST NOT be NULL.
275  *                           Age is provided as the duration (in milliseconds) from when entry was recorded to
276  *                           @p aIterator initialization time. It is set to `OT_HISTORY_TRACKER_MAX_AGE` for entries
277  *                           older than max age.
278  *
279  * @returns A pointer to `otHistoryTrackerUnicastAddressInfo` entry or `NULL` if no more entries in the list.
280  */
281 const otHistoryTrackerUnicastAddressInfo *otHistoryTrackerIterateUnicastAddressHistory(
282     otInstance               *aInstance,
283     otHistoryTrackerIterator *aIterator,
284     uint32_t                 *aEntryAge);
285 
286 /**
287  * Iterates over the entries in the multicast address history list.
288  *
289  * @param[in]     aInstance  A pointer to the OpenThread instance.
290  * @param[in,out] aIterator  A pointer to an iterator. MUST be initialized or the behavior is undefined.
291  * @param[out]    aEntryAge  A pointer to a variable to output the entry's age. MUST NOT be NULL.
292  *                           Age is provided as the duration (in milliseconds) from when entry was recorded to
293  *                           @p aIterator initialization time. It is set to `OT_HISTORY_TRACKER_MAX_AGE` for entries
294  *                           older than max age.
295  *
296  * @returns A pointer to `otHistoryTrackerMulticastAddressInfo` entry or `NULL` if no more entries in the list.
297  */
298 const otHistoryTrackerMulticastAddressInfo *otHistoryTrackerIterateMulticastAddressHistory(
299     otInstance               *aInstance,
300     otHistoryTrackerIterator *aIterator,
301     uint32_t                 *aEntryAge);
302 
303 /**
304  * Iterates over the entries in the RX message history list.
305  *
306  * @param[in]     aInstance  A pointer to the OpenThread instance.
307  * @param[in,out] aIterator  A pointer to an iterator. MUST be initialized or the behavior is undefined.
308  * @param[out]    aEntryAge  A pointer to a variable to output the entry's age. MUST NOT be NULL.
309  *                           Age is provided as the duration (in milliseconds) from when entry was recorded to
310  *                           @p aIterator initialization time. It is set to `OT_HISTORY_TRACKER_MAX_AGE` for entries
311  *                           older than max age.
312  *
313  * @returns The `otHistoryTrackerMessageInfo` entry or `NULL` if no more entries in the list.
314  */
315 const otHistoryTrackerMessageInfo *otHistoryTrackerIterateRxHistory(otInstance               *aInstance,
316                                                                     otHistoryTrackerIterator *aIterator,
317                                                                     uint32_t                 *aEntryAge);
318 
319 /**
320  * Iterates over the entries in the TX message history list.
321  *
322  * @param[in]     aInstance  A pointer to the OpenThread instance.
323  * @param[in,out] aIterator  A pointer to an iterator. MUST be initialized or the behavior is undefined.
324  * @param[out]    aEntryAge  A pointer to a variable to output the entry's age. MUST NOT be NULL.
325  *                           Age is provided as the duration (in milliseconds) from when entry was recorded to
326  *                           @p aIterator initialization time. It is set to `OT_HISTORY_TRACKER_MAX_AGE` for entries
327  *                           older than max age.
328  *
329  * @returns The `otHistoryTrackerMessageInfo` entry or `NULL` if no more entries in the list.
330  */
331 const otHistoryTrackerMessageInfo *otHistoryTrackerIterateTxHistory(otInstance               *aInstance,
332                                                                     otHistoryTrackerIterator *aIterator,
333                                                                     uint32_t                 *aEntryAge);
334 
335 /**
336  * Iterates over the entries in the neighbor history list.
337  *
338  * @param[in]     aInstance  A pointer to the OpenThread instance.
339  * @param[in,out] aIterator  A pointer to an iterator. MUST be initialized or the behavior is undefined.
340  * @param[out]    aEntryAge  A pointer to a variable to output the entry's age. MUST NOT be NULL.
341  *                           Age is provided as the duration (in milliseconds) from when entry was recorded to
342  *                           @p aIterator initialization time. It is set to `OT_HISTORY_TRACKER_MAX_AGE` for entries
343  *                           older than max age.
344  *
345  * @returns The `otHistoryTrackerNeighborInfo` entry or `NULL` if no more entries in the list.
346  */
347 const otHistoryTrackerNeighborInfo *otHistoryTrackerIterateNeighborHistory(otInstance               *aInstance,
348                                                                            otHistoryTrackerIterator *aIterator,
349                                                                            uint32_t                 *aEntryAge);
350 
351 /**
352  * Iterates over the entries in the router history list.
353  *
354  * @param[in]     aInstance  A pointer to the OpenThread instance.
355  * @param[in,out] aIterator  A pointer to an iterator. MUST be initialized or the behavior is undefined.
356  * @param[out]    aEntryAge  A pointer to a variable to output the entry's age. MUST NOT be NULL.
357  *                           Age is provided as the duration (in milliseconds) from when entry was recorded to
358  *                           @p aIterator initialization time. It is set to `OT_HISTORY_TRACKER_MAX_AGE` for entries
359  *                           older than max age.
360  *
361  * @returns The `otHistoryTrackerRouterInfo` entry or `NULL` if no more entries in the list.
362  */
363 const otHistoryTrackerRouterInfo *otHistoryTrackerIterateRouterHistory(otInstance               *aInstance,
364                                                                        otHistoryTrackerIterator *aIterator,
365                                                                        uint32_t                 *aEntryAge);
366 
367 /**
368  * Iterates over the entries in the Network Data on mesh prefix entry history list.
369  *
370  * @param[in]     aInstance  A pointer to the OpenThread instance.
371  * @param[in,out] aIterator  A pointer to an iterator. MUST be initialized or the behavior is undefined.
372  * @param[out]    aEntryAge  A pointer to a variable to output the entry's age. MUST NOT be NULL.
373  *                           Age is provided as the duration (in milliseconds) from when entry was recorded to
374  *                           @p aIterator initialization time. It is set to `OT_HISTORY_TRACKER_MAX_AGE` for entries
375  *                           older than max age.
376  *
377  * @returns The `otHistoryTrackerOnMeshPrefixInfo` entry or `NULL` if no more entries in the list.
378  */
379 const otHistoryTrackerOnMeshPrefixInfo *otHistoryTrackerIterateOnMeshPrefixHistory(otInstance               *aInstance,
380                                                                                    otHistoryTrackerIterator *aIterator,
381                                                                                    uint32_t                 *aEntryAge);
382 
383 /**
384  * Iterates over the entries in the Network Data external route entry history list.
385  *
386  * @param[in]     aInstance  A pointer to the OpenThread instance.
387  * @param[in,out] aIterator  A pointer to an iterator. MUST be initialized or the behavior is undefined.
388  * @param[out]    aEntryAge  A pointer to a variable to output the entry's age. MUST NOT be NULL.
389  *                           Age is provided as the duration (in milliseconds) from when entry was recorded to
390  *                           @p aIterator initialization time. It is set to `OT_HISTORY_TRACKER_MAX_AGE` for entries
391  *                           older than max age.
392  *
393  * @returns The `otHistoryTrackerExternalRouteInfo` entry or `NULL` if no more entries in the list.
394  */
395 const otHistoryTrackerExternalRouteInfo *otHistoryTrackerIterateExternalRouteHistory(
396     otInstance               *aInstance,
397     otHistoryTrackerIterator *aIterator,
398     uint32_t                 *aEntryAge);
399 
400 /**
401  * Converts a given entry age to a human-readable string.
402  *
403  * The entry age string follows the format `hours:minutes:seconds:milliseconds` (if
404  * shorter than one day) or `days:hours:minutes:seconds`(if longer than one day).
405  *
406  * If the resulting string does not fit in @p aBuffer (within its @p aSize characters), the string will be truncated
407  * but the outputted string is always null-terminated.
408  *
409  * @param[in]  aEntryAge The entry age (duration in msec).
410  * @param[out] aBuffer   A pointer to a char array to output the string (MUST NOT be NULL).
411  * @param[in]  aSize     The size of @p aBuffer. Recommended to use `OT_HISTORY_TRACKER_ENTRY_AGE_STRING_SIZE`.
412  */
413 void otHistoryTrackerEntryAgeToString(uint32_t aEntryAge, char *aBuffer, uint16_t aSize);
414 
415 /**
416  * @}
417  */
418 
419 #ifdef __cplusplus
420 } // extern "C"
421 #endif
422 
423 #endif // OPENTHREAD_HISTORY_TRACKER_H_
424