mirror of
https://github.com/espressif/openthread.git
synced 2026-10-02 05:47:40 +00:00
[history-tracker] support tracking netdata prefix and route entries (#7324)
This commit adds a mechanism in `HistoryTracker` to track changes in Thread Network Data maintaining a history of on-mesh prefix and external route entries as they are added or removed by different nodes in Network Data. This commit also adds new `cli history` commands to retrieve the Network Data prefix/route history list and updates the documentation in `cli/README_HISTORY.md`.
This commit is contained in:
@@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
#include <openthread/instance.h>
|
#include <openthread/instance.h>
|
||||||
#include <openthread/ip6.h>
|
#include <openthread/ip6.h>
|
||||||
|
#include <openthread/netdata.h>
|
||||||
#include <openthread/thread.h>
|
#include <openthread/thread.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@@ -191,6 +192,36 @@ typedef struct otHistoryTrackerNeighborInfo
|
|||||||
bool mIsChild : 1; ///< Indicates whether or not the neighbor is a child.
|
bool mIsChild : 1; ///< Indicates whether or not the neighbor is a child.
|
||||||
} otHistoryTrackerNeighborInfo;
|
} otHistoryTrackerNeighborInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This enumeration defines the events for a Network Data entry (i.e., whether an entry is added or removed).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
OT_HISTORY_TRACKER_NET_DATA_ENTRY_ADDED = 0, ///< Network data entry is added.
|
||||||
|
OT_HISTORY_TRACKER_NET_DATA_ENTRY_REMOVED = 1, ///< Network data entry is removed.
|
||||||
|
} otHistoryTrackerNetDataEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This structure represent a Network Data on mesh prefix info.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct otHistoryTrackerOnMeshPrefixInfo
|
||||||
|
{
|
||||||
|
otBorderRouterConfig mPrefix; ///< The on mesh prefix entry.
|
||||||
|
otHistoryTrackerNetDataEvent mEvent; ///< Indicates the event (added/removed).
|
||||||
|
} otHistoryTrackerOnMeshPrefixInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This structure represent a Network Data extern route info.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct otHistoryTrackerExternalRouteInfo
|
||||||
|
{
|
||||||
|
otExternalRouteConfig mRoute; ///< The external route entry.
|
||||||
|
otHistoryTrackerNetDataEvent mEvent; ///< Indicates the event (added/removed).
|
||||||
|
} otHistoryTrackerExternalRouteInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function initializes an `otHistoryTrackerIterator`.
|
* This function initializes an `otHistoryTrackerIterator`.
|
||||||
*
|
*
|
||||||
@@ -311,6 +342,41 @@ const otHistoryTrackerNeighborInfo *otHistoryTrackerIterateNeighborHistory(otIns
|
|||||||
otHistoryTrackerIterator *aIterator,
|
otHistoryTrackerIterator *aIterator,
|
||||||
uint32_t * aEntryAge);
|
uint32_t * aEntryAge);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function iterates over the entries in the Network Data on mesh prefix entry history list.
|
||||||
|
*
|
||||||
|
* @param[in] aInstance A pointer to the OpenThread instance.
|
||||||
|
* @param[inout] aIterator A pointer to an iterator. MUST be initialized or the behavior is undefined.
|
||||||
|
* @param[out] aEntryAge A pointer to a variable to output the entry's age. MUST NOT be NULL.
|
||||||
|
* Age is provided as the duration (in milliseconds) from when entry was recorded to
|
||||||
|
* @p aIterator initialization time. It is set to `OT_HISTORY_TRACKER_MAX_AGE` for entries
|
||||||
|
* older than max age.
|
||||||
|
*
|
||||||
|
* @returns The `otHistoryTrackerOnMeshPrefixInfo` entry or `NULL` if no more entries in the list.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
const otHistoryTrackerOnMeshPrefixInfo *otHistoryTrackerIterateOnMeshPrefixHistory(otInstance * aInstance,
|
||||||
|
otHistoryTrackerIterator *aIterator,
|
||||||
|
uint32_t * aEntryAge);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function iterates over the entries in the Network Data external route entry history list.
|
||||||
|
*
|
||||||
|
* @param[in] aInstance A pointer to the OpenThread instance.
|
||||||
|
* @param[inout] aIterator A pointer to an iterator. MUST be initialized or the behavior is undefined.
|
||||||
|
* @param[out] aEntryAge A pointer to a variable to output the entry's age. MUST NOT be NULL.
|
||||||
|
* Age is provided as the duration (in milliseconds) from when entry was recorded to
|
||||||
|
* @p aIterator initialization time. It is set to `OT_HISTORY_TRACKER_MAX_AGE` for entries
|
||||||
|
* older than max age.
|
||||||
|
*
|
||||||
|
* @returns The `otHistoryTrackerExternalRouteInfo` entry or `NULL` if no more entries in the list.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
const otHistoryTrackerExternalRouteInfo *otHistoryTrackerIterateExternalRouteHistory(
|
||||||
|
otInstance * aInstance,
|
||||||
|
otHistoryTrackerIterator *aIterator,
|
||||||
|
uint32_t * aEntryAge);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function converts a given entry age to a human-readable string.
|
* This function converts a given entry age to a human-readable string.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ extern "C" {
|
|||||||
* @note This number versions both OpenThread platform and user APIs.
|
* @note This number versions both OpenThread platform and user APIs.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#define OPENTHREAD_API_VERSION (185)
|
#define OPENTHREAD_API_VERSION (186)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup api-instance
|
* @addtogroup api-instance
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ Usage : `history [command] ...`
|
|||||||
- [ipmaddr](#ipmaddr)
|
- [ipmaddr](#ipmaddr)
|
||||||
- [neighbor](#neighbor)
|
- [neighbor](#neighbor)
|
||||||
- [netinfo](#netinfo)
|
- [netinfo](#netinfo)
|
||||||
|
- [prefix](#prefix)
|
||||||
|
- [route](#route)
|
||||||
- [rx](#rx)
|
- [rx](#rx)
|
||||||
- [rxtx](#rxtx)
|
- [rxtx](#rxtx)
|
||||||
- [tx](#tx)
|
- [tx](#tx)
|
||||||
@@ -52,6 +54,8 @@ ipaddr
|
|||||||
ipmaddr
|
ipmaddr
|
||||||
neighbor
|
neighbor
|
||||||
netinfo
|
netinfo
|
||||||
|
prefix
|
||||||
|
route
|
||||||
rx
|
rx
|
||||||
rxtx
|
rxtx
|
||||||
tx
|
tx
|
||||||
@@ -243,6 +247,96 @@ Print only the latest 2 entries.
|
|||||||
Done
|
Done
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### prefix
|
||||||
|
|
||||||
|
Usage `history prefix [list] [<num-entries>]`
|
||||||
|
|
||||||
|
Print the Network Data on mesh prefix history. Each item provides:
|
||||||
|
|
||||||
|
- Event (`Added` or `Removed`)
|
||||||
|
- Prefix
|
||||||
|
- Flags
|
||||||
|
- Preference (`high`, `med`, `low`)
|
||||||
|
- RLOC16
|
||||||
|
|
||||||
|
The flags are as follows:
|
||||||
|
|
||||||
|
- `p`: Preferred flag
|
||||||
|
- `a`: Stateless IPv6 Address Autoconfiguration flag
|
||||||
|
- `d`: DHCPv6 IPv6 Address Configuration flag
|
||||||
|
- `c`: DHCPv6 Other Configuration flag
|
||||||
|
- `r`: Default Route flag
|
||||||
|
- `o`: On Mesh flag
|
||||||
|
- `s`: Stable flag
|
||||||
|
- `n`: Nd Dns flag
|
||||||
|
- `D`: Domain Prefix flag
|
||||||
|
|
||||||
|
Print the history as a table.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
> history prefix
|
||||||
|
| Age | Event | Prefix | Flags | Pref | RLOC16 |
|
||||||
|
+----------------------+---------+---------------------------------------------+-----------+------+--------+
|
||||||
|
| 00:00:10.663 | Added | fd00:1111:2222:3333::/64 | paro | med | 0x5400 |
|
||||||
|
| 00:01:02.054 | Removed | fd00:dead:beef:1::/64 | paros | high | 0x5400 |
|
||||||
|
| 00:01:21.136 | Added | fd00:abba:cddd:0::/64 | paos | med | 0x5400 |
|
||||||
|
| 00:01:45.144 | Added | fd00:dead:beef:1::/64 | paros | high | 0x3c00 |
|
||||||
|
| 00:01:50.944 | Added | fd00:dead:beef:1::/64 | paros | high | 0x5400 |
|
||||||
|
| 00:01:59.887 | Added | fd00:dead:beef:1::/64 | paros | med | 0x8800 |
|
||||||
|
Done
|
||||||
|
```
|
||||||
|
|
||||||
|
Print the history as a list.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
> history prefix list
|
||||||
|
00:04:12.487 -> event:Added prefix:fd00:1111:2222:3333::/64 flags:paro pref:med rloc16:0x5400
|
||||||
|
00:05:03.878 -> event:Removed prefix:fd00:dead:beef:1::/64 flags:paros pref:high rloc16:0x5400
|
||||||
|
00:05:22.960 -> event:Added prefix:fd00:abba:cddd:0::/64 flags:paos pref:med rloc16:0x5400
|
||||||
|
00:05:46.968 -> event:Added prefix:fd00:dead:beef:1::/64 flags:paros pref:high rloc16:0x3c00
|
||||||
|
00:05:52.768 -> event:Added prefix:fd00:dead:beef:1::/64 flags:paros pref:high rloc16:0x5400
|
||||||
|
00:06:01.711 -> event:Added prefix:fd00:dead:beef:1::/64 flags:paros pref:med rloc16:0x8800
|
||||||
|
```
|
||||||
|
|
||||||
|
### prefix
|
||||||
|
|
||||||
|
Usage `history route [list] [<num-entries>]`
|
||||||
|
|
||||||
|
Print the Network Data external route history. Each item provides:
|
||||||
|
|
||||||
|
- Event (`Added` or `Removed`)
|
||||||
|
- Route
|
||||||
|
- Flags
|
||||||
|
- Preference (`high`, `med`, `low`)
|
||||||
|
- RLOC16
|
||||||
|
|
||||||
|
The flags are as follows:
|
||||||
|
|
||||||
|
- `s`: Stable flag
|
||||||
|
- `n`: NAT64 flag
|
||||||
|
|
||||||
|
Print the history as a table.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
history route
|
||||||
|
| Age | Event | Route | Flags | Pref | RLOC16 |
|
||||||
|
+----------------------+---------+---------------------------------------------+-----------+------+--------+
|
||||||
|
| 00:00:05.456 | Removed | fd00:1111:0::/48 | s | med | 0x3c00 |
|
||||||
|
| 00:00:29.310 | Added | fd00:1111:0::/48 | s | med | 0x3c00 |
|
||||||
|
| 00:00:42.822 | Added | fd00:1111:0::/48 | s | med | 0x5400 |
|
||||||
|
| 00:01:27.688 | Added | fd00:aaaa:bbbb:cccc::/64 | s | med | 0x8800 |
|
||||||
|
Done
|
||||||
|
```
|
||||||
|
|
||||||
|
Print the history as a list (last two entries).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
> history route list 2
|
||||||
|
00:00:48.704 -> event:Removed route:fd00:1111:0::/48 flags:s pref:med rloc16:0x3c00
|
||||||
|
00:01:12.558 -> event:Added route:fd00:1111:0::/48 flags:s pref:med rloc16:0x3c00
|
||||||
|
Done
|
||||||
|
```
|
||||||
|
|
||||||
### rx
|
### rx
|
||||||
|
|
||||||
Usage `history rx [list] [<num-entries>]`
|
Usage `history rx [list] [<num-entries>]`
|
||||||
|
|||||||
+107
-7
@@ -44,6 +44,11 @@ namespace Cli {
|
|||||||
|
|
||||||
constexpr History::Command History::sCommands[];
|
constexpr History::Command History::sCommands[];
|
||||||
|
|
||||||
|
static const char *const kSimpleEventStrings[] = {
|
||||||
|
"Added", // (0) OT_HISTORY_TRACKER_{NET_DATA_ENTRY/ADDRESSS_EVENT}_ADDED
|
||||||
|
"Removed" // (1) OT_HISTORY_TRACKER_{NET_DATA_ENTRY/ADDRESS_EVENT}_REMOVED
|
||||||
|
};
|
||||||
|
|
||||||
otError History::ProcessHelp(Arg aArgs[])
|
otError History::ProcessHelp(Arg aArgs[])
|
||||||
{
|
{
|
||||||
OT_UNUSED_VARIABLE(aArgs);
|
OT_UNUSED_VARIABLE(aArgs);
|
||||||
@@ -82,11 +87,6 @@ otError History::ParseArgs(Arg aArgs[], bool &aIsList, uint16_t &aNumEntries) co
|
|||||||
|
|
||||||
otError History::ProcessIpAddr(Arg aArgs[])
|
otError History::ProcessIpAddr(Arg aArgs[])
|
||||||
{
|
{
|
||||||
static const char *const kEventStrings[] = {
|
|
||||||
"Added", // (0) OT_HISTORY_TRACKER_ADDRESS_EVENT_ADDED
|
|
||||||
"Removed" // (1) OT_HISTORY_TRACKER_ADDRESS_EVENT_REMOVED
|
|
||||||
};
|
|
||||||
|
|
||||||
otError error;
|
otError error;
|
||||||
bool isList;
|
bool isList;
|
||||||
uint16_t numEntries;
|
uint16_t numEntries;
|
||||||
@@ -129,14 +129,14 @@ otError History::ProcessIpAddr(Arg aArgs[])
|
|||||||
sprintf(&addressString[strlen(addressString)], "/%d", info->mPrefixLength);
|
sprintf(&addressString[strlen(addressString)], "/%d", info->mPrefixLength);
|
||||||
|
|
||||||
OutputLine("| %20s | %-7s | %-43s | %-6s | %3d | %c | %c | %c |", ageString,
|
OutputLine("| %20s | %-7s | %-43s | %-6s | %3d | %c | %c | %c |", ageString,
|
||||||
Stringify(info->mEvent, kEventStrings), addressString,
|
Stringify(info->mEvent, kSimpleEventStrings), addressString,
|
||||||
Interpreter::AddressOriginToString(info->mAddressOrigin), info->mScope,
|
Interpreter::AddressOriginToString(info->mAddressOrigin), info->mScope,
|
||||||
info->mPreferred ? 'Y' : 'N', info->mValid ? 'Y' : 'N', info->mRloc ? 'Y' : 'N');
|
info->mPreferred ? 'Y' : 'N', info->mValid ? 'Y' : 'N', info->mRloc ? 'Y' : 'N');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
OutputLine("%s -> event:%s address:%s prefixlen:%d origin:%s scope:%d preferred:%s valid:%s rloc:%s",
|
OutputLine("%s -> event:%s address:%s prefixlen:%d origin:%s scope:%d preferred:%s valid:%s rloc:%s",
|
||||||
ageString, Stringify(info->mEvent, kEventStrings), addressString, info->mPrefixLength,
|
ageString, Stringify(info->mEvent, kSimpleEventStrings), addressString, info->mPrefixLength,
|
||||||
Interpreter::AddressOriginToString(info->mAddressOrigin), info->mScope,
|
Interpreter::AddressOriginToString(info->mAddressOrigin), info->mScope,
|
||||||
info->mPreferred ? "yes" : "no", info->mValid ? "yes" : "no", info->mRloc ? "yes" : "no");
|
info->mPreferred ? "yes" : "no", info->mValid ? "yes" : "no", info->mRloc ? "yes" : "no");
|
||||||
}
|
}
|
||||||
@@ -571,6 +571,106 @@ void History::OutputRxTxEntryTableFormat(const otHistoryTrackerMessageInfo &aInf
|
|||||||
OutputLine("| %20s | dst: %-70s |", "", addrString);
|
OutputLine("| %20s | dst: %-70s |", "", addrString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
otError History::ProcessPrefix(Arg aArgs[])
|
||||||
|
{
|
||||||
|
otError error;
|
||||||
|
bool isList;
|
||||||
|
uint16_t numEntries;
|
||||||
|
otHistoryTrackerIterator iterator;
|
||||||
|
const otHistoryTrackerOnMeshPrefixInfo *info;
|
||||||
|
uint32_t entryAge;
|
||||||
|
char ageString[OT_HISTORY_TRACKER_ENTRY_AGE_STRING_SIZE];
|
||||||
|
char prefixString[OT_IP6_PREFIX_STRING_SIZE];
|
||||||
|
NetworkData::FlagsString flagsString;
|
||||||
|
|
||||||
|
static_assert(0 == OT_HISTORY_TRACKER_NET_DATA_ENTRY_ADDED, "NET_DATA_ENTRY_ADDED value is incorrect");
|
||||||
|
static_assert(1 == OT_HISTORY_TRACKER_NET_DATA_ENTRY_REMOVED, "NET_DATA_ENTRY_REMOVED value is incorrect");
|
||||||
|
|
||||||
|
SuccessOrExit(error = ParseArgs(aArgs, isList, numEntries));
|
||||||
|
|
||||||
|
if (!isList)
|
||||||
|
{
|
||||||
|
// | Age | Event | Prefix | Flags | Pref | RLOC16 |
|
||||||
|
// +----------------------+---------+---------------------------------------------+-----------+------+--------+
|
||||||
|
|
||||||
|
static const char *const kPrefixTitles[] = {"Age", "Event", "Prefix", "Flags", "Pref", "RLOC16"};
|
||||||
|
static const uint8_t kPrefixColumnWidths[] = {22, 9, 45, 11, 6, 8};
|
||||||
|
|
||||||
|
OutputTableHeader(kPrefixTitles, kPrefixColumnWidths);
|
||||||
|
}
|
||||||
|
|
||||||
|
otHistoryTrackerInitIterator(&iterator);
|
||||||
|
|
||||||
|
for (uint16_t index = 0; (numEntries == 0) || (index < numEntries); index++)
|
||||||
|
{
|
||||||
|
info = otHistoryTrackerIterateOnMeshPrefixHistory(GetInstancePtr(), &iterator, &entryAge);
|
||||||
|
VerifyOrExit(info != nullptr);
|
||||||
|
|
||||||
|
otHistoryTrackerEntryAgeToString(entryAge, ageString, sizeof(ageString));
|
||||||
|
|
||||||
|
otIp6PrefixToString(&info->mPrefix.mPrefix, prefixString, sizeof(prefixString));
|
||||||
|
NetworkData::PrefixFlagsToString(info->mPrefix, flagsString);
|
||||||
|
|
||||||
|
OutputLine(isList ? "%s -> event:%s prefix:%s flags:%s pref:%s rloc16:0x%04x"
|
||||||
|
: "| %20s | %-7s | %-43s | %-9s | %-4s | 0x%04x |",
|
||||||
|
ageString, Stringify(info->mEvent, kSimpleEventStrings), prefixString, flagsString,
|
||||||
|
NetworkData::PreferenceToString(info->mPrefix.mPreference), info->mPrefix.mRloc16);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
otError History::ProcessRoute(Arg aArgs[])
|
||||||
|
{
|
||||||
|
otError error;
|
||||||
|
bool isList;
|
||||||
|
uint16_t numEntries;
|
||||||
|
otHistoryTrackerIterator iterator;
|
||||||
|
const otHistoryTrackerExternalRouteInfo *info;
|
||||||
|
uint32_t entryAge;
|
||||||
|
char ageString[OT_HISTORY_TRACKER_ENTRY_AGE_STRING_SIZE];
|
||||||
|
char prefixString[OT_IP6_PREFIX_STRING_SIZE];
|
||||||
|
NetworkData::FlagsString flagsString;
|
||||||
|
|
||||||
|
static_assert(0 == OT_HISTORY_TRACKER_NET_DATA_ENTRY_ADDED, "NET_DATA_ENTRY_ADDED value is incorrect");
|
||||||
|
static_assert(1 == OT_HISTORY_TRACKER_NET_DATA_ENTRY_REMOVED, "NET_DATA_ENTRY_REMOVED value is incorrect");
|
||||||
|
|
||||||
|
SuccessOrExit(error = ParseArgs(aArgs, isList, numEntries));
|
||||||
|
|
||||||
|
if (!isList)
|
||||||
|
{
|
||||||
|
// | Age | Event | Route | Flags | Pref | RLOC16 |
|
||||||
|
// +----------------------+---------+---------------------------------------------+-----------+------+--------+
|
||||||
|
|
||||||
|
static const char *const kRouteTitles[] = {"Age", "Event", "Route", "Flags", "Pref", "RLOC16"};
|
||||||
|
static const uint8_t kRouteColumnWidths[] = {22, 9, 45, 11, 6, 8};
|
||||||
|
|
||||||
|
OutputTableHeader(kRouteTitles, kRouteColumnWidths);
|
||||||
|
}
|
||||||
|
|
||||||
|
otHistoryTrackerInitIterator(&iterator);
|
||||||
|
|
||||||
|
for (uint16_t index = 0; (numEntries == 0) || (index < numEntries); index++)
|
||||||
|
{
|
||||||
|
info = otHistoryTrackerIterateExternalRouteHistory(GetInstancePtr(), &iterator, &entryAge);
|
||||||
|
VerifyOrExit(info != nullptr);
|
||||||
|
|
||||||
|
otHistoryTrackerEntryAgeToString(entryAge, ageString, sizeof(ageString));
|
||||||
|
|
||||||
|
otIp6PrefixToString(&info->mRoute.mPrefix, prefixString, sizeof(prefixString));
|
||||||
|
NetworkData::RouteFlagsToString(info->mRoute, flagsString);
|
||||||
|
|
||||||
|
OutputLine(isList ? "%s -> event:%s route:%s flags:%s pref:%s rloc16:0x%04x"
|
||||||
|
: "| %20s | %-7s | %-43s | %-9s | %-4s | 0x%04x |",
|
||||||
|
ageString, Stringify(info->mEvent, kSimpleEventStrings), prefixString, flagsString,
|
||||||
|
NetworkData::PreferenceToString(info->mRoute.mPreference), info->mRoute.mRloc16);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
otError History::Process(Arg aArgs[])
|
otError History::Process(Arg aArgs[])
|
||||||
{
|
{
|
||||||
otError error = OT_ERROR_INVALID_COMMAND;
|
otError error = OT_ERROR_INVALID_COMMAND;
|
||||||
|
|||||||
@@ -93,6 +93,8 @@ private:
|
|||||||
otError ProcessIpMulticastAddr(Arg aArgs[]);
|
otError ProcessIpMulticastAddr(Arg aArgs[]);
|
||||||
otError ProcessNetInfo(Arg aArgs[]);
|
otError ProcessNetInfo(Arg aArgs[]);
|
||||||
otError ProcessNeighbor(Arg aArgs[]);
|
otError ProcessNeighbor(Arg aArgs[]);
|
||||||
|
otError ProcessPrefix(Arg aArgs[]);
|
||||||
|
otError ProcessRoute(Arg aArgs[]);
|
||||||
otError ProcessRx(Arg aArgs[]);
|
otError ProcessRx(Arg aArgs[]);
|
||||||
otError ProcessRxTx(Arg aArgs[]);
|
otError ProcessRxTx(Arg aArgs[]);
|
||||||
otError ProcessTx(Arg aArgs[]);
|
otError ProcessTx(Arg aArgs[]);
|
||||||
@@ -112,6 +114,8 @@ private:
|
|||||||
{"ipmaddr", &History::ProcessIpMulticastAddr},
|
{"ipmaddr", &History::ProcessIpMulticastAddr},
|
||||||
{"neighbor", &History::ProcessNeighbor},
|
{"neighbor", &History::ProcessNeighbor},
|
||||||
{"netinfo", &History::ProcessNetInfo},
|
{"netinfo", &History::ProcessNetInfo},
|
||||||
|
{"prefix", &History::ProcessPrefix},
|
||||||
|
{"route", &History::ProcessRoute},
|
||||||
{"rx", &History::ProcessRx},
|
{"rx", &History::ProcessRx},
|
||||||
{"rxtx", &History::ProcessRxTx},
|
{"rxtx", &History::ProcessRxTx},
|
||||||
{"tx", &History::ProcessTx},
|
{"tx", &History::ProcessTx},
|
||||||
|
|||||||
@@ -45,20 +45,9 @@ namespace Cli {
|
|||||||
|
|
||||||
constexpr NetworkData::Command NetworkData::sCommands[];
|
constexpr NetworkData::Command NetworkData::sCommands[];
|
||||||
|
|
||||||
void NetworkData::OutputPrefix(const otBorderRouterConfig &aConfig)
|
void NetworkData::PrefixFlagsToString(const otBorderRouterConfig &aConfig, FlagsString &aString)
|
||||||
{
|
{
|
||||||
enum
|
char *flagsPtr = &aString[0];
|
||||||
{
|
|
||||||
// BorderRouter flag is `uint16_t` (though some of the bits are
|
|
||||||
// reserved for future use), so we use 17 chars string (16 flags
|
|
||||||
// plus null char at end of string).
|
|
||||||
kMaxFlagStringSize = 17,
|
|
||||||
};
|
|
||||||
|
|
||||||
char flagsString[kMaxFlagStringSize];
|
|
||||||
char *flagsPtr = &flagsString[0];
|
|
||||||
|
|
||||||
OutputIp6Prefix(aConfig.mPrefix);
|
|
||||||
|
|
||||||
if (aConfig.mPreferred)
|
if (aConfig.mPreferred)
|
||||||
{
|
{
|
||||||
@@ -106,31 +95,27 @@ void NetworkData::OutputPrefix(const otBorderRouterConfig &aConfig)
|
|||||||
}
|
}
|
||||||
|
|
||||||
*flagsPtr = '\0';
|
*flagsPtr = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
if (flagsPtr != &flagsString[0])
|
void NetworkData::OutputPrefix(const otBorderRouterConfig &aConfig)
|
||||||
|
{
|
||||||
|
FlagsString flagsString;
|
||||||
|
|
||||||
|
OutputIp6Prefix(aConfig.mPrefix);
|
||||||
|
|
||||||
|
PrefixFlagsToString(aConfig, flagsString);
|
||||||
|
|
||||||
|
if (flagsString[0] != '\0')
|
||||||
{
|
{
|
||||||
OutputFormat(" %s", flagsString);
|
OutputFormat(" %s", flagsString);
|
||||||
}
|
}
|
||||||
|
|
||||||
OutputPreference(aConfig.mPreference);
|
OutputLine(" %s %04x", PreferenceToString(aConfig.mPreference), aConfig.mRloc16);
|
||||||
|
|
||||||
OutputLine(" %04x", aConfig.mRloc16);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkData::OutputRoute(const otExternalRouteConfig &aConfig)
|
void NetworkData::RouteFlagsToString(const otExternalRouteConfig &aConfig, FlagsString &aString)
|
||||||
{
|
{
|
||||||
enum
|
char *flagsPtr = &aString[0];
|
||||||
{
|
|
||||||
// ExternalRoute flag is `uint8_t` (though some of the bits are
|
|
||||||
// reserved for future use), so we use 9 chars string (8 flags
|
|
||||||
// plus null char at end of string).
|
|
||||||
kMaxFlagStringSize = 9,
|
|
||||||
};
|
|
||||||
|
|
||||||
char flagsString[kMaxFlagStringSize];
|
|
||||||
char *flagsPtr = &flagsString[0];
|
|
||||||
|
|
||||||
OutputIp6Prefix(aConfig.mPrefix);
|
|
||||||
|
|
||||||
if (aConfig.mStable)
|
if (aConfig.mStable)
|
||||||
{
|
{
|
||||||
@@ -143,36 +128,47 @@ void NetworkData::OutputRoute(const otExternalRouteConfig &aConfig)
|
|||||||
}
|
}
|
||||||
|
|
||||||
*flagsPtr = '\0';
|
*flagsPtr = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
if (flagsPtr != &flagsString[0])
|
void NetworkData::OutputRoute(const otExternalRouteConfig &aConfig)
|
||||||
|
{
|
||||||
|
FlagsString flagsString;
|
||||||
|
|
||||||
|
OutputIp6Prefix(aConfig.mPrefix);
|
||||||
|
|
||||||
|
RouteFlagsToString(aConfig, flagsString);
|
||||||
|
|
||||||
|
if (flagsString[0] != '\0')
|
||||||
{
|
{
|
||||||
OutputFormat(" %s", flagsString);
|
OutputFormat(" %s", flagsString);
|
||||||
}
|
}
|
||||||
|
|
||||||
OutputPreference(aConfig.mPreference);
|
OutputLine(" %s %04x", PreferenceToString(aConfig.mPreference), aConfig.mRloc16);
|
||||||
|
|
||||||
OutputLine(" %04x", aConfig.mRloc16);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkData::OutputPreference(signed int aPreference)
|
const char *NetworkData::PreferenceToString(signed int aPreference)
|
||||||
{
|
{
|
||||||
|
const char *str = "";
|
||||||
|
|
||||||
switch (aPreference)
|
switch (aPreference)
|
||||||
{
|
{
|
||||||
case OT_ROUTE_PREFERENCE_LOW:
|
case OT_ROUTE_PREFERENCE_LOW:
|
||||||
OutputFormat(" low");
|
str = "low";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OT_ROUTE_PREFERENCE_MED:
|
case OT_ROUTE_PREFERENCE_MED:
|
||||||
OutputFormat(" med");
|
str = "med";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OT_ROUTE_PREFERENCE_HIGH:
|
case OT_ROUTE_PREFERENCE_HIGH:
|
||||||
OutputFormat(" high");
|
str = "high";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkData::OutputService(const otServiceConfig &aConfig)
|
void NetworkData::OutputService(const otServiceConfig &aConfig)
|
||||||
|
|||||||
@@ -52,6 +52,18 @@ class NetworkData : private OutputWrapper
|
|||||||
public:
|
public:
|
||||||
typedef Utils::CmdLineParser::Arg Arg;
|
typedef Utils::CmdLineParser::Arg Arg;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This constant specifies the string size for representing Network Data prefix/route entry flags.
|
||||||
|
*
|
||||||
|
* BorderRouter (OnMeshPrefix) TLV uses `uint16_t` for its flags and ExternalRoute uses `uint8_t`, though some of
|
||||||
|
* the bits are not currently used and reserved for future, so 17 chars string (16 flags plus null char at end of
|
||||||
|
* string) covers current and future flags.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static constexpr uint16_t kFlagsStringSize = 17;
|
||||||
|
|
||||||
|
typedef char FlagsString[kFlagsStringSize]; ///< Flags String type (char array of `kFlagsStringSize`).
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
@@ -95,6 +107,34 @@ public:
|
|||||||
*/
|
*/
|
||||||
void OutputService(const otServiceConfig &aConfig);
|
void OutputService(const otServiceConfig &aConfig);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method converts the flags from a given prefix config to string.
|
||||||
|
*
|
||||||
|
* @param[in] aConfig The prefix config.
|
||||||
|
* @param[out] aString The string to populate from @a Config flags.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void PrefixFlagsToString(const otBorderRouterConfig &aConfig, FlagsString &aString);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method converts the flags from a given route config to string.
|
||||||
|
*
|
||||||
|
* @param[in] aConfig The route config.
|
||||||
|
* @param[out] aString The string to populate from @a Config flags.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void RouteFlagsToString(const otExternalRouteConfig &aConfig, FlagsString &aString);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This static method converts a route preference value to human-readable string.
|
||||||
|
*
|
||||||
|
* @param[in] aPreference The preference value to convert (`OT_ROUTE_PREFERENCE_*` values).
|
||||||
|
*
|
||||||
|
* @returns A string representation @p aPreference.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static const char *PreferenceToString(signed int aPreference);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using Command = CommandEntry<NetworkData>;
|
using Command = CommandEntry<NetworkData>;
|
||||||
|
|
||||||
@@ -117,7 +157,6 @@ private:
|
|||||||
void OutputPrefixes(bool aLocal);
|
void OutputPrefixes(bool aLocal);
|
||||||
void OutputRoutes(bool aLocal);
|
void OutputRoutes(bool aLocal);
|
||||||
void OutputServices(bool aLocal);
|
void OutputServices(bool aLocal);
|
||||||
void OutputPreference(signed int aPreference);
|
|
||||||
|
|
||||||
static constexpr Command sCommands[] = {
|
static constexpr Command sCommands[] = {
|
||||||
{"help", &NetworkData::ProcessHelp},
|
{"help", &NetworkData::ProcessHelp},
|
||||||
|
|||||||
@@ -94,6 +94,23 @@ const otHistoryTrackerNeighborInfo *otHistoryTrackerIterateNeighborHistory(otIns
|
|||||||
return AsCoreType(aInstance).Get<Utils::HistoryTracker>().IterateNeighborHistory(AsCoreType(aIterator), *aEntryAge);
|
return AsCoreType(aInstance).Get<Utils::HistoryTracker>().IterateNeighborHistory(AsCoreType(aIterator), *aEntryAge);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const otHistoryTrackerOnMeshPrefixInfo *otHistoryTrackerIterateOnMeshPrefixHistory(otInstance * aInstance,
|
||||||
|
otHistoryTrackerIterator *aIterator,
|
||||||
|
uint32_t * aEntryAge)
|
||||||
|
{
|
||||||
|
return AsCoreType(aInstance).Get<Utils::HistoryTracker>().IterateOnMeshPrefixHistory(AsCoreType(aIterator),
|
||||||
|
*aEntryAge);
|
||||||
|
}
|
||||||
|
|
||||||
|
const otHistoryTrackerExternalRouteInfo *otHistoryTrackerIterateExternalRouteHistory(
|
||||||
|
otInstance * aInstance,
|
||||||
|
otHistoryTrackerIterator *aIterator,
|
||||||
|
uint32_t * aEntryAge)
|
||||||
|
{
|
||||||
|
return AsCoreType(aInstance).Get<Utils::HistoryTracker>().IterateExternalRouteHistory(AsCoreType(aIterator),
|
||||||
|
*aEntryAge);
|
||||||
|
}
|
||||||
|
|
||||||
void otHistoryTrackerEntryAgeToString(uint32_t aEntryAge, char *aBuffer, uint16_t aSize)
|
void otHistoryTrackerEntryAgeToString(uint32_t aEntryAge, char *aBuffer, uint16_t aSize)
|
||||||
{
|
{
|
||||||
Utils::HistoryTracker::EntryAgeToString(aEntryAge, aBuffer, aSize);
|
Utils::HistoryTracker::EntryAgeToString(aEntryAge, aBuffer, aSize);
|
||||||
|
|||||||
@@ -127,4 +127,28 @@
|
|||||||
#define OPENTHREAD_CONFIG_HISTORY_TRACKER_NEIGHBOR_LIST_SIZE 64
|
#define OPENTHREAD_CONFIG_HISTORY_TRACKER_NEIGHBOR_LIST_SIZE 64
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def OPENTHREAD_CONFIG_HISTORY_TRACKER_ON_MESH_PREFIX_LIST_SIZE
|
||||||
|
*
|
||||||
|
* Specifies the maximum number of entries in Network Data On Mesh Prefix history list.
|
||||||
|
*
|
||||||
|
* Can be set to zero to configure History Tracker module not to collect prefix info.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef OPENTHREAD_CONFIG_HISTORY_TRACKER_ON_MESH_PREFIX_LIST_SIZE
|
||||||
|
#define OPENTHREAD_CONFIG_HISTORY_TRACKER_ON_MESH_PREFIX_LIST_SIZE 32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def OPENTHREAD_CONFIG_HISTORY_TRACKER_EXTERNAL_ROUTE_LIST_SIZE
|
||||||
|
*
|
||||||
|
* Specifies the maximum number of entries in Network Data External Route history list.
|
||||||
|
*
|
||||||
|
* Can be set to zero to configure History Tracker module not to collect route info.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef OPENTHREAD_CONFIG_HISTORY_TRACKER_EXTERNAL_ROUTE_LIST_SIZE
|
||||||
|
#define OPENTHREAD_CONFIG_HISTORY_TRACKER_EXTERNAL_ROUTE_LIST_SIZE 32
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // CONFIG_HISTORY_TRACKER_H_
|
#endif // CONFIG_HISTORY_TRACKER_H_
|
||||||
|
|||||||
@@ -52,6 +52,9 @@ namespace Utils {
|
|||||||
HistoryTracker::HistoryTracker(Instance &aInstance)
|
HistoryTracker::HistoryTracker(Instance &aInstance)
|
||||||
: InstanceLocator(aInstance)
|
: InstanceLocator(aInstance)
|
||||||
, mTimer(aInstance, HandleTimer)
|
, mTimer(aInstance, HandleTimer)
|
||||||
|
#if OPENTHREAD_CONFIG_HISTORY_TRACKER_NET_DATA
|
||||||
|
, mPreviousNetworkData(aInstance, mNetworkDataTlvBuffer, 0, sizeof(mNetworkDataTlvBuffer))
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
mTimer.Start(kAgeCheckPeriod);
|
mTimer.Start(kAgeCheckPeriod);
|
||||||
}
|
}
|
||||||
@@ -291,6 +294,86 @@ exit:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if OPENTHREAD_CONFIG_HISTORY_TRACKER_NET_DATA
|
||||||
|
void HistoryTracker::RecordNetworkDataChange(void)
|
||||||
|
{
|
||||||
|
NetworkData::Iterator iterator;
|
||||||
|
NetworkData::OnMeshPrefixConfig prefix;
|
||||||
|
NetworkData::ExternalRouteConfig route;
|
||||||
|
|
||||||
|
// On mesh prefix entries
|
||||||
|
|
||||||
|
iterator = NetworkData::kIteratorInit;
|
||||||
|
|
||||||
|
while (mPreviousNetworkData.GetNextOnMeshPrefix(iterator, prefix) == kErrorNone)
|
||||||
|
{
|
||||||
|
if (!Get<NetworkData::Leader>().ContainsOnMeshPrefix(prefix))
|
||||||
|
{
|
||||||
|
RecordOnMeshPrefixEvent(kNetDataEntryRemoved, prefix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator = NetworkData::kIteratorInit;
|
||||||
|
|
||||||
|
while (Get<NetworkData::Leader>().GetNextOnMeshPrefix(iterator, prefix) == kErrorNone)
|
||||||
|
{
|
||||||
|
if (!mPreviousNetworkData.ContainsOnMeshPrefix(prefix))
|
||||||
|
{
|
||||||
|
RecordOnMeshPrefixEvent(kNetDataEntryAdded, prefix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// External route entries
|
||||||
|
|
||||||
|
iterator = NetworkData::kIteratorInit;
|
||||||
|
|
||||||
|
while (mPreviousNetworkData.GetNextExternalRoute(iterator, route) == kErrorNone)
|
||||||
|
{
|
||||||
|
if (!Get<NetworkData::Leader>().ContainsExternalRoute(route))
|
||||||
|
{
|
||||||
|
RecordExternalRouteEvent(kNetDataEntryRemoved, route);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator = NetworkData::kIteratorInit;
|
||||||
|
|
||||||
|
while (Get<NetworkData::Leader>().GetNextExternalRoute(iterator, route) == kErrorNone)
|
||||||
|
{
|
||||||
|
if (!mPreviousNetworkData.ContainsExternalRoute(route))
|
||||||
|
{
|
||||||
|
RecordExternalRouteEvent(kNetDataEntryAdded, route);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SuccessOrAssert(Get<NetworkData::Leader>().CopyNetworkData(/* aSatble */ false, mPreviousNetworkData));
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryTracker::RecordOnMeshPrefixEvent(NetDataEvent aEvent, const NetworkData::OnMeshPrefixConfig &aPrefix)
|
||||||
|
{
|
||||||
|
OnMeshPrefixInfo *entry = mOnMeshPrefixHistory.AddNewEntry();
|
||||||
|
|
||||||
|
VerifyOrExit(entry != nullptr);
|
||||||
|
entry->mPrefix = aPrefix;
|
||||||
|
entry->mEvent = aEvent;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryTracker::RecordExternalRouteEvent(NetDataEvent aEvent, const NetworkData::ExternalRouteConfig &aRoute)
|
||||||
|
{
|
||||||
|
ExternalRouteInfo *entry = mExternalRouteHistory.AddNewEntry();
|
||||||
|
|
||||||
|
VerifyOrExit(entry != nullptr);
|
||||||
|
entry->mRoute = aRoute;
|
||||||
|
entry->mEvent = aEvent;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // OPENTHREAD_CONFIG_HISTORY_TRACKER_NET_DATA
|
||||||
|
|
||||||
void HistoryTracker::HandleNotifierEvents(Events aEvents)
|
void HistoryTracker::HandleNotifierEvents(Events aEvents)
|
||||||
{
|
{
|
||||||
if (aEvents.ContainsAny(kEventThreadRoleChanged | kEventThreadRlocAdded | kEventThreadRlocRemoved |
|
if (aEvents.ContainsAny(kEventThreadRoleChanged | kEventThreadRlocAdded | kEventThreadRlocRemoved |
|
||||||
@@ -298,6 +381,13 @@ void HistoryTracker::HandleNotifierEvents(Events aEvents)
|
|||||||
{
|
{
|
||||||
RecordNetworkInfo();
|
RecordNetworkInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if OPENTHREAD_CONFIG_HISTORY_TRACKER_NET_DATA
|
||||||
|
if (aEvents.Contains(kEventThreadNetdataChanged))
|
||||||
|
{
|
||||||
|
RecordNetworkDataChange();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryTracker::HandleTimer(Timer &aTimer)
|
void HistoryTracker::HandleTimer(Timer &aTimer)
|
||||||
@@ -313,6 +403,8 @@ void HistoryTracker::HandleTimer(void)
|
|||||||
mRxHistory.UpdateAgedEntries();
|
mRxHistory.UpdateAgedEntries();
|
||||||
mTxHistory.UpdateAgedEntries();
|
mTxHistory.UpdateAgedEntries();
|
||||||
mNeighborHistory.UpdateAgedEntries();
|
mNeighborHistory.UpdateAgedEntries();
|
||||||
|
mOnMeshPrefixHistory.UpdateAgedEntries();
|
||||||
|
mExternalRouteHistory.UpdateAgedEntries();
|
||||||
|
|
||||||
mTimer.Start(kAgeCheckPeriod);
|
mTimer.Start(kAgeCheckPeriod);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,10 +53,20 @@
|
|||||||
#include "thread/mle.hpp"
|
#include "thread/mle.hpp"
|
||||||
#include "thread/mle_types.hpp"
|
#include "thread/mle_types.hpp"
|
||||||
#include "thread/neighbor_table.hpp"
|
#include "thread/neighbor_table.hpp"
|
||||||
|
#include "thread/network_data.hpp"
|
||||||
|
|
||||||
namespace ot {
|
namespace ot {
|
||||||
namespace Utils {
|
namespace Utils {
|
||||||
|
|
||||||
|
#ifdef OPENTHREAD_CONFIG_HISTORY_TRACKER_NET_DATA
|
||||||
|
#error "OPENTHREAD_CONFIG_HISTORY_TRACKER_NET_DATA should not be defined directly." \
|
||||||
|
"It is derived from other configs: on-mesh prefix and external route history list sizes"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define OPENTHREAD_CONFIG_HISTORY_TRACKER_NET_DATA \
|
||||||
|
((OPENTHREAD_CONFIG_HISTORY_TRACKER_ON_MESH_PREFIX_LIST_SIZE > 0) || \
|
||||||
|
(OPENTHREAD_CONFIG_HISTORY_TRACKER_EXTERNAL_ROUTE_LIST_SIZE > 0))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class implements History Tracker.
|
* This class implements History Tracker.
|
||||||
*
|
*
|
||||||
@@ -110,35 +120,13 @@ public:
|
|||||||
void SetInitTime(void) { mData32 = TimerMilli::GetNow().GetValue(); }
|
void SetInitTime(void) { mData32 = TimerMilli::GetNow().GetValue(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
typedef otHistoryTrackerNetworkInfo NetworkInfo; ///< Thread network info.
|
||||||
* This type represents Thread network info.
|
typedef otHistoryTrackerUnicastAddressInfo UnicastAddressInfo; ///< Unicast IPv6 address info.
|
||||||
*
|
typedef otHistoryTrackerMulticastAddressInfo MulticastAddressInfo; ///< Multicast IPv6 address info.
|
||||||
*/
|
typedef otHistoryTrackerMessageInfo MessageInfo; ///< RX/TX IPv6 message info.
|
||||||
typedef otHistoryTrackerNetworkInfo NetworkInfo;
|
typedef otHistoryTrackerNeighborInfo NeighborInfo; ///< Neighbor info.
|
||||||
|
typedef otHistoryTrackerOnMeshPrefixInfo OnMeshPrefixInfo; ///< Network Data on mesh prefix info.
|
||||||
/**
|
typedef otHistoryTrackerExternalRouteInfo ExternalRouteInfo; ///< Network Data external route info
|
||||||
* This structure represents a unicast IPv6 address info.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
typedef otHistoryTrackerUnicastAddressInfo UnicastAddressInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This structure represent a multicast IPv6 address info.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
typedef otHistoryTrackerMulticastAddressInfo MulticastAddressInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This type represents a RX/TX IPv6 message info.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
typedef otHistoryTrackerMessageInfo MessageInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This type represents a neighbor info.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
typedef otHistoryTrackerNeighborInfo NeighborInfo;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This constructor initializes the `HistoryTracker`.
|
* This constructor initializes the `HistoryTracker`.
|
||||||
@@ -233,6 +221,16 @@ public:
|
|||||||
return mNeighborHistory.Iterate(aIterator, aEntryAge);
|
return mNeighborHistory.Iterate(aIterator, aEntryAge);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const OnMeshPrefixInfo *IterateOnMeshPrefixHistory(Iterator &aIterator, uint32_t &aEntryAge) const
|
||||||
|
{
|
||||||
|
return mOnMeshPrefixHistory.Iterate(aIterator, aEntryAge);
|
||||||
|
}
|
||||||
|
|
||||||
|
const ExternalRouteInfo *IterateExternalRouteHistory(Iterator &aIterator, uint32_t &aEntryAge) const
|
||||||
|
{
|
||||||
|
return mExternalRouteHistory.Iterate(aIterator, aEntryAge);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This static method converts a given entry age to a human-readable string.
|
* This static method converts a given entry age to a human-readable string.
|
||||||
*
|
*
|
||||||
@@ -262,6 +260,8 @@ private:
|
|||||||
static constexpr uint16_t kRxListSize = OPENTHREAD_CONFIG_HISTORY_TRACKER_RX_LIST_SIZE;
|
static constexpr uint16_t kRxListSize = OPENTHREAD_CONFIG_HISTORY_TRACKER_RX_LIST_SIZE;
|
||||||
static constexpr uint16_t kTxListSize = OPENTHREAD_CONFIG_HISTORY_TRACKER_TX_LIST_SIZE;
|
static constexpr uint16_t kTxListSize = OPENTHREAD_CONFIG_HISTORY_TRACKER_TX_LIST_SIZE;
|
||||||
static constexpr uint16_t kNeighborListSize = OPENTHREAD_CONFIG_HISTORY_TRACKER_NEIGHBOR_LIST_SIZE;
|
static constexpr uint16_t kNeighborListSize = OPENTHREAD_CONFIG_HISTORY_TRACKER_NEIGHBOR_LIST_SIZE;
|
||||||
|
static constexpr uint16_t kOnMeshPrefixListSize = OPENTHREAD_CONFIG_HISTORY_TRACKER_ON_MESH_PREFIX_LIST_SIZE;
|
||||||
|
static constexpr uint16_t kExternalRouteListSize = OPENTHREAD_CONFIG_HISTORY_TRACKER_EXTERNAL_ROUTE_LIST_SIZE;
|
||||||
|
|
||||||
typedef otHistoryTrackerAddressEvent AddressEvent;
|
typedef otHistoryTrackerAddressEvent AddressEvent;
|
||||||
|
|
||||||
@@ -278,6 +278,11 @@ private:
|
|||||||
static constexpr NeighborEvent kNeighborChanged = OT_HISTORY_TRACKER_NEIGHBOR_EVENT_CHANGED;
|
static constexpr NeighborEvent kNeighborChanged = OT_HISTORY_TRACKER_NEIGHBOR_EVENT_CHANGED;
|
||||||
static constexpr NeighborEvent kNeighborRestoring = OT_HISTORY_TRACKER_NEIGHBOR_EVENT_RESTORING;
|
static constexpr NeighborEvent kNeighborRestoring = OT_HISTORY_TRACKER_NEIGHBOR_EVENT_RESTORING;
|
||||||
|
|
||||||
|
typedef otHistoryTrackerNetDataEvent NetDataEvent;
|
||||||
|
|
||||||
|
static constexpr NetDataEvent kNetDataEntryAdded = OT_HISTORY_TRACKER_NET_DATA_ENTRY_ADDED;
|
||||||
|
static constexpr NetDataEvent kNetDataEntryRemoved = OT_HISTORY_TRACKER_NET_DATA_ENTRY_REMOVED;
|
||||||
|
|
||||||
class Timestamp
|
class Timestamp
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -379,6 +384,11 @@ private:
|
|||||||
void HandleNotifierEvents(Events aEvents);
|
void HandleNotifierEvents(Events aEvents);
|
||||||
static void HandleTimer(Timer &aTimer);
|
static void HandleTimer(Timer &aTimer);
|
||||||
void HandleTimer(void);
|
void HandleTimer(void);
|
||||||
|
#if OPENTHREAD_CONFIG_HISTORY_TRACKER_NET_DATA
|
||||||
|
void RecordNetworkDataChange(void);
|
||||||
|
void RecordOnMeshPrefixEvent(NetDataEvent aEvent, const NetworkData::OnMeshPrefixConfig &aPrefix);
|
||||||
|
void RecordExternalRouteEvent(NetDataEvent aEvent, const NetworkData::ExternalRouteConfig &aRoute);
|
||||||
|
#endif
|
||||||
|
|
||||||
EntryList<NetworkInfo, kNetInfoListSize> mNetInfoHistory;
|
EntryList<NetworkInfo, kNetInfoListSize> mNetInfoHistory;
|
||||||
EntryList<UnicastAddressInfo, kUnicastAddrListSize> mUnicastAddressHistory;
|
EntryList<UnicastAddressInfo, kUnicastAddrListSize> mUnicastAddressHistory;
|
||||||
@@ -386,8 +396,16 @@ private:
|
|||||||
EntryList<MessageInfo, kRxListSize> mRxHistory;
|
EntryList<MessageInfo, kRxListSize> mRxHistory;
|
||||||
EntryList<MessageInfo, kTxListSize> mTxHistory;
|
EntryList<MessageInfo, kTxListSize> mTxHistory;
|
||||||
EntryList<NeighborInfo, kNeighborListSize> mNeighborHistory;
|
EntryList<NeighborInfo, kNeighborListSize> mNeighborHistory;
|
||||||
|
EntryList<OnMeshPrefixInfo, kOnMeshPrefixListSize> mOnMeshPrefixHistory;
|
||||||
|
EntryList<ExternalRouteInfo, kExternalRouteListSize> mExternalRouteHistory;
|
||||||
|
|
||||||
TimerMilli mTimer;
|
TimerMilli mTimer;
|
||||||
|
|
||||||
|
#if OPENTHREAD_CONFIG_HISTORY_TRACKER_NET_DATA
|
||||||
|
NetworkData::MutableNetworkData mPreviousNetworkData;
|
||||||
|
|
||||||
|
uint8_t mNetworkDataTlvBuffer[NetworkData::NetworkData::kMaxSize];
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Utils
|
} // namespace Utils
|
||||||
@@ -396,6 +414,8 @@ DefineCoreType(otHistoryTrackerIterator, Utils::HistoryTracker::Iterator);
|
|||||||
DefineCoreType(otHistoryTrackerNetworkInfo, Utils::HistoryTracker::NetworkInfo);
|
DefineCoreType(otHistoryTrackerNetworkInfo, Utils::HistoryTracker::NetworkInfo);
|
||||||
DefineCoreType(otHistoryTrackerMessageInfo, Utils::HistoryTracker::MessageInfo);
|
DefineCoreType(otHistoryTrackerMessageInfo, Utils::HistoryTracker::MessageInfo);
|
||||||
DefineCoreType(otHistoryTrackerNeighborInfo, Utils::HistoryTracker::NeighborInfo);
|
DefineCoreType(otHistoryTrackerNeighborInfo, Utils::HistoryTracker::NeighborInfo);
|
||||||
|
DefineCoreType(otHistoryTrackerOnMeshPrefixInfo, Utils::HistoryTracker::OnMeshPrefixInfo);
|
||||||
|
DefineCoreType(otHistoryTrackerExternalRouteInfo, Utils::HistoryTracker::ExternalRouteInfo);
|
||||||
|
|
||||||
} // namespace ot
|
} // namespace ot
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user