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