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