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