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 /** 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 * 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 * 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 * 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 * 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 * 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 * 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_INVALID_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 * 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 * 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 * Defines the events in a router info (i.e. whether router is added, removed, or changed). 197 * 198 */ 199 typedef enum 200 { 201 OT_HISTORY_TRACKER_ROUTER_EVENT_ADDED = 0, ///< Router is added (router ID allocated). 202 OT_HISTORY_TRACKER_ROUTER_EVENT_REMOVED = 1, ///< Router entry is removed (router ID released). 203 OT_HISTORY_TRACKER_ROUTER_EVENT_NEXT_HOP_CHANGED = 2, ///< Router entry next hop and cost changed. 204 OT_HISTORY_TRACKER_ROUTER_EVENT_COST_CHANGED = 3, ///< Router entry path cost changed (next hop as before). 205 } otHistoryTrackerRouterEvent; 206 207 #define OT_HISTORY_TRACKER_NO_NEXT_HOP 63 ///< No next hop - For `mNextHop` in `otHistoryTrackerRouterInfo`. 208 209 #define OT_HISTORY_TRACKER_INFINITE_PATH_COST 0 ///< Infinite path cost - used in `otHistoryTrackerRouterInfo`. 210 211 /** 212 * Represents a router table entry event. 213 * 214 */ 215 typedef struct otHistoryTrackerRouterInfo 216 { 217 uint8_t mEvent : 2; ///< Router entry event (`OT_HISTORY_TRACKER_ROUTER_EVENT_*` enumeration). 218 uint8_t mRouterId : 6; ///< Router ID. 219 uint8_t mNextHop; ///< Next Hop Router ID - `OT_HISTORY_TRACKER_NO_NEXT_HOP` if no next hop. 220 uint8_t mOldPathCost : 4; ///< Old path cost - `OT_HISTORY_TRACKER_INFINITE_PATH_COST` if infinite or unknown. 221 uint8_t mPathCost : 4; ///< New path cost - `OT_HISTORY_TRACKER_INFINITE_PATH_COST` if infinite or unknown. 222 } otHistoryTrackerRouterInfo; 223 224 /** 225 * Defines the events for a Network Data entry (i.e., whether an entry is added or removed). 226 * 227 */ 228 typedef enum 229 { 230 OT_HISTORY_TRACKER_NET_DATA_ENTRY_ADDED = 0, ///< Network data entry is added. 231 OT_HISTORY_TRACKER_NET_DATA_ENTRY_REMOVED = 1, ///< Network data entry is removed. 232 } otHistoryTrackerNetDataEvent; 233 234 /** 235 * Represent a Network Data on mesh prefix info. 236 * 237 */ 238 typedef struct otHistoryTrackerOnMeshPrefixInfo 239 { 240 otBorderRouterConfig mPrefix; ///< The on mesh prefix entry. 241 otHistoryTrackerNetDataEvent mEvent; ///< Indicates the event (added/removed). 242 } otHistoryTrackerOnMeshPrefixInfo; 243 244 /** 245 * Represent a Network Data extern route info. 246 * 247 */ 248 typedef struct otHistoryTrackerExternalRouteInfo 249 { 250 otExternalRouteConfig mRoute; ///< The external route entry. 251 otHistoryTrackerNetDataEvent mEvent; ///< Indicates the event (added/removed). 252 } otHistoryTrackerExternalRouteInfo; 253 254 /** 255 * Initializes an `otHistoryTrackerIterator`. 256 * 257 * An iterator MUST be initialized before it is used. 258 * 259 * An iterator can be initialized again to start from the beginning of the list. 260 * 261 * When iterating over entries in a list, to ensure the entry ages are consistent, the age is given relative to the 262 * time the iterator was initialized, i.e., the entry age is provided as the duration (in milliseconds) from the event 263 * (when entry was recorded) to the iterator initialization time. 264 * 265 * @param[in] aIterator A pointer to the iterator to initialize (MUST NOT be NULL). 266 * 267 */ 268 void otHistoryTrackerInitIterator(otHistoryTrackerIterator *aIterator); 269 270 /** 271 * Iterates over the entries in the network info history list. 272 * 273 * @param[in] aInstance A pointer to the OpenThread instance. 274 * @param[in,out] aIterator A pointer to an iterator. MUST be initialized or the behavior is undefined. 275 * @param[out] aEntryAge A pointer to a variable to output the entry's age. MUST NOT be NULL. 276 * Age is provided as the duration (in milliseconds) from when entry was recorded to 277 * @p aIterator initialization time. It is set to `OT_HISTORY_TRACKER_MAX_AGE` for entries 278 * older than max age. 279 * 280 * @returns A pointer to `otHistoryTrackerNetworkInfo` entry or `NULL` if no more entries in the list. 281 * 282 */ 283 const otHistoryTrackerNetworkInfo *otHistoryTrackerIterateNetInfoHistory(otInstance *aInstance, 284 otHistoryTrackerIterator *aIterator, 285 uint32_t *aEntryAge); 286 287 /** 288 * Iterates over the entries in the unicast address history list. 289 * 290 * @param[in] aInstance A pointer to the OpenThread instance. 291 * @param[in,out] aIterator A pointer to an iterator. MUST be initialized or the behavior is undefined. 292 * @param[out] aEntryAge A pointer to a variable to output the entry's age. MUST NOT be NULL. 293 * Age is provided as the duration (in milliseconds) from when entry was recorded to 294 * @p aIterator initialization time. It is set to `OT_HISTORY_TRACKER_MAX_AGE` for entries 295 * older than max age. 296 * 297 * @returns A pointer to `otHistoryTrackerUnicastAddressInfo` entry or `NULL` if no more entries in the list. 298 * 299 */ 300 const otHistoryTrackerUnicastAddressInfo *otHistoryTrackerIterateUnicastAddressHistory( 301 otInstance *aInstance, 302 otHistoryTrackerIterator *aIterator, 303 uint32_t *aEntryAge); 304 305 /** 306 * Iterates over the entries in the multicast address history list. 307 * 308 * @param[in] aInstance A pointer to the OpenThread instance. 309 * @param[in,out] aIterator A pointer to an iterator. MUST be initialized or the behavior is undefined. 310 * @param[out] aEntryAge A pointer to a variable to output the entry's age. MUST NOT be NULL. 311 * Age is provided as the duration (in milliseconds) from when entry was recorded to 312 * @p aIterator initialization time. It is set to `OT_HISTORY_TRACKER_MAX_AGE` for entries 313 * older than max age. 314 * 315 * @returns A pointer to `otHistoryTrackerMulticastAddressInfo` entry or `NULL` if no more entries in the list. 316 * 317 */ 318 const otHistoryTrackerMulticastAddressInfo *otHistoryTrackerIterateMulticastAddressHistory( 319 otInstance *aInstance, 320 otHistoryTrackerIterator *aIterator, 321 uint32_t *aEntryAge); 322 323 /** 324 * Iterates over the entries in the RX message history list. 325 * 326 * @param[in] aInstance A pointer to the OpenThread instance. 327 * @param[in,out] aIterator A pointer to an iterator. MUST be initialized or the behavior is undefined. 328 * @param[out] aEntryAge A pointer to a variable to output the entry's age. MUST NOT be NULL. 329 * Age is provided as the duration (in milliseconds) from when entry was recorded to 330 * @p aIterator initialization time. It is set to `OT_HISTORY_TRACKER_MAX_AGE` for entries 331 * older than max age. 332 * 333 * @returns The `otHistoryTrackerMessageInfo` entry or `NULL` if no more entries in the list. 334 * 335 */ 336 const otHistoryTrackerMessageInfo *otHistoryTrackerIterateRxHistory(otInstance *aInstance, 337 otHistoryTrackerIterator *aIterator, 338 uint32_t *aEntryAge); 339 340 /** 341 * Iterates over the entries in the TX message history list. 342 * 343 * @param[in] aInstance A pointer to the OpenThread instance. 344 * @param[in,out] aIterator A pointer to an iterator. MUST be initialized or the behavior is undefined. 345 * @param[out] aEntryAge A pointer to a variable to output the entry's age. MUST NOT be NULL. 346 * Age is provided as the duration (in milliseconds) from when entry was recorded to 347 * @p aIterator initialization time. It is set to `OT_HISTORY_TRACKER_MAX_AGE` for entries 348 * older than max age. 349 * 350 * @returns The `otHistoryTrackerMessageInfo` entry or `NULL` if no more entries in the list. 351 * 352 */ 353 const otHistoryTrackerMessageInfo *otHistoryTrackerIterateTxHistory(otInstance *aInstance, 354 otHistoryTrackerIterator *aIterator, 355 uint32_t *aEntryAge); 356 357 /** 358 * Iterates over the entries in the neighbor history list. 359 * 360 * @param[in] aInstance A pointer to the OpenThread instance. 361 * @param[in,out] aIterator A pointer to an iterator. MUST be initialized or the behavior is undefined. 362 * @param[out] aEntryAge A pointer to a variable to output the entry's age. MUST NOT be NULL. 363 * Age is provided as the duration (in milliseconds) from when entry was recorded to 364 * @p aIterator initialization time. It is set to `OT_HISTORY_TRACKER_MAX_AGE` for entries 365 * older than max age. 366 * 367 * @returns The `otHistoryTrackerNeighborInfo` entry or `NULL` if no more entries in the list. 368 * 369 */ 370 const otHistoryTrackerNeighborInfo *otHistoryTrackerIterateNeighborHistory(otInstance *aInstance, 371 otHistoryTrackerIterator *aIterator, 372 uint32_t *aEntryAge); 373 374 /** 375 * Iterates over the entries in the router history list. 376 * 377 * @param[in] aInstance A pointer to the OpenThread instance. 378 * @param[in,out] aIterator A pointer to an iterator. MUST be initialized or the behavior is undefined. 379 * @param[out] aEntryAge A pointer to a variable to output the entry's age. MUST NOT be NULL. 380 * Age is provided as the duration (in milliseconds) from when entry was recorded to 381 * @p aIterator initialization time. It is set to `OT_HISTORY_TRACKER_MAX_AGE` for entries 382 * older than max age. 383 * 384 * @returns The `otHistoryTrackerRouterInfo` entry or `NULL` if no more entries in the list. 385 * 386 */ 387 const otHistoryTrackerRouterInfo *otHistoryTrackerIterateRouterHistory(otInstance *aInstance, 388 otHistoryTrackerIterator *aIterator, 389 uint32_t *aEntryAge); 390 391 /** 392 * Iterates over the entries in the Network Data on mesh prefix entry history list. 393 * 394 * @param[in] aInstance A pointer to the OpenThread instance. 395 * @param[in,out] aIterator A pointer to an iterator. MUST be initialized or the behavior is undefined. 396 * @param[out] aEntryAge A pointer to a variable to output the entry's age. MUST NOT be NULL. 397 * Age is provided as the duration (in milliseconds) from when entry was recorded to 398 * @p aIterator initialization time. It is set to `OT_HISTORY_TRACKER_MAX_AGE` for entries 399 * older than max age. 400 * 401 * @returns The `otHistoryTrackerOnMeshPrefixInfo` entry or `NULL` if no more entries in the list. 402 * 403 */ 404 const otHistoryTrackerOnMeshPrefixInfo *otHistoryTrackerIterateOnMeshPrefixHistory(otInstance *aInstance, 405 otHistoryTrackerIterator *aIterator, 406 uint32_t *aEntryAge); 407 408 /** 409 * Iterates over the entries in the Network Data external route entry history list. 410 * 411 * @param[in] aInstance A pointer to the OpenThread instance. 412 * @param[in,out] aIterator A pointer to an iterator. MUST be initialized or the behavior is undefined. 413 * @param[out] aEntryAge A pointer to a variable to output the entry's age. MUST NOT be NULL. 414 * Age is provided as the duration (in milliseconds) from when entry was recorded to 415 * @p aIterator initialization time. It is set to `OT_HISTORY_TRACKER_MAX_AGE` for entries 416 * older than max age. 417 * 418 * @returns The `otHistoryTrackerExternalRouteInfo` entry or `NULL` if no more entries in the list. 419 * 420 */ 421 const otHistoryTrackerExternalRouteInfo *otHistoryTrackerIterateExternalRouteHistory( 422 otInstance *aInstance, 423 otHistoryTrackerIterator *aIterator, 424 uint32_t *aEntryAge); 425 426 /** 427 * Converts a given entry age to a human-readable string. 428 * 429 * The entry age string follows the format `hours:minutes:seconds:milliseconds` (if 430 * shorter than one day) or `days:hours:minutes:seconds`(if longer than one day). 431 * 432 * If the resulting string does not fit in @p aBuffer (within its @p aSize characters), the string will be truncated 433 * but the outputted string is always null-terminated. 434 * 435 * @param[in] aEntryAge The entry age (duration in msec). 436 * @param[out] aBuffer A pointer to a char array to output the string (MUST NOT be NULL). 437 * @param[in] aSize The size of @p aBuffer. Recommended to use `OT_HISTORY_TRACKER_ENTRY_AGE_STRING_SIZE`. 438 * 439 */ 440 void otHistoryTrackerEntryAgeToString(uint32_t aEntryAge, char *aBuffer, uint16_t aSize); 441 442 /** 443 * @} 444 * 445 */ 446 447 #ifdef __cplusplus 448 } // extern "C" 449 #endif 450 451 #endif // OPENTHREAD_HISTORY_TRACKER_H_ 452