1*cfb92d14SAndroid Build Coastguard Worker /*
2*cfb92d14SAndroid Build Coastguard Worker * Copyright (c) 2021, The OpenThread Authors.
3*cfb92d14SAndroid Build Coastguard Worker * All rights reserved.
4*cfb92d14SAndroid Build Coastguard Worker *
5*cfb92d14SAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
6*cfb92d14SAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions are met:
7*cfb92d14SAndroid Build Coastguard Worker * 1. Redistributions of source code must retain the above copyright
8*cfb92d14SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
9*cfb92d14SAndroid Build Coastguard Worker * 2. Redistributions in binary form must reproduce the above copyright
10*cfb92d14SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer in the
11*cfb92d14SAndroid Build Coastguard Worker * documentation and/or other materials provided with the distribution.
12*cfb92d14SAndroid Build Coastguard Worker * 3. Neither the name of the copyright holder nor the
13*cfb92d14SAndroid Build Coastguard Worker * names of its contributors may be used to endorse or promote products
14*cfb92d14SAndroid Build Coastguard Worker * derived from this software without specific prior written permission.
15*cfb92d14SAndroid Build Coastguard Worker *
16*cfb92d14SAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17*cfb92d14SAndroid Build Coastguard Worker * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*cfb92d14SAndroid Build Coastguard Worker * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*cfb92d14SAndroid Build Coastguard Worker * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20*cfb92d14SAndroid Build Coastguard Worker * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*cfb92d14SAndroid Build Coastguard Worker * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*cfb92d14SAndroid Build Coastguard Worker * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*cfb92d14SAndroid Build Coastguard Worker * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*cfb92d14SAndroid Build Coastguard Worker * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*cfb92d14SAndroid Build Coastguard Worker * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*cfb92d14SAndroid Build Coastguard Worker * POSSIBILITY OF SUCH DAMAGE.
27*cfb92d14SAndroid Build Coastguard Worker */
28*cfb92d14SAndroid Build Coastguard Worker
29*cfb92d14SAndroid Build Coastguard Worker /**
30*cfb92d14SAndroid Build Coastguard Worker * @file
31*cfb92d14SAndroid Build Coastguard Worker * This file implements CLI for the History Tracker.
32*cfb92d14SAndroid Build Coastguard Worker */
33*cfb92d14SAndroid Build Coastguard Worker
34*cfb92d14SAndroid Build Coastguard Worker #include "cli_history.hpp"
35*cfb92d14SAndroid Build Coastguard Worker
36*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
37*cfb92d14SAndroid Build Coastguard Worker
38*cfb92d14SAndroid Build Coastguard Worker #include <string.h>
39*cfb92d14SAndroid Build Coastguard Worker
40*cfb92d14SAndroid Build Coastguard Worker #include "cli/cli.hpp"
41*cfb92d14SAndroid Build Coastguard Worker
42*cfb92d14SAndroid Build Coastguard Worker namespace ot {
43*cfb92d14SAndroid Build Coastguard Worker namespace Cli {
44*cfb92d14SAndroid Build Coastguard Worker
45*cfb92d14SAndroid Build Coastguard Worker static const char *const kSimpleEventStrings[] = {
46*cfb92d14SAndroid Build Coastguard Worker "Added", // (0) OT_HISTORY_TRACKER_{NET_DATA_ENTRY/ADDRESS_EVENT}_ADDED
47*cfb92d14SAndroid Build Coastguard Worker "Removed" // (1) OT_HISTORY_TRACKER_{NET_DATA_ENTRY/ADDRESS_EVENT}_REMOVED
48*cfb92d14SAndroid Build Coastguard Worker };
49*cfb92d14SAndroid Build Coastguard Worker
ParseArgs(Arg aArgs[],bool & aIsList,uint16_t & aNumEntries) const50*cfb92d14SAndroid Build Coastguard Worker otError History::ParseArgs(Arg aArgs[], bool &aIsList, uint16_t &aNumEntries) const
51*cfb92d14SAndroid Build Coastguard Worker {
52*cfb92d14SAndroid Build Coastguard Worker if (*aArgs == "list")
53*cfb92d14SAndroid Build Coastguard Worker {
54*cfb92d14SAndroid Build Coastguard Worker aArgs++;
55*cfb92d14SAndroid Build Coastguard Worker aIsList = true;
56*cfb92d14SAndroid Build Coastguard Worker }
57*cfb92d14SAndroid Build Coastguard Worker else
58*cfb92d14SAndroid Build Coastguard Worker {
59*cfb92d14SAndroid Build Coastguard Worker aIsList = false;
60*cfb92d14SAndroid Build Coastguard Worker }
61*cfb92d14SAndroid Build Coastguard Worker
62*cfb92d14SAndroid Build Coastguard Worker if (aArgs->ParseAsUint16(aNumEntries) == OT_ERROR_NONE)
63*cfb92d14SAndroid Build Coastguard Worker {
64*cfb92d14SAndroid Build Coastguard Worker aArgs++;
65*cfb92d14SAndroid Build Coastguard Worker }
66*cfb92d14SAndroid Build Coastguard Worker else
67*cfb92d14SAndroid Build Coastguard Worker {
68*cfb92d14SAndroid Build Coastguard Worker aNumEntries = 0;
69*cfb92d14SAndroid Build Coastguard Worker }
70*cfb92d14SAndroid Build Coastguard Worker
71*cfb92d14SAndroid Build Coastguard Worker return aArgs[0].IsEmpty() ? OT_ERROR_NONE : OT_ERROR_INVALID_ARGS;
72*cfb92d14SAndroid Build Coastguard Worker }
73*cfb92d14SAndroid Build Coastguard Worker
74*cfb92d14SAndroid Build Coastguard Worker /**
75*cfb92d14SAndroid Build Coastguard Worker * @cli history ipaddr
76*cfb92d14SAndroid Build Coastguard Worker * @code
77*cfb92d14SAndroid Build Coastguard Worker * history ipaddr
78*cfb92d14SAndroid Build Coastguard Worker * | Age | Event | Address / Prefix Length | Origin |Scope| P | V | R |
79*cfb92d14SAndroid Build Coastguard Worker * +----------------------+---------+---------------------------------------------+--------+-----+---+---+---+
80*cfb92d14SAndroid Build Coastguard Worker * | 00:00:04.991 | Removed | 2001:dead:beef:cafe:c4cb:caba:8d55:e30b/64 | slaac | 14 | Y | Y | N |
81*cfb92d14SAndroid Build Coastguard Worker * | 00:00:44.647 | Added | 2001:dead:beef:cafe:c4cb:caba:8d55:e30b/64 | slaac | 14 | Y | Y | N |
82*cfb92d14SAndroid Build Coastguard Worker * | 00:01:07.199 | Added | fd00:0:0:0:0:0:0:1/64 | manual | 14 | Y | Y | N |
83*cfb92d14SAndroid Build Coastguard Worker * | 00:02:17.885 | Added | fdde:ad00:beef:0:0:ff:fe00:fc00/64 | thread | 3 | N | Y | N |
84*cfb92d14SAndroid Build Coastguard Worker * | 00:02:17.885 | Added | fdde:ad00:beef:0:0:ff:fe00:5400/64 | thread | 3 | N | Y | Y |
85*cfb92d14SAndroid Build Coastguard Worker * | 00:02:20.107 | Removed | fdde:ad00:beef:0:0:ff:fe00:5400/64 | thread | 3 | N | Y | Y |
86*cfb92d14SAndroid Build Coastguard Worker * | 00:02:21.575 | Added | fdde:ad00:beef:0:0:ff:fe00:5400/64 | thread | 3 | N | Y | Y |
87*cfb92d14SAndroid Build Coastguard Worker * | 00:02:21.575 | Added | fdde:ad00:beef:0:ecea:c4fc:ad96:4655/64 | thread | 3 | N | Y | N |
88*cfb92d14SAndroid Build Coastguard Worker * | 00:02:23.904 | Added | fe80:0:0:0:3c12:a4d2:fbe0:31ad/64 | thread | 2 | Y | Y | N |
89*cfb92d14SAndroid Build Coastguard Worker * Done
90*cfb92d14SAndroid Build Coastguard Worker * @endcode
91*cfb92d14SAndroid Build Coastguard Worker * @code
92*cfb92d14SAndroid Build Coastguard Worker * history ipaddr list 5
93*cfb92d14SAndroid Build Coastguard Worker * 00:00:20.327 -> event:Removed address:2001:dead:beef:cafe:c4cb:caba:8d55:e30b <!--
94*cfb92d14SAndroid Build Coastguard Worker * -->prefixlen:64 origin:slaac scope:14 preferred:yes valid:yes rloc:no
95*cfb92d14SAndroid Build Coastguard Worker * 00:00:59.983 -> event:Added address:2001:dead:beef:cafe:c4cb:caba:8d55:e30b <!--
96*cfb92d14SAndroid Build Coastguard Worker * -->prefixlen:64 origin:slaac scope:14 preferred:yes valid:yes rloc:no
97*cfb92d14SAndroid Build Coastguard Worker * 00:01:22.535 -> event:Added address:fd00:0:0:0:0:0:0:1 prefixlen:64 <!--
98*cfb92d14SAndroid Build Coastguard Worker * -->origin:manual scope:14 preferred:yes valid:yes rloc:no
99*cfb92d14SAndroid Build Coastguard Worker * 00:02:33.221 -> event:Added address:fdde:ad00:beef:0:0:ff:fe00:fc00 <!--
100*cfb92d14SAndroid Build Coastguard Worker * -->prefixlen:64 origin:thread scope:3 preferred:no valid:yes rloc:no
101*cfb92d14SAndroid Build Coastguard Worker * 00:02:33.221 -> event:Added address:fdde:ad00:beef:0:0:ff:fe00:5400 <!--
102*cfb92d14SAndroid Build Coastguard Worker * -->prefixlen:64 origin:thread scope:3 preferred:no valid:yes rloc:yes
103*cfb92d14SAndroid Build Coastguard Worker * Done
104*cfb92d14SAndroid Build Coastguard Worker * @endcode
105*cfb92d14SAndroid Build Coastguard Worker * @cparam history ipaddr [@ca{list}] [@ca{num-entries}]
106*cfb92d14SAndroid Build Coastguard Worker * * Use the `list` option to display the output in list format. Otherwise,
107*cfb92d14SAndroid Build Coastguard Worker * the output is shown in table format.
108*cfb92d14SAndroid Build Coastguard Worker * * Use the `num-entries` option to limit the output to the number of
109*cfb92d14SAndroid Build Coastguard Worker * most-recent entries specified. If this option is not used, all stored
110*cfb92d14SAndroid Build Coastguard Worker * entries are shown in the output.
111*cfb92d14SAndroid Build Coastguard Worker * @par
112*cfb92d14SAndroid Build Coastguard Worker * Displays the unicast IPv6 address history in table or list format.
113*cfb92d14SAndroid Build Coastguard Worker * @par
114*cfb92d14SAndroid Build Coastguard Worker * Each table or list entry provides:
115*cfb92d14SAndroid Build Coastguard Worker * * Age: Time elapsed since the command was issued, and given in the format:
116*cfb92d14SAndroid Build Coastguard Worker * `hours`:`minutes`:`seconds`:`milliseconds`
117*cfb92d14SAndroid Build Coastguard Worker * * Event: Possible values are `Added` or `Removed`.
118*cfb92d14SAndroid Build Coastguard Worker * * Address/Prefix Length: Unicast address with its prefix length (in bits).
119*cfb92d14SAndroid Build Coastguard Worker * * Origin: Possible value are `thread`, `slaac`, `dhcp6`, or `manual`.
120*cfb92d14SAndroid Build Coastguard Worker * * Scope: IPv6 address scope.
121*cfb92d14SAndroid Build Coastguard Worker * * P: Preferred flag.
122*cfb92d14SAndroid Build Coastguard Worker * * V: Valid flag.
123*cfb92d14SAndroid Build Coastguard Worker * * RLOC (R): This flag indicates if the IPv6 address is a routing locator.
124*cfb92d14SAndroid Build Coastguard Worker * @note
125*cfb92d14SAndroid Build Coastguard Worker * All commands under `history` require the `OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE`
126*cfb92d14SAndroid Build Coastguard Worker * feature to be enabled.
127*cfb92d14SAndroid Build Coastguard Worker * @sa otHistoryTrackerEntryAgeToString
128*cfb92d14SAndroid Build Coastguard Worker * @sa otHistoryTrackerIterateUnicastAddressHistory
129*cfb92d14SAndroid Build Coastguard Worker */
Process(Arg aArgs[])130*cfb92d14SAndroid Build Coastguard Worker template <> otError History::Process<Cmd("ipaddr")>(Arg aArgs[])
131*cfb92d14SAndroid Build Coastguard Worker {
132*cfb92d14SAndroid Build Coastguard Worker otError error;
133*cfb92d14SAndroid Build Coastguard Worker bool isList;
134*cfb92d14SAndroid Build Coastguard Worker uint16_t numEntries;
135*cfb92d14SAndroid Build Coastguard Worker otHistoryTrackerIterator iterator;
136*cfb92d14SAndroid Build Coastguard Worker const otHistoryTrackerUnicastAddressInfo *info;
137*cfb92d14SAndroid Build Coastguard Worker uint32_t entryAge;
138*cfb92d14SAndroid Build Coastguard Worker char ageString[OT_HISTORY_TRACKER_ENTRY_AGE_STRING_SIZE];
139*cfb92d14SAndroid Build Coastguard Worker char addressString[OT_IP6_ADDRESS_STRING_SIZE + 4];
140*cfb92d14SAndroid Build Coastguard Worker
141*cfb92d14SAndroid Build Coastguard Worker static_assert(0 == OT_HISTORY_TRACKER_ADDRESS_EVENT_ADDED, "ADDRESS_EVENT_ADDED is incorrect");
142*cfb92d14SAndroid Build Coastguard Worker static_assert(1 == OT_HISTORY_TRACKER_ADDRESS_EVENT_REMOVED, "ADDRESS_EVENT_REMOVED is incorrect");
143*cfb92d14SAndroid Build Coastguard Worker
144*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = ParseArgs(aArgs, isList, numEntries));
145*cfb92d14SAndroid Build Coastguard Worker
146*cfb92d14SAndroid Build Coastguard Worker if (!isList)
147*cfb92d14SAndroid Build Coastguard Worker {
148*cfb92d14SAndroid Build Coastguard Worker // | Age | Event | Address / PrefixLen /123 | Origin |Scope| P | V | R |
149*cfb92d14SAndroid Build Coastguard Worker // +----------------------+---------+---------------------------------------------+--------+-----+---+---+---+
150*cfb92d14SAndroid Build Coastguard Worker
151*cfb92d14SAndroid Build Coastguard Worker static const char *const kUnicastAddrInfoTitles[] = {
152*cfb92d14SAndroid Build Coastguard Worker "Age", "Event", "Address / PrefixLength", "Origin", "Scope", "P", "V", "R"};
153*cfb92d14SAndroid Build Coastguard Worker
154*cfb92d14SAndroid Build Coastguard Worker static const uint8_t kUnicastAddrInfoColumnWidths[] = {22, 9, 45, 8, 5, 3, 3, 3};
155*cfb92d14SAndroid Build Coastguard Worker
156*cfb92d14SAndroid Build Coastguard Worker OutputTableHeader(kUnicastAddrInfoTitles, kUnicastAddrInfoColumnWidths);
157*cfb92d14SAndroid Build Coastguard Worker }
158*cfb92d14SAndroid Build Coastguard Worker
159*cfb92d14SAndroid Build Coastguard Worker otHistoryTrackerInitIterator(&iterator);
160*cfb92d14SAndroid Build Coastguard Worker
161*cfb92d14SAndroid Build Coastguard Worker for (uint16_t index = 0; (numEntries == 0) || (index < numEntries); index++)
162*cfb92d14SAndroid Build Coastguard Worker {
163*cfb92d14SAndroid Build Coastguard Worker info = otHistoryTrackerIterateUnicastAddressHistory(GetInstancePtr(), &iterator, &entryAge);
164*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(info != nullptr);
165*cfb92d14SAndroid Build Coastguard Worker
166*cfb92d14SAndroid Build Coastguard Worker otHistoryTrackerEntryAgeToString(entryAge, ageString, sizeof(ageString));
167*cfb92d14SAndroid Build Coastguard Worker otIp6AddressToString(&info->mAddress, addressString, sizeof(addressString));
168*cfb92d14SAndroid Build Coastguard Worker
169*cfb92d14SAndroid Build Coastguard Worker if (!isList)
170*cfb92d14SAndroid Build Coastguard Worker {
171*cfb92d14SAndroid Build Coastguard Worker size_t len = strlen(addressString);
172*cfb92d14SAndroid Build Coastguard Worker
173*cfb92d14SAndroid Build Coastguard Worker snprintf(&addressString[len], sizeof(addressString) - len, "/%d", info->mPrefixLength);
174*cfb92d14SAndroid Build Coastguard Worker
175*cfb92d14SAndroid Build Coastguard Worker OutputLine("| %20s | %-7s | %-43s | %-6s | %3d | %c | %c | %c |", ageString,
176*cfb92d14SAndroid Build Coastguard Worker Stringify(info->mEvent, kSimpleEventStrings), addressString,
177*cfb92d14SAndroid Build Coastguard Worker Interpreter::AddressOriginToString(info->mAddressOrigin), info->mScope,
178*cfb92d14SAndroid Build Coastguard Worker info->mPreferred ? 'Y' : 'N', info->mValid ? 'Y' : 'N', info->mRloc ? 'Y' : 'N');
179*cfb92d14SAndroid Build Coastguard Worker }
180*cfb92d14SAndroid Build Coastguard Worker else
181*cfb92d14SAndroid Build Coastguard Worker {
182*cfb92d14SAndroid Build Coastguard Worker OutputLine("%s -> event:%s address:%s prefixlen:%d origin:%s scope:%d preferred:%s valid:%s rloc:%s",
183*cfb92d14SAndroid Build Coastguard Worker ageString, Stringify(info->mEvent, kSimpleEventStrings), addressString, info->mPrefixLength,
184*cfb92d14SAndroid Build Coastguard Worker Interpreter::AddressOriginToString(info->mAddressOrigin), info->mScope,
185*cfb92d14SAndroid Build Coastguard Worker info->mPreferred ? "yes" : "no", info->mValid ? "yes" : "no", info->mRloc ? "yes" : "no");
186*cfb92d14SAndroid Build Coastguard Worker }
187*cfb92d14SAndroid Build Coastguard Worker }
188*cfb92d14SAndroid Build Coastguard Worker
189*cfb92d14SAndroid Build Coastguard Worker exit:
190*cfb92d14SAndroid Build Coastguard Worker return error;
191*cfb92d14SAndroid Build Coastguard Worker }
192*cfb92d14SAndroid Build Coastguard Worker
193*cfb92d14SAndroid Build Coastguard Worker /**
194*cfb92d14SAndroid Build Coastguard Worker * @cli history ipmaddr
195*cfb92d14SAndroid Build Coastguard Worker * @code
196*cfb92d14SAndroid Build Coastguard Worker * history ipmaddr
197*cfb92d14SAndroid Build Coastguard Worker * | Age | Event | Multicast Address | Origin |
198*cfb92d14SAndroid Build Coastguard Worker * +----------------------+--------------+-----------------------------------------+--------+
199*cfb92d14SAndroid Build Coastguard Worker * | 00:00:08.592 | Unsubscribed | ff05:0:0:0:0:0:0:1 | Manual |
200*cfb92d14SAndroid Build Coastguard Worker * | 00:01:25.353 | Subscribed | ff05:0:0:0:0:0:0:1 | Manual |
201*cfb92d14SAndroid Build Coastguard Worker * | 00:01:54.953 | Subscribed | ff03:0:0:0:0:0:0:2 | Thread |
202*cfb92d14SAndroid Build Coastguard Worker * | 00:01:54.953 | Subscribed | ff02:0:0:0:0:0:0:2 | Thread |
203*cfb92d14SAndroid Build Coastguard Worker * | 00:01:59.329 | Subscribed | ff33:40:fdde:ad00:beef:0:0:1 | Thread |
204*cfb92d14SAndroid Build Coastguard Worker * | 00:01:59.329 | Subscribed | ff32:40:fdde:ad00:beef:0:0:1 | Thread |
205*cfb92d14SAndroid Build Coastguard Worker * | 00:02:01.129 | Subscribed | ff03:0:0:0:0:0:0:fc | Thread |
206*cfb92d14SAndroid Build Coastguard Worker * | 00:02:01.129 | Subscribed | ff03:0:0:0:0:0:0:1 | Thread |
207*cfb92d14SAndroid Build Coastguard Worker * | 00:02:01.129 | Subscribed | ff02:0:0:0:0:0:0:1 | Thread |
208*cfb92d14SAndroid Build Coastguard Worker * Done
209*cfb92d14SAndroid Build Coastguard Worker * @endcode
210*cfb92d14SAndroid Build Coastguard Worker * @code
211*cfb92d14SAndroid Build Coastguard Worker * history ipmaddr list
212*cfb92d14SAndroid Build Coastguard Worker * 00:00:25.447 -> event:Unsubscribed address:ff05:0:0:0:0:0:0:1 origin:Manual
213*cfb92d14SAndroid Build Coastguard Worker * 00:01:42.208 -> event:Subscribed address:ff05:0:0:0:0:0:0:1 origin:Manual
214*cfb92d14SAndroid Build Coastguard Worker * 00:02:11.808 -> event:Subscribed address:ff03:0:0:0:0:0:0:2 origin:Thread
215*cfb92d14SAndroid Build Coastguard Worker * 00:02:11.808 -> event:Subscribed address:ff02:0:0:0:0:0:0:2 origin:Thread
216*cfb92d14SAndroid Build Coastguard Worker * 00:02:16.184 -> event:Subscribed address:ff33:40:fdde:ad00:beef:0:0:1 origin:Thread
217*cfb92d14SAndroid Build Coastguard Worker * 00:02:16.184 -> event:Subscribed address:ff32:40:fdde:ad00:beef:0:0:1 origin:Thread
218*cfb92d14SAndroid Build Coastguard Worker * 00:02:17.984 -> event:Subscribed address:ff03:0:0:0:0:0:0:fc origin:Thread
219*cfb92d14SAndroid Build Coastguard Worker * 00:02:17.984 -> event:Subscribed address:ff03:0:0:0:0:0:0:1 origin:Thread
220*cfb92d14SAndroid Build Coastguard Worker * 00:02:17.984 -> event:Subscribed address:ff02:0:0:0:0:0:0:1 origin:Thread
221*cfb92d14SAndroid Build Coastguard Worker * Done
222*cfb92d14SAndroid Build Coastguard Worker * @endcode
223*cfb92d14SAndroid Build Coastguard Worker * @cparam history ipmaddr [@ca{list}] [@ca{num-entries}]
224*cfb92d14SAndroid Build Coastguard Worker * * Use the `list` option to display the output in list format. Otherwise,
225*cfb92d14SAndroid Build Coastguard Worker * the output is shown in table format.
226*cfb92d14SAndroid Build Coastguard Worker * * Use the `num-entries` option to limit the output to the number of
227*cfb92d14SAndroid Build Coastguard Worker * most-recent entries specified. If this option is not used, all stored
228*cfb92d14SAndroid Build Coastguard Worker * entries are shown in the output.
229*cfb92d14SAndroid Build Coastguard Worker * @par
230*cfb92d14SAndroid Build Coastguard Worker * Displays the multicast IPv6 address history in table or list format.
231*cfb92d14SAndroid Build Coastguard Worker * @par
232*cfb92d14SAndroid Build Coastguard Worker * Each table or list entry provides:
233*cfb92d14SAndroid Build Coastguard Worker * * Age: Time elapsed since the command was issued, and given in the format:
234*cfb92d14SAndroid Build Coastguard Worker * `hours`:`minutes`:`seconds`:`milliseconds`
235*cfb92d14SAndroid Build Coastguard Worker * * Event: Possible values are `Subscribed` or `Unsubscribed`.
236*cfb92d14SAndroid Build Coastguard Worker * * Multicast Address
237*cfb92d14SAndroid Build Coastguard Worker * * Origin: Possible values are `Thread` or `Manual`.
238*cfb92d14SAndroid Build Coastguard Worker * @sa otHistoryTrackerEntryAgeToString
239*cfb92d14SAndroid Build Coastguard Worker * @sa otHistoryTrackerIterateMulticastAddressHistory
240*cfb92d14SAndroid Build Coastguard Worker */
Process(Arg aArgs[])241*cfb92d14SAndroid Build Coastguard Worker template <> otError History::Process<Cmd("ipmaddr")>(Arg aArgs[])
242*cfb92d14SAndroid Build Coastguard Worker {
243*cfb92d14SAndroid Build Coastguard Worker static const char *const kEventStrings[] = {
244*cfb92d14SAndroid Build Coastguard Worker "Subscribed", // (0) OT_HISTORY_TRACKER_ADDRESS_EVENT_ADDED
245*cfb92d14SAndroid Build Coastguard Worker "Unsubscribed" // (1) OT_HISTORY_TRACKER_ADDRESS_EVENT_REMOVED
246*cfb92d14SAndroid Build Coastguard Worker };
247*cfb92d14SAndroid Build Coastguard Worker
248*cfb92d14SAndroid Build Coastguard Worker otError error;
249*cfb92d14SAndroid Build Coastguard Worker bool isList;
250*cfb92d14SAndroid Build Coastguard Worker uint16_t numEntries;
251*cfb92d14SAndroid Build Coastguard Worker otHistoryTrackerIterator iterator;
252*cfb92d14SAndroid Build Coastguard Worker const otHistoryTrackerMulticastAddressInfo *info;
253*cfb92d14SAndroid Build Coastguard Worker uint32_t entryAge;
254*cfb92d14SAndroid Build Coastguard Worker char ageString[OT_HISTORY_TRACKER_ENTRY_AGE_STRING_SIZE];
255*cfb92d14SAndroid Build Coastguard Worker char addressString[OT_IP6_ADDRESS_STRING_SIZE];
256*cfb92d14SAndroid Build Coastguard Worker
257*cfb92d14SAndroid Build Coastguard Worker static_assert(0 == OT_HISTORY_TRACKER_ADDRESS_EVENT_ADDED, "ADDRESS_EVENT_ADDED is incorrect");
258*cfb92d14SAndroid Build Coastguard Worker static_assert(1 == OT_HISTORY_TRACKER_ADDRESS_EVENT_REMOVED, "ADDRESS_EVENT_REMOVED is incorrect");
259*cfb92d14SAndroid Build Coastguard Worker
260*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = ParseArgs(aArgs, isList, numEntries));
261*cfb92d14SAndroid Build Coastguard Worker
262*cfb92d14SAndroid Build Coastguard Worker if (!isList)
263*cfb92d14SAndroid Build Coastguard Worker {
264*cfb92d14SAndroid Build Coastguard Worker // | Age | Event | Multicast Address | Origin |
265*cfb92d14SAndroid Build Coastguard Worker // +----------------------+--------------+-----------------------------------------+--------+
266*cfb92d14SAndroid Build Coastguard Worker
267*cfb92d14SAndroid Build Coastguard Worker static const char *const kMulticastAddrInfoTitles[] = {
268*cfb92d14SAndroid Build Coastguard Worker "Age",
269*cfb92d14SAndroid Build Coastguard Worker "Event",
270*cfb92d14SAndroid Build Coastguard Worker "Multicast Address",
271*cfb92d14SAndroid Build Coastguard Worker "Origin",
272*cfb92d14SAndroid Build Coastguard Worker };
273*cfb92d14SAndroid Build Coastguard Worker
274*cfb92d14SAndroid Build Coastguard Worker static const uint8_t kMulticastAddrInfoColumnWidths[] = {22, 14, 42, 8};
275*cfb92d14SAndroid Build Coastguard Worker
276*cfb92d14SAndroid Build Coastguard Worker OutputTableHeader(kMulticastAddrInfoTitles, kMulticastAddrInfoColumnWidths);
277*cfb92d14SAndroid Build Coastguard Worker }
278*cfb92d14SAndroid Build Coastguard Worker
279*cfb92d14SAndroid Build Coastguard Worker otHistoryTrackerInitIterator(&iterator);
280*cfb92d14SAndroid Build Coastguard Worker
281*cfb92d14SAndroid Build Coastguard Worker for (uint16_t index = 0; (numEntries == 0) || (index < numEntries); index++)
282*cfb92d14SAndroid Build Coastguard Worker {
283*cfb92d14SAndroid Build Coastguard Worker info = otHistoryTrackerIterateMulticastAddressHistory(GetInstancePtr(), &iterator, &entryAge);
284*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(info != nullptr);
285*cfb92d14SAndroid Build Coastguard Worker
286*cfb92d14SAndroid Build Coastguard Worker otHistoryTrackerEntryAgeToString(entryAge, ageString, sizeof(ageString));
287*cfb92d14SAndroid Build Coastguard Worker otIp6AddressToString(&info->mAddress, addressString, sizeof(addressString));
288*cfb92d14SAndroid Build Coastguard Worker
289*cfb92d14SAndroid Build Coastguard Worker OutputLine(isList ? "%s -> event:%s address:%s origin:%s" : "| %20s | %-12s | %-39s | %-6s |", ageString,
290*cfb92d14SAndroid Build Coastguard Worker Stringify(info->mEvent, kEventStrings), addressString,
291*cfb92d14SAndroid Build Coastguard Worker Interpreter::AddressOriginToString(info->mAddressOrigin));
292*cfb92d14SAndroid Build Coastguard Worker }
293*cfb92d14SAndroid Build Coastguard Worker
294*cfb92d14SAndroid Build Coastguard Worker exit:
295*cfb92d14SAndroid Build Coastguard Worker return error;
296*cfb92d14SAndroid Build Coastguard Worker }
297*cfb92d14SAndroid Build Coastguard Worker
298*cfb92d14SAndroid Build Coastguard Worker /**
299*cfb92d14SAndroid Build Coastguard Worker * @cli history neighbor
300*cfb92d14SAndroid Build Coastguard Worker * @code
301*cfb92d14SAndroid Build Coastguard Worker * history neighbor
302*cfb92d14SAndroid Build Coastguard Worker * | Age | Type | Event | Extended Address | RLOC16 | Mode | Ave RSS |
303*cfb92d14SAndroid Build Coastguard Worker * +----------------------+--------+-----------+------------------+--------+------+---------+
304*cfb92d14SAndroid Build Coastguard Worker * | 00:00:29.233 | Child | Added | ae5105292f0b9169 | 0x8404 | - | -20 |
305*cfb92d14SAndroid Build Coastguard Worker * | 00:01:38.368 | Child | Removed | ae5105292f0b9169 | 0x8401 | - | -20 |
306*cfb92d14SAndroid Build Coastguard Worker * | 00:04:27.181 | Child | Changed | ae5105292f0b9169 | 0x8401 | - | -20 |
307*cfb92d14SAndroid Build Coastguard Worker * | 00:04:51.236 | Router | Added | 865c7ca38a5fa960 | 0x9400 | rdn | -20 |
308*cfb92d14SAndroid Build Coastguard Worker * | 00:04:51.587 | Child | Removed | 865c7ca38a5fa960 | 0x8402 | rdn | -20 |
309*cfb92d14SAndroid Build Coastguard Worker * | 00:05:22.764 | Child | Changed | ae5105292f0b9169 | 0x8401 | rn | -20 |
310*cfb92d14SAndroid Build Coastguard Worker * | 00:06:40.764 | Child | Added | 4ec99efc874a1841 | 0x8403 | r | -20 |
311*cfb92d14SAndroid Build Coastguard Worker * | 00:06:44.060 | Child | Added | 865c7ca38a5fa960 | 0x8402 | rdn | -20 |
312*cfb92d14SAndroid Build Coastguard Worker * | 00:06:49.515 | Child | Added | ae5105292f0b9169 | 0x8401 | - | -20 |
313*cfb92d14SAndroid Build Coastguard Worker * Done
314*cfb92d14SAndroid Build Coastguard Worker * @endcode
315*cfb92d14SAndroid Build Coastguard Worker * @code
316*cfb92d14SAndroid Build Coastguard Worker * history neighbor list
317*cfb92d14SAndroid Build Coastguard Worker * 00:00:34.753 -> type:Child event:Added extaddr:ae5105292f0b9169 rloc16:0x8404 mode:- rss:-20
318*cfb92d14SAndroid Build Coastguard Worker * 00:01:43.888 -> type:Child event:Removed extaddr:ae5105292f0b9169 rloc16:0x8401 mode:- rss:-20
319*cfb92d14SAndroid Build Coastguard Worker * 00:04:32.701 -> type:Child event:Changed extaddr:ae5105292f0b9169 rloc16:0x8401 mode:- rss:-20
320*cfb92d14SAndroid Build Coastguard Worker * 00:04:56.756 -> type:Router event:Added extaddr:865c7ca38a5fa960 rloc16:0x9400 mode:rdn rss:-20
321*cfb92d14SAndroid Build Coastguard Worker * 00:04:57.107 -> type:Child event:Removed extaddr:865c7ca38a5fa960 rloc16:0x8402 mode:rdn rss:-20
322*cfb92d14SAndroid Build Coastguard Worker * 00:05:28.284 -> type:Child event:Changed extaddr:ae5105292f0b9169 rloc16:0x8401 mode:rn rss:-20
323*cfb92d14SAndroid Build Coastguard Worker * 00:06:46.284 -> type:Child event:Added extaddr:4ec99efc874a1841 rloc16:0x8403 mode:r rss:-20
324*cfb92d14SAndroid Build Coastguard Worker * 00:06:49.580 -> type:Child event:Added extaddr:865c7ca38a5fa960 rloc16:0x8402 mode:rdn rss:-20
325*cfb92d14SAndroid Build Coastguard Worker * 00:06:55.035 -> type:Child event:Added extaddr:ae5105292f0b9169 rloc16:0x8401 mode:- rss:-20
326*cfb92d14SAndroid Build Coastguard Worker * Done
327*cfb92d14SAndroid Build Coastguard Worker * @endcode
328*cfb92d14SAndroid Build Coastguard Worker * @cparam history neighbor [@ca{list}] [@ca{num-entries}]
329*cfb92d14SAndroid Build Coastguard Worker * * Use the `list` option to display the output in list format. Otherwise,
330*cfb92d14SAndroid Build Coastguard Worker * the output is shown in table format.
331*cfb92d14SAndroid Build Coastguard Worker * * Use the `num-entries` option to limit the output to the number of
332*cfb92d14SAndroid Build Coastguard Worker * most-recent entries specified. If this option is not used, all stored
333*cfb92d14SAndroid Build Coastguard Worker * entries are shown in the output.
334*cfb92d14SAndroid Build Coastguard Worker * @par
335*cfb92d14SAndroid Build Coastguard Worker * Displays the neighbor history in table or list format.
336*cfb92d14SAndroid Build Coastguard Worker * @par
337*cfb92d14SAndroid Build Coastguard Worker * Each table or list entry provides:
338*cfb92d14SAndroid Build Coastguard Worker * * Age: Time elapsed since the command was issued, and given in the format:
339*cfb92d14SAndroid Build Coastguard Worker * `hours`:`minutes`:`seconds`:`milliseconds`
340*cfb92d14SAndroid Build Coastguard Worker * * Type: `Child` or `Router`.
341*cfb92d14SAndroid Build Coastguard Worker * * Event: Possible values are `Added`, `Removed`, or `Changed`.
342*cfb92d14SAndroid Build Coastguard Worker * * Extended Address
343*cfb92d14SAndroid Build Coastguard Worker * * RLOC16
344*cfb92d14SAndroid Build Coastguard Worker * * Mode: MLE link mode. Possible values:
345*cfb92d14SAndroid Build Coastguard Worker * * `-`: no flags set (rx-off-when-idle, minimal Thread device,
346*cfb92d14SAndroid Build Coastguard Worker * stable network data).
347*cfb92d14SAndroid Build Coastguard Worker * * `r`: rx-on-when-idle
348*cfb92d14SAndroid Build Coastguard Worker * * `d`: Full Thread Device.
349*cfb92d14SAndroid Build Coastguard Worker * * `n`: Full Network Data
350*cfb92d14SAndroid Build Coastguard Worker * * Ave RSS: Average number of frames (in dBm) received from the neighbor at the
351*cfb92d14SAndroid Build Coastguard Worker * time the entry was recorded.
352*cfb92d14SAndroid Build Coastguard Worker * @sa otHistoryTrackerIterateNeighborHistory
353*cfb92d14SAndroid Build Coastguard Worker */
Process(Arg aArgs[])354*cfb92d14SAndroid Build Coastguard Worker template <> otError History::Process<Cmd("neighbor")>(Arg aArgs[])
355*cfb92d14SAndroid Build Coastguard Worker {
356*cfb92d14SAndroid Build Coastguard Worker static const char *const kEventString[] = {
357*cfb92d14SAndroid Build Coastguard Worker /* (0) OT_HISTORY_TRACKER_NEIGHBOR_EVENT_ADDED -> */ "Added",
358*cfb92d14SAndroid Build Coastguard Worker /* (1) OT_HISTORY_TRACKER_NEIGHBOR_EVENT_REMOVED -> */ "Removed",
359*cfb92d14SAndroid Build Coastguard Worker /* (2) OT_HISTORY_TRACKER_NEIGHBOR_EVENT_CHANGED -> */ "Changed",
360*cfb92d14SAndroid Build Coastguard Worker /* (3) OT_HISTORY_TRACKER_NEIGHBOR_EVENT_RESTORING -> */ "Restoring",
361*cfb92d14SAndroid Build Coastguard Worker };
362*cfb92d14SAndroid Build Coastguard Worker
363*cfb92d14SAndroid Build Coastguard Worker otError error;
364*cfb92d14SAndroid Build Coastguard Worker bool isList;
365*cfb92d14SAndroid Build Coastguard Worker uint16_t numEntries;
366*cfb92d14SAndroid Build Coastguard Worker otHistoryTrackerIterator iterator;
367*cfb92d14SAndroid Build Coastguard Worker const otHistoryTrackerNeighborInfo *info;
368*cfb92d14SAndroid Build Coastguard Worker uint32_t entryAge;
369*cfb92d14SAndroid Build Coastguard Worker char ageString[OT_HISTORY_TRACKER_ENTRY_AGE_STRING_SIZE];
370*cfb92d14SAndroid Build Coastguard Worker otLinkModeConfig mode;
371*cfb92d14SAndroid Build Coastguard Worker char linkModeString[Interpreter::kLinkModeStringSize];
372*cfb92d14SAndroid Build Coastguard Worker
373*cfb92d14SAndroid Build Coastguard Worker static_assert(0 == OT_HISTORY_TRACKER_NEIGHBOR_EVENT_ADDED, "NEIGHBOR_EVENT_ADDED value is incorrect");
374*cfb92d14SAndroid Build Coastguard Worker static_assert(1 == OT_HISTORY_TRACKER_NEIGHBOR_EVENT_REMOVED, "NEIGHBOR_EVENT_REMOVED value is incorrect");
375*cfb92d14SAndroid Build Coastguard Worker static_assert(2 == OT_HISTORY_TRACKER_NEIGHBOR_EVENT_CHANGED, "NEIGHBOR_EVENT_CHANGED value is incorrect");
376*cfb92d14SAndroid Build Coastguard Worker static_assert(3 == OT_HISTORY_TRACKER_NEIGHBOR_EVENT_RESTORING, "NEIGHBOR_EVENT_RESTORING value is incorrect");
377*cfb92d14SAndroid Build Coastguard Worker
378*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = ParseArgs(aArgs, isList, numEntries));
379*cfb92d14SAndroid Build Coastguard Worker
380*cfb92d14SAndroid Build Coastguard Worker if (!isList)
381*cfb92d14SAndroid Build Coastguard Worker {
382*cfb92d14SAndroid Build Coastguard Worker // | Age | Type | Event | Extended Address | RLOC16 | Mode | Ave RSS |
383*cfb92d14SAndroid Build Coastguard Worker // +----------------------+--------+-----------+------------------+--------+------+---------+
384*cfb92d14SAndroid Build Coastguard Worker
385*cfb92d14SAndroid Build Coastguard Worker static const char *const kNeighborInfoTitles[] = {
386*cfb92d14SAndroid Build Coastguard Worker "Age", "Type", "Event", "Extended Address", "RLOC16", "Mode", "Ave RSS",
387*cfb92d14SAndroid Build Coastguard Worker };
388*cfb92d14SAndroid Build Coastguard Worker
389*cfb92d14SAndroid Build Coastguard Worker static const uint8_t kNeighborInfoColumnWidths[] = {22, 8, 11, 18, 8, 6, 9};
390*cfb92d14SAndroid Build Coastguard Worker
391*cfb92d14SAndroid Build Coastguard Worker OutputTableHeader(kNeighborInfoTitles, kNeighborInfoColumnWidths);
392*cfb92d14SAndroid Build Coastguard Worker }
393*cfb92d14SAndroid Build Coastguard Worker
394*cfb92d14SAndroid Build Coastguard Worker otHistoryTrackerInitIterator(&iterator);
395*cfb92d14SAndroid Build Coastguard Worker
396*cfb92d14SAndroid Build Coastguard Worker for (uint16_t index = 0; (numEntries == 0) || (index < numEntries); index++)
397*cfb92d14SAndroid Build Coastguard Worker {
398*cfb92d14SAndroid Build Coastguard Worker info = otHistoryTrackerIterateNeighborHistory(GetInstancePtr(), &iterator, &entryAge);
399*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(info != nullptr);
400*cfb92d14SAndroid Build Coastguard Worker
401*cfb92d14SAndroid Build Coastguard Worker otHistoryTrackerEntryAgeToString(entryAge, ageString, sizeof(ageString));
402*cfb92d14SAndroid Build Coastguard Worker
403*cfb92d14SAndroid Build Coastguard Worker mode.mRxOnWhenIdle = info->mRxOnWhenIdle;
404*cfb92d14SAndroid Build Coastguard Worker mode.mDeviceType = info->mFullThreadDevice;
405*cfb92d14SAndroid Build Coastguard Worker mode.mNetworkData = info->mFullNetworkData;
406*cfb92d14SAndroid Build Coastguard Worker Interpreter::LinkModeToString(mode, linkModeString);
407*cfb92d14SAndroid Build Coastguard Worker
408*cfb92d14SAndroid Build Coastguard Worker OutputFormat(isList ? "%s -> type:%s event:%s extaddr:" : "| %20s | %-6s | %-9s | ", ageString,
409*cfb92d14SAndroid Build Coastguard Worker info->mIsChild ? "Child" : "Router", kEventString[info->mEvent]);
410*cfb92d14SAndroid Build Coastguard Worker OutputExtAddress(info->mExtAddress);
411*cfb92d14SAndroid Build Coastguard Worker OutputLine(isList ? " rloc16:0x%04x mode:%s rss:%d" : " | 0x%04x | %-4s | %7d |", info->mRloc16, linkModeString,
412*cfb92d14SAndroid Build Coastguard Worker info->mAverageRssi);
413*cfb92d14SAndroid Build Coastguard Worker }
414*cfb92d14SAndroid Build Coastguard Worker
415*cfb92d14SAndroid Build Coastguard Worker exit:
416*cfb92d14SAndroid Build Coastguard Worker return error;
417*cfb92d14SAndroid Build Coastguard Worker }
418*cfb92d14SAndroid Build Coastguard Worker
419*cfb92d14SAndroid Build Coastguard Worker /**
420*cfb92d14SAndroid Build Coastguard Worker * @cli history router
421*cfb92d14SAndroid Build Coastguard Worker * @code
422*cfb92d14SAndroid Build Coastguard Worker * history router
423*cfb92d14SAndroid Build Coastguard Worker * | Age | Event | ID (RLOC16) | Next Hop | Path Cost |
424*cfb92d14SAndroid Build Coastguard Worker * +----------------------+----------------+-------------+-------------+------------+
425*cfb92d14SAndroid Build Coastguard Worker * | 00:00:05.258 | NextHopChanged | 7 (0x1c00) | 34 (0x8800) | inf -> 3 |
426*cfb92d14SAndroid Build Coastguard Worker * | 00:00:08.604 | NextHopChanged | 34 (0x8800) | 34 (0x8800) | inf -> 2 |
427*cfb92d14SAndroid Build Coastguard Worker * | 00:00:08.604 | Added | 7 (0x1c00) | none | inf -> inf |
428*cfb92d14SAndroid Build Coastguard Worker * | 00:00:11.931 | Added | 34 (0x8800) | none | inf -> inf |
429*cfb92d14SAndroid Build Coastguard Worker * | 00:00:14.948 | Removed | 59 (0xec00) | none | inf -> inf |
430*cfb92d14SAndroid Build Coastguard Worker * | 00:00:14.948 | Removed | 54 (0xd800) | none | inf -> inf |
431*cfb92d14SAndroid Build Coastguard Worker * | 00:00:14.948 | Removed | 34 (0x8800) | none | inf -> inf |
432*cfb92d14SAndroid Build Coastguard Worker * | 00:00:14.948 | Removed | 7 (0x1c00) | none | inf -> inf |
433*cfb92d14SAndroid Build Coastguard Worker * | 00:00:54.795 | NextHopChanged | 59 (0xec00) | 34 (0x8800) | 1 -> 5 |
434*cfb92d14SAndroid Build Coastguard Worker * | 00:02:33.735 | NextHopChanged | 54 (0xd800) | none | 15 -> inf |
435*cfb92d14SAndroid Build Coastguard Worker * | 00:03:10.915 | CostChanged | 54 (0xd800) | 34 (0x8800) | 13 -> 15 |
436*cfb92d14SAndroid Build Coastguard Worker * | 00:03:45.716 | NextHopChanged | 54 (0xd800) | 34 (0x8800) | 15 -> 13 |
437*cfb92d14SAndroid Build Coastguard Worker * | 00:03:46.188 | CostChanged | 54 (0xd800) | 59 (0xec00) | 13 -> 15 |
438*cfb92d14SAndroid Build Coastguard Worker * | 00:04:19.124 | CostChanged | 54 (0xd800) | 59 (0xec00) | 11 -> 13 |
439*cfb92d14SAndroid Build Coastguard Worker * | 00:04:52.008 | CostChanged | 54 (0xd800) | 59 (0xec00) | 9 -> 11 |
440*cfb92d14SAndroid Build Coastguard Worker * | 00:05:23.176 | CostChanged | 54 (0xd800) | 59 (0xec00) | 7 -> 9 |
441*cfb92d14SAndroid Build Coastguard Worker * | 00:05:51.081 | CostChanged | 54 (0xd800) | 59 (0xec00) | 5 -> 7 |
442*cfb92d14SAndroid Build Coastguard Worker * | 00:06:48.721 | CostChanged | 54 (0xd800) | 59 (0xec00) | 3 -> 5 |
443*cfb92d14SAndroid Build Coastguard Worker * | 00:07:13.792 | NextHopChanged | 54 (0xd800) | 59 (0xec00) | 1 -> 3 |
444*cfb92d14SAndroid Build Coastguard Worker * | 00:09:28.681 | NextHopChanged | 7 (0x1c00) | 34 (0x8800) | inf -> 3 |
445*cfb92d14SAndroid Build Coastguard Worker * | 00:09:31.882 | Added | 7 (0x1c00) | none | inf -> inf |
446*cfb92d14SAndroid Build Coastguard Worker * | 00:09:51.240 | NextHopChanged | 54 (0xd800) | 54 (0xd800) | inf -> 1 |
447*cfb92d14SAndroid Build Coastguard Worker * | 00:09:54.204 | Added | 54 (0xd800) | none | inf -> inf |
448*cfb92d14SAndroid Build Coastguard Worker * | 00:10:20.645 | NextHopChanged | 34 (0x8800) | 34 (0x8800) | inf -> 2 |
449*cfb92d14SAndroid Build Coastguard Worker * | 00:10:24.242 | NextHopChanged | 59 (0xec00) | 59 (0xec00) | inf -> 1 |
450*cfb92d14SAndroid Build Coastguard Worker * | 00:10:24.242 | Added | 34 (0x8800) | none | inf -> inf |
451*cfb92d14SAndroid Build Coastguard Worker * | 00:10:41.900 | NextHopChanged | 59 (0xec00) | none | 1 -> inf |
452*cfb92d14SAndroid Build Coastguard Worker * | 00:10:42.480 | Added | 3 (0x0c00) | 3 (0x0c00) | inf -> inf |
453*cfb92d14SAndroid Build Coastguard Worker * | 00:10:43.614 | Added | 59 (0xec00) | 59 (0xec00) | inf -> 1 |
454*cfb92d14SAndroid Build Coastguard Worker * Done
455*cfb92d14SAndroid Build Coastguard Worker * @endcode
456*cfb92d14SAndroid Build Coastguard Worker * @code
457*cfb92d14SAndroid Build Coastguard Worker * history router list 20
458*cfb92d14SAndroid Build Coastguard Worker * 00:00:06.959 -> event:NextHopChanged router:7(0x1c00) nexthop:34(0x8800) old-cost:inf new-cost:3
459*cfb92d14SAndroid Build Coastguard Worker * 00:00:10.305 -> event:NextHopChanged router:34(0x8800) nexthop:34(0x8800) old-cost:inf new-cost:2
460*cfb92d14SAndroid Build Coastguard Worker * 00:00:10.305 -> event:Added router:7(0x1c00) nexthop:none old-cost:inf new-cost:inf
461*cfb92d14SAndroid Build Coastguard Worker * 00:00:13.632 -> event:Added router:34(0x8800) nexthop:none old-cost:inf new-cost:inf
462*cfb92d14SAndroid Build Coastguard Worker * 00:00:16.649 -> event:Removed router:59(0xec00) nexthop:none old-cost:inf new-cost:inf
463*cfb92d14SAndroid Build Coastguard Worker * 00:00:16.649 -> event:Removed router:54(0xd800) nexthop:none old-cost:inf new-cost:inf
464*cfb92d14SAndroid Build Coastguard Worker * 00:00:16.649 -> event:Removed router:34(0x8800) nexthop:none old-cost:inf new-cost:inf
465*cfb92d14SAndroid Build Coastguard Worker * 00:00:16.649 -> event:Removed router:7(0x1c00) nexthop:none old-cost:inf new-cost:inf
466*cfb92d14SAndroid Build Coastguard Worker * 00:00:56.496 -> event:NextHopChanged router:59(0xec00) nexthop:34(0x8800) old-cost:1 new-cost:5
467*cfb92d14SAndroid Build Coastguard Worker * 00:02:35.436 -> event:NextHopChanged router:54(0xd800) nexthop:none old-cost:15 new-cost:inf
468*cfb92d14SAndroid Build Coastguard Worker * 00:03:12.616 -> event:CostChanged router:54(0xd800) nexthop:34(0x8800) old-cost:13 new-cost:15
469*cfb92d14SAndroid Build Coastguard Worker * 00:03:47.417 -> event:NextHopChanged router:54(0xd800) nexthop:34(0x8800) old-cost:15 new-cost:13
470*cfb92d14SAndroid Build Coastguard Worker * 00:03:47.889 -> event:CostChanged router:54(0xd800) nexthop:59(0xec00) old-cost:13 new-cost:15
471*cfb92d14SAndroid Build Coastguard Worker * 00:04:20.825 -> event:CostChanged router:54(0xd800) nexthop:59(0xec00) old-cost:11 new-cost:13
472*cfb92d14SAndroid Build Coastguard Worker * 00:04:53.709 -> event:CostChanged router:54(0xd800) nexthop:59(0xec00) old-cost:9 new-cost:11
473*cfb92d14SAndroid Build Coastguard Worker * 00:05:24.877 -> event:CostChanged router:54(0xd800) nexthop:59(0xec00) old-cost:7 new-cost:9
474*cfb92d14SAndroid Build Coastguard Worker * 00:05:52.782 -> event:CostChanged router:54(0xd800) nexthop:59(0xec00) old-cost:5 new-cost:7
475*cfb92d14SAndroid Build Coastguard Worker * 00:06:50.422 -> event:CostChanged router:54(0xd800) nexthop:59(0xec00) old-cost:3 new-cost:5
476*cfb92d14SAndroid Build Coastguard Worker * 00:07:15.493 -> event:NextHopChanged router:54(0xd800) nexthop:59(0xec00) old-cost:1 new-cost:3
477*cfb92d14SAndroid Build Coastguard Worker * 00:09:30.382 -> event:NextHopChanged router:7(0x1c00) nexthop:34(0x8800) old-cost:inf new-cost:3
478*cfb92d14SAndroid Build Coastguard Worker * Done
479*cfb92d14SAndroid Build Coastguard Worker * @endcode
480*cfb92d14SAndroid Build Coastguard Worker * @cparam history router [@ca{list}] [@ca{num-entries}]
481*cfb92d14SAndroid Build Coastguard Worker * * Use the `list` option to display the output in list format. Otherwise,
482*cfb92d14SAndroid Build Coastguard Worker * the output is shown in table format.
483*cfb92d14SAndroid Build Coastguard Worker * * Use the `num-entries` option to limit the output to the number of
484*cfb92d14SAndroid Build Coastguard Worker * most-recent entries specified. If this option is not used, all stored
485*cfb92d14SAndroid Build Coastguard Worker * entries are shown in the output.
486*cfb92d14SAndroid Build Coastguard Worker * @par
487*cfb92d14SAndroid Build Coastguard Worker * Displays the route-table history in table or list format.
488*cfb92d14SAndroid Build Coastguard Worker * @par
489*cfb92d14SAndroid Build Coastguard Worker * Each table or list entry provides:
490*cfb92d14SAndroid Build Coastguard Worker * * Age: Time elapsed since the command was issued, and given in the format:
491*cfb92d14SAndroid Build Coastguard Worker * `hours`:`minutes`:`seconds`:`milliseconds`
492*cfb92d14SAndroid Build Coastguard Worker * * Event: Possible values are `Added`, `Removed`, `NextHopChanged`, or `CostChanged`.
493*cfb92d14SAndroid Build Coastguard Worker * * ID (RLOC16): Router ID and RLOC16 of the router.
494*cfb92d14SAndroid Build Coastguard Worker * * Next Hop: Router ID and RLOC16 of the next hop. If there is no next hop,
495*cfb92d14SAndroid Build Coastguard Worker * `none` is shown.
496*cfb92d14SAndroid Build Coastguard Worker * * Path Cost: old cost `->` new cost. A value of `inf` indicates an infinite
497*cfb92d14SAndroid Build Coastguard Worker * path cost.
498*cfb92d14SAndroid Build Coastguard Worker * @sa otHistoryTrackerIterateRouterHistory
499*cfb92d14SAndroid Build Coastguard Worker */
Process(Arg aArgs[])500*cfb92d14SAndroid Build Coastguard Worker template <> otError History::Process<Cmd("router")>(Arg aArgs[])
501*cfb92d14SAndroid Build Coastguard Worker {
502*cfb92d14SAndroid Build Coastguard Worker static const char *const kEventString[] = {
503*cfb92d14SAndroid Build Coastguard Worker /* (0) OT_HISTORY_TRACKER_ROUTER_EVENT_ADDED -> */ "Added",
504*cfb92d14SAndroid Build Coastguard Worker /* (1) OT_HISTORY_TRACKER_ROUTER_EVENT_REMOVED -> */ "Removed",
505*cfb92d14SAndroid Build Coastguard Worker /* (2) OT_HISTORY_TRACKER_ROUTER_EVENT_NEXT_HOP_CHANGED -> */ "NextHopChanged",
506*cfb92d14SAndroid Build Coastguard Worker /* (3) OT_HISTORY_TRACKER_ROUTER_EVENT_COST_CHANGED -> */ "CostChanged",
507*cfb92d14SAndroid Build Coastguard Worker };
508*cfb92d14SAndroid Build Coastguard Worker
509*cfb92d14SAndroid Build Coastguard Worker constexpr uint8_t kRouterIdOffset = 10; // Bit offset of Router ID in RLOC16
510*cfb92d14SAndroid Build Coastguard Worker
511*cfb92d14SAndroid Build Coastguard Worker otError error;
512*cfb92d14SAndroid Build Coastguard Worker bool isList;
513*cfb92d14SAndroid Build Coastguard Worker uint16_t numEntries;
514*cfb92d14SAndroid Build Coastguard Worker otHistoryTrackerIterator iterator;
515*cfb92d14SAndroid Build Coastguard Worker const otHistoryTrackerRouterInfo *info;
516*cfb92d14SAndroid Build Coastguard Worker uint32_t entryAge;
517*cfb92d14SAndroid Build Coastguard Worker char ageString[OT_HISTORY_TRACKER_ENTRY_AGE_STRING_SIZE];
518*cfb92d14SAndroid Build Coastguard Worker
519*cfb92d14SAndroid Build Coastguard Worker static_assert(0 == OT_HISTORY_TRACKER_ROUTER_EVENT_ADDED, "EVENT_ADDED is incorrect");
520*cfb92d14SAndroid Build Coastguard Worker static_assert(1 == OT_HISTORY_TRACKER_ROUTER_EVENT_REMOVED, "EVENT_REMOVED is incorrect");
521*cfb92d14SAndroid Build Coastguard Worker static_assert(2 == OT_HISTORY_TRACKER_ROUTER_EVENT_NEXT_HOP_CHANGED, "EVENT_NEXT_HOP_CHANGED is incorrect");
522*cfb92d14SAndroid Build Coastguard Worker static_assert(3 == OT_HISTORY_TRACKER_ROUTER_EVENT_COST_CHANGED, "EVENT_COST_CHANGED is incorrect");
523*cfb92d14SAndroid Build Coastguard Worker
524*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = ParseArgs(aArgs, isList, numEntries));
525*cfb92d14SAndroid Build Coastguard Worker
526*cfb92d14SAndroid Build Coastguard Worker if (!isList)
527*cfb92d14SAndroid Build Coastguard Worker {
528*cfb92d14SAndroid Build Coastguard Worker // | Age | Event | ID (RlOC16) | Next Hop | Path Cost |
529*cfb92d14SAndroid Build Coastguard Worker // +----------------------+----------------+-------------+------------+-------------+
530*cfb92d14SAndroid Build Coastguard Worker
531*cfb92d14SAndroid Build Coastguard Worker static const char *const kRouterInfoTitles[] = {
532*cfb92d14SAndroid Build Coastguard Worker "Age", "Event", "ID (RLOC16)", "Next Hop", "Path Cost",
533*cfb92d14SAndroid Build Coastguard Worker };
534*cfb92d14SAndroid Build Coastguard Worker
535*cfb92d14SAndroid Build Coastguard Worker static const uint8_t kRouterInfoColumnWidths[] = {22, 16, 13, 13, 12};
536*cfb92d14SAndroid Build Coastguard Worker
537*cfb92d14SAndroid Build Coastguard Worker OutputTableHeader(kRouterInfoTitles, kRouterInfoColumnWidths);
538*cfb92d14SAndroid Build Coastguard Worker }
539*cfb92d14SAndroid Build Coastguard Worker
540*cfb92d14SAndroid Build Coastguard Worker otHistoryTrackerInitIterator(&iterator);
541*cfb92d14SAndroid Build Coastguard Worker
542*cfb92d14SAndroid Build Coastguard Worker for (uint16_t index = 0; (numEntries == 0) || (index < numEntries); index++)
543*cfb92d14SAndroid Build Coastguard Worker {
544*cfb92d14SAndroid Build Coastguard Worker info = otHistoryTrackerIterateRouterHistory(GetInstancePtr(), &iterator, &entryAge);
545*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(info != nullptr);
546*cfb92d14SAndroid Build Coastguard Worker
547*cfb92d14SAndroid Build Coastguard Worker otHistoryTrackerEntryAgeToString(entryAge, ageString, sizeof(ageString));
548*cfb92d14SAndroid Build Coastguard Worker
549*cfb92d14SAndroid Build Coastguard Worker OutputFormat(isList ? "%s -> event:%s router:%u(0x%04x) nexthop:" : "| %20s | %-14s | %2u (0x%04x) | ",
550*cfb92d14SAndroid Build Coastguard Worker ageString, kEventString[info->mEvent], info->mRouterId,
551*cfb92d14SAndroid Build Coastguard Worker static_cast<uint16_t>(info->mRouterId) << kRouterIdOffset);
552*cfb92d14SAndroid Build Coastguard Worker
553*cfb92d14SAndroid Build Coastguard Worker if (info->mNextHop != OT_HISTORY_TRACKER_NO_NEXT_HOP)
554*cfb92d14SAndroid Build Coastguard Worker {
555*cfb92d14SAndroid Build Coastguard Worker OutputFormat(isList ? "%u(0x%04x)" : "%2u (0x%04x)", info->mNextHop,
556*cfb92d14SAndroid Build Coastguard Worker static_cast<uint16_t>(info->mNextHop) << kRouterIdOffset);
557*cfb92d14SAndroid Build Coastguard Worker }
558*cfb92d14SAndroid Build Coastguard Worker else
559*cfb92d14SAndroid Build Coastguard Worker {
560*cfb92d14SAndroid Build Coastguard Worker OutputFormat(isList ? "%s" : "%11s", "none");
561*cfb92d14SAndroid Build Coastguard Worker }
562*cfb92d14SAndroid Build Coastguard Worker
563*cfb92d14SAndroid Build Coastguard Worker if (info->mOldPathCost != OT_HISTORY_TRACKER_INFINITE_PATH_COST)
564*cfb92d14SAndroid Build Coastguard Worker {
565*cfb92d14SAndroid Build Coastguard Worker OutputFormat(isList ? " old-cost:%u" : " | %3u ->", info->mOldPathCost);
566*cfb92d14SAndroid Build Coastguard Worker }
567*cfb92d14SAndroid Build Coastguard Worker else
568*cfb92d14SAndroid Build Coastguard Worker {
569*cfb92d14SAndroid Build Coastguard Worker OutputFormat(isList ? " old-cost:inf" : " | inf ->");
570*cfb92d14SAndroid Build Coastguard Worker }
571*cfb92d14SAndroid Build Coastguard Worker
572*cfb92d14SAndroid Build Coastguard Worker if (info->mPathCost != OT_HISTORY_TRACKER_INFINITE_PATH_COST)
573*cfb92d14SAndroid Build Coastguard Worker {
574*cfb92d14SAndroid Build Coastguard Worker OutputLine(isList ? " new-cost:%u" : " %3u |", info->mPathCost);
575*cfb92d14SAndroid Build Coastguard Worker }
576*cfb92d14SAndroid Build Coastguard Worker else
577*cfb92d14SAndroid Build Coastguard Worker {
578*cfb92d14SAndroid Build Coastguard Worker OutputLine(isList ? " new-cost:inf" : " inf |");
579*cfb92d14SAndroid Build Coastguard Worker }
580*cfb92d14SAndroid Build Coastguard Worker }
581*cfb92d14SAndroid Build Coastguard Worker
582*cfb92d14SAndroid Build Coastguard Worker exit:
583*cfb92d14SAndroid Build Coastguard Worker return error;
584*cfb92d14SAndroid Build Coastguard Worker }
585*cfb92d14SAndroid Build Coastguard Worker
586*cfb92d14SAndroid Build Coastguard Worker /**
587*cfb92d14SAndroid Build Coastguard Worker * @cli history netinfo
588*cfb92d14SAndroid Build Coastguard Worker * @code
589*cfb92d14SAndroid Build Coastguard Worker * history netinfo
590*cfb92d14SAndroid Build Coastguard Worker * | Age | Role | Mode | RLOC16 | Partition ID |
591*cfb92d14SAndroid Build Coastguard Worker * +----------------------+----------+------+--------+--------------+
592*cfb92d14SAndroid Build Coastguard Worker * | 00:00:10.069 | router | rdn | 0x6000 | 151029327 |
593*cfb92d14SAndroid Build Coastguard Worker * | 00:02:09.337 | child | rdn | 0x2001 | 151029327 |
594*cfb92d14SAndroid Build Coastguard Worker * | 00:02:09.338 | child | rdn | 0x2001 | 151029327 |
595*cfb92d14SAndroid Build Coastguard Worker * | 00:07:40.806 | child | - | 0x2001 | 151029327 |
596*cfb92d14SAndroid Build Coastguard Worker * | 00:07:42.297 | detached | - | 0x6000 | 0 |
597*cfb92d14SAndroid Build Coastguard Worker * | 00:07:42.968 | disabled | - | 0x6000 | 0 |
598*cfb92d14SAndroid Build Coastguard Worker * Done
599*cfb92d14SAndroid Build Coastguard Worker * @endcode
600*cfb92d14SAndroid Build Coastguard Worker * @code
601*cfb92d14SAndroid Build Coastguard Worker * history netinfo list
602*cfb92d14SAndroid Build Coastguard Worker * 00:00:59.467 -> role:router mode:rdn rloc16:0x6000 partition-id:151029327
603*cfb92d14SAndroid Build Coastguard Worker * 00:02:58.735 -> role:child mode:rdn rloc16:0x2001 partition-id:151029327
604*cfb92d14SAndroid Build Coastguard Worker * 00:02:58.736 -> role:child mode:rdn rloc16:0x2001 partition-id:151029327
605*cfb92d14SAndroid Build Coastguard Worker * 00:08:30.204 -> role:child mode:- rloc16:0x2001 partition-id:151029327
606*cfb92d14SAndroid Build Coastguard Worker * 00:08:31.695 -> role:detached mode:- rloc16:0x6000 partition-id:0
607*cfb92d14SAndroid Build Coastguard Worker * 00:08:32.366 -> role:disabled mode:- rloc16:0x6000 partition-id:0
608*cfb92d14SAndroid Build Coastguard Worker * Done
609*cfb92d14SAndroid Build Coastguard Worker * @endcode
610*cfb92d14SAndroid Build Coastguard Worker * @code
611*cfb92d14SAndroid Build Coastguard Worker * history netinfo 2
612*cfb92d14SAndroid Build Coastguard Worker * | Age | Role | Mode | RLOC16 | Partition ID |
613*cfb92d14SAndroid Build Coastguard Worker * +----------------------+----------+------+--------+--------------+
614*cfb92d14SAndroid Build Coastguard Worker * | 00:02:05.451 | router | rdn | 0x6000 | 151029327 |
615*cfb92d14SAndroid Build Coastguard Worker * | 00:04:04.719 | child | rdn | 0x2001 | 151029327 |
616*cfb92d14SAndroid Build Coastguard Worker * Done
617*cfb92d14SAndroid Build Coastguard Worker * @endcode
618*cfb92d14SAndroid Build Coastguard Worker * @cparam history netinfo [@ca{list}] [@ca{num-entries}]
619*cfb92d14SAndroid Build Coastguard Worker * * Use the `list` option to display the output in list format. Otherwise,
620*cfb92d14SAndroid Build Coastguard Worker * the output is shown in table format.
621*cfb92d14SAndroid Build Coastguard Worker * * Use the `num-entries` option to limit the output to the number of
622*cfb92d14SAndroid Build Coastguard Worker * most-recent entries specified. If this option is not used, all stored
623*cfb92d14SAndroid Build Coastguard Worker * entries are shown in the output.
624*cfb92d14SAndroid Build Coastguard Worker * @par
625*cfb92d14SAndroid Build Coastguard Worker * Displays the network info history in table or list format.
626*cfb92d14SAndroid Build Coastguard Worker * @par
627*cfb92d14SAndroid Build Coastguard Worker * Each table or list entry provides:
628*cfb92d14SAndroid Build Coastguard Worker * * Age: Time elapsed since the command was issued, and given in the format:
629*cfb92d14SAndroid Build Coastguard Worker * `hours`:`minutes`:`seconds`:`milliseconds`
630*cfb92d14SAndroid Build Coastguard Worker * * Role: Device role. Possible values are `router`, `child`, `detached`, or `disabled`.
631*cfb92d14SAndroid Build Coastguard Worker * * Mode: MLE link mode. Possible values:
632*cfb92d14SAndroid Build Coastguard Worker * * `-`: no flags set (rx-off-when-idle, minimal Thread device,
633*cfb92d14SAndroid Build Coastguard Worker * stable network data).
634*cfb92d14SAndroid Build Coastguard Worker * * `r`: rx-on-when-idle
635*cfb92d14SAndroid Build Coastguard Worker * * `d`: Full Thread Device.
636*cfb92d14SAndroid Build Coastguard Worker * * `n`: Full Network Data
637*cfb92d14SAndroid Build Coastguard Worker * * RLOC16
638*cfb92d14SAndroid Build Coastguard Worker * * Partition ID.
639*cfb92d14SAndroid Build Coastguard Worker * @sa otHistoryTrackerIterateNetInfoHistory
640*cfb92d14SAndroid Build Coastguard Worker */
Process(Arg aArgs[])641*cfb92d14SAndroid Build Coastguard Worker template <> otError History::Process<Cmd("netinfo")>(Arg aArgs[])
642*cfb92d14SAndroid Build Coastguard Worker {
643*cfb92d14SAndroid Build Coastguard Worker otError error;
644*cfb92d14SAndroid Build Coastguard Worker bool isList;
645*cfb92d14SAndroid Build Coastguard Worker uint16_t numEntries;
646*cfb92d14SAndroid Build Coastguard Worker otHistoryTrackerIterator iterator;
647*cfb92d14SAndroid Build Coastguard Worker const otHistoryTrackerNetworkInfo *info;
648*cfb92d14SAndroid Build Coastguard Worker uint32_t entryAge;
649*cfb92d14SAndroid Build Coastguard Worker char ageString[OT_HISTORY_TRACKER_ENTRY_AGE_STRING_SIZE];
650*cfb92d14SAndroid Build Coastguard Worker char linkModeString[Interpreter::kLinkModeStringSize];
651*cfb92d14SAndroid Build Coastguard Worker
652*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = ParseArgs(aArgs, isList, numEntries));
653*cfb92d14SAndroid Build Coastguard Worker
654*cfb92d14SAndroid Build Coastguard Worker if (!isList)
655*cfb92d14SAndroid Build Coastguard Worker {
656*cfb92d14SAndroid Build Coastguard Worker // | Age | Role | Mode | RLOC16 | Partition ID |
657*cfb92d14SAndroid Build Coastguard Worker // +----------------------+----------+------+--------+--------------+
658*cfb92d14SAndroid Build Coastguard Worker
659*cfb92d14SAndroid Build Coastguard Worker static const char *const kNetInfoTitles[] = {"Age", "Role", "Mode", "RLOC16", "Partition ID"};
660*cfb92d14SAndroid Build Coastguard Worker static const uint8_t kNetInfoColumnWidths[] = {22, 10, 6, 8, 14};
661*cfb92d14SAndroid Build Coastguard Worker
662*cfb92d14SAndroid Build Coastguard Worker OutputTableHeader(kNetInfoTitles, kNetInfoColumnWidths);
663*cfb92d14SAndroid Build Coastguard Worker }
664*cfb92d14SAndroid Build Coastguard Worker
665*cfb92d14SAndroid Build Coastguard Worker otHistoryTrackerInitIterator(&iterator);
666*cfb92d14SAndroid Build Coastguard Worker
667*cfb92d14SAndroid Build Coastguard Worker for (uint16_t index = 0; (numEntries == 0) || (index < numEntries); index++)
668*cfb92d14SAndroid Build Coastguard Worker {
669*cfb92d14SAndroid Build Coastguard Worker info = otHistoryTrackerIterateNetInfoHistory(GetInstancePtr(), &iterator, &entryAge);
670*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(info != nullptr);
671*cfb92d14SAndroid Build Coastguard Worker
672*cfb92d14SAndroid Build Coastguard Worker otHistoryTrackerEntryAgeToString(entryAge, ageString, sizeof(ageString));
673*cfb92d14SAndroid Build Coastguard Worker
674*cfb92d14SAndroid Build Coastguard Worker OutputLine(
675*cfb92d14SAndroid Build Coastguard Worker isList ? "%s -> role:%s mode:%s rloc16:0x%04x partition-id:%lu" : "| %20s | %-8s | %-4s | 0x%04x | %12lu |",
676*cfb92d14SAndroid Build Coastguard Worker ageString, otThreadDeviceRoleToString(info->mRole),
677*cfb92d14SAndroid Build Coastguard Worker Interpreter::LinkModeToString(info->mMode, linkModeString), info->mRloc16, ToUlong(info->mPartitionId));
678*cfb92d14SAndroid Build Coastguard Worker }
679*cfb92d14SAndroid Build Coastguard Worker
680*cfb92d14SAndroid Build Coastguard Worker exit:
681*cfb92d14SAndroid Build Coastguard Worker return error;
682*cfb92d14SAndroid Build Coastguard Worker }
683*cfb92d14SAndroid Build Coastguard Worker
684*cfb92d14SAndroid Build Coastguard Worker /**
685*cfb92d14SAndroid Build Coastguard Worker * @cli history rx
686*cfb92d14SAndroid Build Coastguard Worker * @code
687*cfb92d14SAndroid Build Coastguard Worker * history rx
688*cfb92d14SAndroid Build Coastguard Worker * | Age | Type | Len | Chksum | Sec | Prio | RSS |Dir | Neighb | Radio |
689*cfb92d14SAndroid Build Coastguard Worker * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
690*cfb92d14SAndroid Build Coastguard Worker * | | UDP | 50 | 0xbd26 | no | net | -20 | RX | 0x4800 | 15.4 |
691*cfb92d14SAndroid Build Coastguard Worker * | 00:00:07.640 | src: [fe80:0:0:0:d03d:d3e7:cc5e:7cd7]:19788 |
692*cfb92d14SAndroid Build Coastguard Worker * | | dst: [ff02:0:0:0:0:0:0:1]:19788 |
693*cfb92d14SAndroid Build Coastguard Worker * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
694*cfb92d14SAndroid Build Coastguard Worker * | | HopOpts | 44 | 0x0000 | yes | norm | -20 | RX | 0x4800 | 15.4 |
695*cfb92d14SAndroid Build Coastguard Worker * | 00:00:09.263 | src: [fdde:ad00:beef:0:0:ff:fe00:4800]:0 |
696*cfb92d14SAndroid Build Coastguard Worker * | | dst: [ff03:0:0:0:0:0:0:2]:0 |
697*cfb92d14SAndroid Build Coastguard Worker * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
698*cfb92d14SAndroid Build Coastguard Worker * | | UDP | 12 | 0x3f7d | yes | net | -20 | RX | 0x4800 | 15.4 |
699*cfb92d14SAndroid Build Coastguard Worker * | 00:00:09.302 | src: [fdde:ad00:beef:0:0:ff:fe00:4800]:61631 |
700*cfb92d14SAndroid Build Coastguard Worker * | | dst: [fdde:ad00:beef:0:0:ff:fe00:4801]:61631 |
701*cfb92d14SAndroid Build Coastguard Worker * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
702*cfb92d14SAndroid Build Coastguard Worker * | | ICMP6(EchoReqst) | 16 | 0x942c | yes | norm | -20 | RX | 0x4800 | 15.4 |
703*cfb92d14SAndroid Build Coastguard Worker * | 00:00:09.304 | src: [fdde:ad00:beef:0:ac09:a16b:3204:dc09]:0 |
704*cfb92d14SAndroid Build Coastguard Worker * | | dst: [fdde:ad00:beef:0:dc0e:d6b3:f180:b75b]:0 |
705*cfb92d14SAndroid Build Coastguard Worker * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
706*cfb92d14SAndroid Build Coastguard Worker * | | HopOpts | 44 | 0x0000 | yes | norm | -20 | RX | 0x4800 | 15.4 |
707*cfb92d14SAndroid Build Coastguard Worker * | 00:00:09.304 | src: [fdde:ad00:beef:0:0:ff:fe00:4800]:0 |
708*cfb92d14SAndroid Build Coastguard Worker * | | dst: [ff03:0:0:0:0:0:0:2]:0 |
709*cfb92d14SAndroid Build Coastguard Worker * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
710*cfb92d14SAndroid Build Coastguard Worker * | | UDP | 50 | 0x2e37 | no | net | -20 | RX | 0x4800 | 15.4 |
711*cfb92d14SAndroid Build Coastguard Worker * | 00:00:21.622 | src: [fe80:0:0:0:d03d:d3e7:cc5e:7cd7]:19788 |
712*cfb92d14SAndroid Build Coastguard Worker * | | dst: [ff02:0:0:0:0:0:0:1]:19788 |
713*cfb92d14SAndroid Build Coastguard Worker * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
714*cfb92d14SAndroid Build Coastguard Worker * | | UDP | 50 | 0xe177 | no | net | -20 | RX | 0x4800 | 15.4 |
715*cfb92d14SAndroid Build Coastguard Worker * | 00:00:26.640 | src: [fe80:0:0:0:d03d:d3e7:cc5e:7cd7]:19788 |
716*cfb92d14SAndroid Build Coastguard Worker * | | dst: [ff02:0:0:0:0:0:0:1]:19788 |
717*cfb92d14SAndroid Build Coastguard Worker * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
718*cfb92d14SAndroid Build Coastguard Worker * | | UDP | 165 | 0x82ee | yes | net | -20 | RX | 0x4800 | 15.4 |
719*cfb92d14SAndroid Build Coastguard Worker * | 00:00:30.000 | src: [fe80:0:0:0:d03d:d3e7:cc5e:7cd7]:19788 |
720*cfb92d14SAndroid Build Coastguard Worker * | | dst: [fe80:0:0:0:a4a5:bbac:a8e:bd07]:19788 |
721*cfb92d14SAndroid Build Coastguard Worker * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
722*cfb92d14SAndroid Build Coastguard Worker * | | UDP | 93 | 0x52df | no | net | -20 | RX | unknwn | 15.4 |
723*cfb92d14SAndroid Build Coastguard Worker * | 00:00:30.480 | src: [fe80:0:0:0:d03d:d3e7:cc5e:7cd7]:19788 |
724*cfb92d14SAndroid Build Coastguard Worker * | | dst: [fe80:0:0:0:a4a5:bbac:a8e:bd07]:19788 |
725*cfb92d14SAndroid Build Coastguard Worker * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
726*cfb92d14SAndroid Build Coastguard Worker * | | UDP | 50 | 0x5ccf | no | net | -20 | RX | unknwn | 15.4 |
727*cfb92d14SAndroid Build Coastguard Worker * | 00:00:30.772 | src: [fe80:0:0:0:d03d:d3e7:cc5e:7cd7]:19788 |
728*cfb92d14SAndroid Build Coastguard Worker * | | dst: [ff02:0:0:0:0:0:0:1]:19788 |
729*cfb92d14SAndroid Build Coastguard Worker * Done
730*cfb92d14SAndroid Build Coastguard Worker * @endcode
731*cfb92d14SAndroid Build Coastguard Worker * @code
732*cfb92d14SAndroid Build Coastguard Worker * history rx list 4
733*cfb92d14SAndroid Build Coastguard Worker * 00:00:13.368
734*cfb92d14SAndroid Build Coastguard Worker type:UDP len:50 checksum:0xbd26 sec:no prio:net rss:-20 from:0x4800 radio:15.4
735*cfb92d14SAndroid Build Coastguard Worker src:[fe80:0:0:0:d03d:d3e7:cc5e:7cd7]:19788
736*cfb92d14SAndroid Build Coastguard Worker dst:[ff02:0:0:0:0:0:0:1]:19788
737*cfb92d14SAndroid Build Coastguard Worker * 00:00:14.991
738*cfb92d14SAndroid Build Coastguard Worker type:HopOpts len:44 checksum:0x0000 sec:yes prio:norm rss:-20 from:0x4800 radio:15.4
739*cfb92d14SAndroid Build Coastguard Worker src:[fdde:ad00:beef:0:0:ff:fe00:4800]:0
740*cfb92d14SAndroid Build Coastguard Worker dst:[ff03:0:0:0:0:0:0:2]:0
741*cfb92d14SAndroid Build Coastguard Worker * 00:00:15.030
742*cfb92d14SAndroid Build Coastguard Worker type:UDP len:12 checksum:0x3f7d sec:yes prio:net rss:-20 from:0x4800 radio:15.4
743*cfb92d14SAndroid Build Coastguard Worker src:[fdde:ad00:beef:0:0:ff:fe00:4800]:61631
744*cfb92d14SAndroid Build Coastguard Worker dst:[fdde:ad00:beef:0:0:ff:fe00:4801]:61631
745*cfb92d14SAndroid Build Coastguard Worker * 00:00:15.032
746*cfb92d14SAndroid Build Coastguard Worker type:ICMP6(EchoReqst) len:16 checksum:0x942c sec:yes prio:norm rss:-20 from:0x4800 radio:15.4
747*cfb92d14SAndroid Build Coastguard Worker src:[fdde:ad00:beef:0:ac09:a16b:3204:dc09]:0
748*cfb92d14SAndroid Build Coastguard Worker dst:[fdde:ad00:beef:0:dc0e:d6b3:f180:b75b]:0
749*cfb92d14SAndroid Build Coastguard Worker * Done
750*cfb92d14SAndroid Build Coastguard Worker * @endcode
751*cfb92d14SAndroid Build Coastguard Worker * @cparam history rx [@ca{list}] [@ca{num-entries}]
752*cfb92d14SAndroid Build Coastguard Worker * * Use the `list` option to display the output in list format. Otherwise,
753*cfb92d14SAndroid Build Coastguard Worker * the output is shown in table format.
754*cfb92d14SAndroid Build Coastguard Worker * * Use the `num-entries` option to limit the output to the number of
755*cfb92d14SAndroid Build Coastguard Worker * most-recent entries specified. If this option is not used, all stored
756*cfb92d14SAndroid Build Coastguard Worker * entries are shown in the output.
757*cfb92d14SAndroid Build Coastguard Worker * @par
758*cfb92d14SAndroid Build Coastguard Worker * Displays the IPv6 message RX history in table or list format.
759*cfb92d14SAndroid Build Coastguard Worker * @par
760*cfb92d14SAndroid Build Coastguard Worker * Each table or list entry provides:
761*cfb92d14SAndroid Build Coastguard Worker * * Age: Time elapsed since the command was issued, and given in the format:
762*cfb92d14SAndroid Build Coastguard Worker * `hours`:`minutes`:`seconds`:`milliseconds`
763*cfb92d14SAndroid Build Coastguard Worker * * Type:
764*cfb92d14SAndroid Build Coastguard Worker * * IPv6 message type, such as `UDP`, `TCP`, `HopOpts`, and `ICMP6` (and its subtype).
765*cfb92d14SAndroid Build Coastguard Worker * * `src`: Source IPv6 address and port number.
766*cfb92d14SAndroid Build Coastguard Worker * * `dst`: Destination IPv6 address and port number (port number is valid
767*cfb92d14SAndroid Build Coastguard Worker for UDP/TCP, otherwise it is 0).
768*cfb92d14SAndroid Build Coastguard Worker * * Len: IPv6 payload length (excluding the IPv6 header).
769*cfb92d14SAndroid Build Coastguard Worker * * Chksum: Message checksum (valid for UDP, TCP, or ICMP6 messages).
770*cfb92d14SAndroid Build Coastguard Worker * * Sec: Indicates if link-layer security was used.
771*cfb92d14SAndroid Build Coastguard Worker * * Prio: Message priority. Possible values are `low`, `norm`, `high`, or
772*cfb92d14SAndroid Build Coastguard Worker * `net` (for Thread control messages).
773*cfb92d14SAndroid Build Coastguard Worker * * RSS: Received Signal Strength (in dBm), averaged over all received fragment
774*cfb92d14SAndroid Build Coastguard Worker * frames that formed the message. For TX history, `NA` (not applicable)
775*cfb92d14SAndroid Build Coastguard Worker is displayed.
776*cfb92d14SAndroid Build Coastguard Worker * * Dir: Shows whether the message was sent (`TX`) or received (`RX`). A failed
777*cfb92d14SAndroid Build Coastguard Worker * transmission is indicated with `TX-F` in table format or
778*cfb92d14SAndroid Build Coastguard Worker * `tx-success:no` in list format. Examples of a failed transmission
779*cfb92d14SAndroid Build Coastguard Worker * include a `tx`getting aborted and no `ack` getting sent from the peer for
780*cfb92d14SAndroid Build Coastguard Worker * any of the message fragments.
781*cfb92d14SAndroid Build Coastguard Worker * * Neighb: Short address (RLOC16) of the neighbor with whom the message was
782*cfb92d14SAndroid Build Coastguard Worker * sent/received. If the frame was broadcast, it is shown as
783*cfb92d14SAndroid Build Coastguard Worker * `bcast` in table format or `0xffff` in list format. If the short
784*cfb92d14SAndroid Build Coastguard Worker * address of the neighbor is not available, it is shown as `unknwn` in
785*cfb92d14SAndroid Build Coastguard Worker * table format or `0xfffe` in list format.
786*cfb92d14SAndroid Build Coastguard Worker * * Radio: Radio link on which the message was sent/received (useful when
787*cfb92d14SAndroid Build Coastguard Worker `OPENTHREAD_CONFIG_MULTI_RADIO` is enabled). Can be `15.4`, `trel`,
788*cfb92d14SAndroid Build Coastguard Worker or `all` (if sent on all radio links).
789*cfb92d14SAndroid Build Coastguard Worker * @sa otHistoryTrackerIterateRxHistory
790*cfb92d14SAndroid Build Coastguard Worker */
Process(Arg aArgs[])791*cfb92d14SAndroid Build Coastguard Worker template <> otError History::Process<Cmd("rx")>(Arg aArgs[]) { return ProcessRxTxHistory(kRx, aArgs); }
792*cfb92d14SAndroid Build Coastguard Worker
793*cfb92d14SAndroid Build Coastguard Worker /**
794*cfb92d14SAndroid Build Coastguard Worker * @cli history rxtx
795*cfb92d14SAndroid Build Coastguard Worker * @code
796*cfb92d14SAndroid Build Coastguard Worker * history rxtx
797*cfb92d14SAndroid Build Coastguard Worker * | Age | Type | Len | Chksum | Sec | Prio | RSS |Dir | Neighb | Radio |
798*cfb92d14SAndroid Build Coastguard Worker * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
799*cfb92d14SAndroid Build Coastguard Worker * | | HopOpts | 44 | 0x0000 | yes | norm | -20 | RX | 0x0800 | 15.4 |
800*cfb92d14SAndroid Build Coastguard Worker * | 00:00:09.267 | src: [fdde:ad00:beef:0:0:ff:fe00:800]:0 |
801*cfb92d14SAndroid Build Coastguard Worker * | | dst: [ff03:0:0:0:0:0:0:2]:0 |
802*cfb92d14SAndroid Build Coastguard Worker * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
803*cfb92d14SAndroid Build Coastguard Worker * | | UDP | 12 | 0x6c6b | yes | net | -20 | RX | 0x0800 | 15.4 |
804*cfb92d14SAndroid Build Coastguard Worker * | 00:00:09.290 | src: [fdde:ad00:beef:0:0:ff:fe00:800]:61631 |
805*cfb92d14SAndroid Build Coastguard Worker * | | dst: [fdde:ad00:beef:0:0:ff:fe00:801]:61631 |
806*cfb92d14SAndroid Build Coastguard Worker * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
807*cfb92d14SAndroid Build Coastguard Worker * | | ICMP6(EchoReqst) | 16 | 0xc6a2 | yes | norm | -20 | RX | 0x0800 | 15.4 |
808*cfb92d14SAndroid Build Coastguard Worker * | 00:00:09.292 | src: [fdde:ad00:beef:0:efe8:4910:cf95:dee9]:0 |
809*cfb92d14SAndroid Build Coastguard Worker * | | dst: [fdde:ad00:beef:0:af4c:3644:882a:3698]:0 |
810*cfb92d14SAndroid Build Coastguard Worker * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
811*cfb92d14SAndroid Build Coastguard Worker * | | ICMP6(EchoReply) | 16 | 0xc5a2 | yes | norm | NA | TX | 0x0800 | 15.4 |
812*cfb92d14SAndroid Build Coastguard Worker * | 00:00:09.292 | src: [fdde:ad00:beef:0:af4c:3644:882a:3698]:0 |
813*cfb92d14SAndroid Build Coastguard Worker * | | dst: [fdde:ad00:beef:0:efe8:4910:cf95:dee9]:0 |
814*cfb92d14SAndroid Build Coastguard Worker * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
815*cfb92d14SAndroid Build Coastguard Worker * | | UDP | 50 | 0xaa0d | yes | net | NA | TX | 0x0800 | 15.4 |
816*cfb92d14SAndroid Build Coastguard Worker * | 00:00:09.294 | src: [fdde:ad00:beef:0:0:ff:fe00:801]:61631 |
817*cfb92d14SAndroid Build Coastguard Worker * | | dst: [fdde:ad00:beef:0:0:ff:fe00:800]:61631 |
818*cfb92d14SAndroid Build Coastguard Worker * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
819*cfb92d14SAndroid Build Coastguard Worker * | | HopOpts | 44 | 0x0000 | yes | norm | -20 | RX | 0x0800 | 15.4 |
820*cfb92d14SAndroid Build Coastguard Worker * | 00:00:09.296 | src: [fdde:ad00:beef:0:0:ff:fe00:800]:0 |
821*cfb92d14SAndroid Build Coastguard Worker * | | dst: [ff03:0:0:0:0:0:0:2]:0 |
822*cfb92d14SAndroid Build Coastguard Worker * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
823*cfb92d14SAndroid Build Coastguard Worker * | | UDP | 50 | 0xc1d8 | no | net | -20 | RX | 0x0800 | 15.4 |
824*cfb92d14SAndroid Build Coastguard Worker * | 00:00:09.569 | src: [fe80:0:0:0:54d9:5153:ffc6:df26]:19788 |
825*cfb92d14SAndroid Build Coastguard Worker * | | dst: [ff02:0:0:0:0:0:0:1]:19788 |
826*cfb92d14SAndroid Build Coastguard Worker * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
827*cfb92d14SAndroid Build Coastguard Worker * | | UDP | 50 | 0x3cb1 | no | net | -20 | RX | 0x0800 | 15.4 |
828*cfb92d14SAndroid Build Coastguard Worker * | 00:00:16.519 | src: [fe80:0:0:0:54d9:5153:ffc6:df26]:19788 |
829*cfb92d14SAndroid Build Coastguard Worker * | | dst: [ff02:0:0:0:0:0:0:1]:19788 |
830*cfb92d14SAndroid Build Coastguard Worker * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
831*cfb92d14SAndroid Build Coastguard Worker * | | UDP | 50 | 0xeda0 | no | net | -20 | RX | 0x0800 | 15.4 |
832*cfb92d14SAndroid Build Coastguard Worker * | 00:00:20.599 | src: [fe80:0:0:0:54d9:5153:ffc6:df26]:19788 |
833*cfb92d14SAndroid Build Coastguard Worker * | | dst: [ff02:0:0:0:0:0:0:1]:19788 |
834*cfb92d14SAndroid Build Coastguard Worker * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
835*cfb92d14SAndroid Build Coastguard Worker * | | UDP | 165 | 0xbdfa | yes | net | -20 | RX | 0x0800 | 15.4 |
836*cfb92d14SAndroid Build Coastguard Worker * | 00:00:21.059 | src: [fe80:0:0:0:54d9:5153:ffc6:df26]:19788 |
837*cfb92d14SAndroid Build Coastguard Worker * | | dst: [fe80:0:0:0:8893:c2cc:d983:1e1c]:19788 |
838*cfb92d14SAndroid Build Coastguard Worker * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
839*cfb92d14SAndroid Build Coastguard Worker * | | UDP | 64 | 0x1c11 | no | net | NA | TX | 0x0800 | 15.4 |
840*cfb92d14SAndroid Build Coastguard Worker * | 00:00:21.062 | src: [fe80:0:0:0:8893:c2cc:d983:1e1c]:19788 |
841*cfb92d14SAndroid Build Coastguard Worker * | | dst: [fe80:0:0:0:54d9:5153:ffc6:df26]:19788 |
842*cfb92d14SAndroid Build Coastguard Worker * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
843*cfb92d14SAndroid Build Coastguard Worker * | | UDP | 93 | 0xedff | no | net | -20 | RX | unknwn | 15.4 |
844*cfb92d14SAndroid Build Coastguard Worker * | 00:00:21.474 | src: [fe80:0:0:0:54d9:5153:ffc6:df26]:19788 |
845*cfb92d14SAndroid Build Coastguard Worker * | | dst: [fe80:0:0:0:8893:c2cc:d983:1e1c]:19788 |
846*cfb92d14SAndroid Build Coastguard Worker * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
847*cfb92d14SAndroid Build Coastguard Worker * | | UDP | 44 | 0xd383 | no | net | NA | TX | bcast | 15.4 |
848*cfb92d14SAndroid Build Coastguard Worker * | 00:00:21.811 | src: [fe80:0:0:0:8893:c2cc:d983:1e1c]:19788 |
849*cfb92d14SAndroid Build Coastguard Worker * | | dst: [ff02:0:0:0:0:0:0:2]:19788 |
850*cfb92d14SAndroid Build Coastguard Worker * Done
851*cfb92d14SAndroid Build Coastguard Worker * @endcode
852*cfb92d14SAndroid Build Coastguard Worker * @code
853*cfb92d14SAndroid Build Coastguard Worker * history rxtx list 5
854*cfb92d14SAndroid Build Coastguard Worker * 00:00:02.100
855*cfb92d14SAndroid Build Coastguard Worker type:UDP len:50 checksum:0xd843 sec:no prio:net rss:-20 from:0x0800 radio:15.4
856*cfb92d14SAndroid Build Coastguard Worker src:[fe80:0:0:0:54d9:5153:ffc6:df26]:19788
857*cfb92d14SAndroid Build Coastguard Worker dst:[ff02:0:0:0:0:0:0:1]:19788
858*cfb92d14SAndroid Build Coastguard Worker * 00:00:15.331
859*cfb92d14SAndroid Build Coastguard Worker type:HopOpts len:44 checksum:0x0000 sec:yes prio:norm rss:-20 from:0x0800 radio:15.4
860*cfb92d14SAndroid Build Coastguard Worker src:[fdde:ad00:beef:0:0:ff:fe00:800]:0
861*cfb92d14SAndroid Build Coastguard Worker dst:[ff03:0:0:0:0:0:0:2]:0
862*cfb92d14SAndroid Build Coastguard Worker * 00:00:15.354
863*cfb92d14SAndroid Build Coastguard Worker type:UDP len:12 checksum:0x6c6b sec:yes prio:net rss:-20 from:0x0800 radio:15.4
864*cfb92d14SAndroid Build Coastguard Worker src:[fdde:ad00:beef:0:0:ff:fe00:800]:61631
865*cfb92d14SAndroid Build Coastguard Worker dst:[fdde:ad00:beef:0:0:ff:fe00:801]:61631
866*cfb92d14SAndroid Build Coastguard Worker * 00:00:15.356
867*cfb92d14SAndroid Build Coastguard Worker type:ICMP6(EchoReqst) len:16 checksum:0xc6a2 sec:yes prio:norm rss:-20 from:0x0800 radio:15.4
868*cfb92d14SAndroid Build Coastguard Worker src:[fdde:ad00:beef:0:efe8:4910:cf95:dee9]:0
869*cfb92d14SAndroid Build Coastguard Worker dst:[fdde:ad00:beef:0:af4c:3644:882a:3698]:0
870*cfb92d14SAndroid Build Coastguard Worker * 00:00:15.356
871*cfb92d14SAndroid Build Coastguard Worker type:ICMP6(EchoReply) len:16 checksum:0xc5a2 sec:yes prio:norm tx-success:yes to:0x0800 radio:15.4
872*cfb92d14SAndroid Build Coastguard Worker src:[fdde:ad00:beef:0:af4c:3644:882a:3698]:0
873*cfb92d14SAndroid Build Coastguard Worker dst:[fdde:ad00:beef:0:efe8:4910:cf95:dee9]:0
874*cfb92d14SAndroid Build Coastguard Worker * Done
875*cfb92d14SAndroid Build Coastguard Worker * @endcode
876*cfb92d14SAndroid Build Coastguard Worker * @cparam history rxtx [@ca{list}] [@ca{num-entries}]
877*cfb92d14SAndroid Build Coastguard Worker * * Use the `list` option to display the output in list format. Otherwise,
878*cfb92d14SAndroid Build Coastguard Worker * the output is shown in table format.
879*cfb92d14SAndroid Build Coastguard Worker * * Use the `num-entries` option to limit the output to the number of
880*cfb92d14SAndroid Build Coastguard Worker * most-recent entries specified. If this option is not used, all stored
881*cfb92d14SAndroid Build Coastguard Worker * entries are shown in the output.
882*cfb92d14SAndroid Build Coastguard Worker * @par
883*cfb92d14SAndroid Build Coastguard Worker * Displays the combined IPv6 message RX and TX history in table or list format.
884*cfb92d14SAndroid Build Coastguard Worker * @par
885*cfb92d14SAndroid Build Coastguard Worker * Each table or list entry provides:
886*cfb92d14SAndroid Build Coastguard Worker * * Age: Time elapsed since the command was issued, and given in the format:
887*cfb92d14SAndroid Build Coastguard Worker * `hours`:`minutes`:`seconds`:`milliseconds`
888*cfb92d14SAndroid Build Coastguard Worker * * Type:
889*cfb92d14SAndroid Build Coastguard Worker * * IPv6 message type, such as `UDP`, `TCP`, `HopOpts`, and `ICMP6` (and its subtype).
890*cfb92d14SAndroid Build Coastguard Worker * * `src`: Source IPv6 address and port number.
891*cfb92d14SAndroid Build Coastguard Worker * * `dst`: Destination IPv6 address and port number (port number is valid
892*cfb92d14SAndroid Build Coastguard Worker for UDP/TCP, otherwise it is 0).
893*cfb92d14SAndroid Build Coastguard Worker * * Len: IPv6 payload length (excluding the IPv6 header).
894*cfb92d14SAndroid Build Coastguard Worker * * Chksum: Message checksum (valid for UDP, TCP, or ICMP6 messages).
895*cfb92d14SAndroid Build Coastguard Worker * * Sec: Indicates if link-layer security was used.
896*cfb92d14SAndroid Build Coastguard Worker * * Prio: Message priority. Possible values are `low`, `norm`, `high`, or
897*cfb92d14SAndroid Build Coastguard Worker * `net` (for Thread control messages).
898*cfb92d14SAndroid Build Coastguard Worker * * RSS: Received Signal Strength (in dBm), averaged over all received fragment
899*cfb92d14SAndroid Build Coastguard Worker * frames that formed the message. For TX history, `NA` (not applicable)
900*cfb92d14SAndroid Build Coastguard Worker is displayed.
901*cfb92d14SAndroid Build Coastguard Worker * * Dir: Shows whether the message was sent (`TX`) or received (`RX`). A failed
902*cfb92d14SAndroid Build Coastguard Worker * transmission is indicated with `TX-F` in table format or
903*cfb92d14SAndroid Build Coastguard Worker * `tx-success:no` in list format. Examples of a failed transmission
904*cfb92d14SAndroid Build Coastguard Worker * include a `tx`getting aborted and no `ack` getting sent from the peer for
905*cfb92d14SAndroid Build Coastguard Worker * any of the message fragments.
906*cfb92d14SAndroid Build Coastguard Worker * * Neighb: Short address (RLOC16) of the neighbor with whom the message was
907*cfb92d14SAndroid Build Coastguard Worker * sent/received. If the frame was broadcast, it is shown as
908*cfb92d14SAndroid Build Coastguard Worker * `bcast` in table format or `0xffff` in list format. If the short
909*cfb92d14SAndroid Build Coastguard Worker * address of the neighbor is not available, it is shown as `unknwn` in
910*cfb92d14SAndroid Build Coastguard Worker * table format or `0xfffe` in list format.
911*cfb92d14SAndroid Build Coastguard Worker * * Radio: Radio link on which the message was sent/received (useful when
912*cfb92d14SAndroid Build Coastguard Worker `OPENTHREAD_CONFIG_MULTI_RADIO` is enabled). Can be `15.4`, `trel`,
913*cfb92d14SAndroid Build Coastguard Worker or `all` (if sent on all radio links).
914*cfb92d14SAndroid Build Coastguard Worker * @sa otHistoryTrackerIterateRxHistory
915*cfb92d14SAndroid Build Coastguard Worker * @sa otHistoryTrackerIterateTxHistory
916*cfb92d14SAndroid Build Coastguard Worker */
Process(Arg aArgs[])917*cfb92d14SAndroid Build Coastguard Worker template <> otError History::Process<Cmd("rxtx")>(Arg aArgs[]) { return ProcessRxTxHistory(kRxTx, aArgs); }
918*cfb92d14SAndroid Build Coastguard Worker
919*cfb92d14SAndroid Build Coastguard Worker /**
920*cfb92d14SAndroid Build Coastguard Worker * @cli history tx
921*cfb92d14SAndroid Build Coastguard Worker * @code
922*cfb92d14SAndroid Build Coastguard Worker * history tx
923*cfb92d14SAndroid Build Coastguard Worker * | Age | Type | Len | Chksum | Sec | Prio | RSS |Dir | Neighb | Radio |
924*cfb92d14SAndroid Build Coastguard Worker * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
925*cfb92d14SAndroid Build Coastguard Worker * | | ICMP6(EchoReply) | 16 | 0x932c | yes | norm | NA | TX | 0x4800 | 15.4 |
926*cfb92d14SAndroid Build Coastguard Worker * | 00:00:18.798 | src: [fdde:ad00:beef:0:dc0e:d6b3:f180:b75b]:0 |
927*cfb92d14SAndroid Build Coastguard Worker * | | dst: [fdde:ad00:beef:0:ac09:a16b:3204:dc09]:0 |
928*cfb92d14SAndroid Build Coastguard Worker * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
929*cfb92d14SAndroid Build Coastguard Worker * | | UDP | 50 | 0xce87 | yes | net | NA | TX | 0x4800 | 15.4 |
930*cfb92d14SAndroid Build Coastguard Worker * | 00:00:18.800 | src: [fdde:ad00:beef:0:0:ff:fe00:4801]:61631 |
931*cfb92d14SAndroid Build Coastguard Worker * | | dst: [fdde:ad00:beef:0:0:ff:fe00:4800]:61631 |
932*cfb92d14SAndroid Build Coastguard Worker * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
933*cfb92d14SAndroid Build Coastguard Worker * | | UDP | 64 | 0xf7ba | no | net | NA | TX | 0x4800 | 15.4 |
934*cfb92d14SAndroid Build Coastguard Worker * | 00:00:39.499 | src: [fe80:0:0:0:a4a5:bbac:a8e:bd07]:19788 |
935*cfb92d14SAndroid Build Coastguard Worker * | | dst: [fe80:0:0:0:d03d:d3e7:cc5e:7cd7]:19788 |
936*cfb92d14SAndroid Build Coastguard Worker * +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
937*cfb92d14SAndroid Build Coastguard Worker * | | UDP | 44 | 0x26d4 | no | net | NA | TX | bcast | 15.4 |
938*cfb92d14SAndroid Build Coastguard Worker * | 00:00:40.256 | src: [fe80:0:0:0:a4a5:bbac:a8e:bd07]:19788 |
939*cfb92d14SAndroid Build Coastguard Worker * | | dst: [ff02:0:0:0:0:0:0:2]:19788 |
940*cfb92d14SAndroid Build Coastguard Worker * Done
941*cfb92d14SAndroid Build Coastguard Worker * @endcode
942*cfb92d14SAndroid Build Coastguard Worker * @code
943*cfb92d14SAndroid Build Coastguard Worker * history tx list
944*cfb92d14SAndroid Build Coastguard Worker * 00:00:23.957
945*cfb92d14SAndroid Build Coastguard Worker type:ICMP6(EchoReply) len:16 checksum:0x932c sec:yes prio:norm tx-success:yes to:0x4800 radio:15.4
946*cfb92d14SAndroid Build Coastguard Worker src:[fdde:ad00:beef:0:dc0e:d6b3:f180:b75b]:0
947*cfb92d14SAndroid Build Coastguard Worker dst:[fdde:ad00:beef:0:ac09:a16b:3204:dc09]:0
948*cfb92d14SAndroid Build Coastguard Worker * 00:00:23.959
949*cfb92d14SAndroid Build Coastguard Worker type:UDP len:50 checksum:0xce87 sec:yes prio:net tx-success:yes to:0x4800 radio:15.4
950*cfb92d14SAndroid Build Coastguard Worker src:[fdde:ad00:beef:0:0:ff:fe00:4801]:61631
951*cfb92d14SAndroid Build Coastguard Worker dst:[fdde:ad00:beef:0:0:ff:fe00:4800]:61631
952*cfb92d14SAndroid Build Coastguard Worker * 00:00:44.658
953*cfb92d14SAndroid Build Coastguard Worker type:UDP len:64 checksum:0xf7ba sec:no prio:net tx-success:yes to:0x4800 radio:15.4
954*cfb92d14SAndroid Build Coastguard Worker src:[fe80:0:0:0:a4a5:bbac:a8e:bd07]:19788
955*cfb92d14SAndroid Build Coastguard Worker dst:[fe80:0:0:0:d03d:d3e7:cc5e:7cd7]:19788
956*cfb92d14SAndroid Build Coastguard Worker * 00:00:45.415
957*cfb92d14SAndroid Build Coastguard Worker type:UDP len:44 checksum:0x26d4 sec:no prio:net tx-success:yes to:0xffff radio:15.4
958*cfb92d14SAndroid Build Coastguard Worker src:[fe80:0:0:0:a4a5:bbac:a8e:bd07]:19788
959*cfb92d14SAndroid Build Coastguard Worker dst:[ff02:0:0:0:0:0:0:2]:19788
960*cfb92d14SAndroid Build Coastguard Worker * Done
961*cfb92d14SAndroid Build Coastguard Worker * @endcode
962*cfb92d14SAndroid Build Coastguard Worker * @cparam history tx [@ca{list}] [@ca{num-entries}]
963*cfb92d14SAndroid Build Coastguard Worker * * Use the `list` option to display the output in list format. Otherwise,
964*cfb92d14SAndroid Build Coastguard Worker * the output is shown in table format.
965*cfb92d14SAndroid Build Coastguard Worker * * Use the `num-entries` option to limit the output to the number of
966*cfb92d14SAndroid Build Coastguard Worker * most-recent entries specified. If this option is not used, all stored
967*cfb92d14SAndroid Build Coastguard Worker * entries are shown in the output.
968*cfb92d14SAndroid Build Coastguard Worker * @par
969*cfb92d14SAndroid Build Coastguard Worker * Displays the IPv6 message TX history in table or list format.
970*cfb92d14SAndroid Build Coastguard Worker * @par
971*cfb92d14SAndroid Build Coastguard Worker * Each table or list entry provides:
972*cfb92d14SAndroid Build Coastguard Worker * * Age: Time elapsed since the command was issued, and given in the format:
973*cfb92d14SAndroid Build Coastguard Worker * `hours`:`minutes`:`seconds`:`milliseconds`
974*cfb92d14SAndroid Build Coastguard Worker * * Type:
975*cfb92d14SAndroid Build Coastguard Worker * * IPv6 message type, such as `UDP`, `TCP`, `HopOpts`, and `ICMP6` (and its subtype).
976*cfb92d14SAndroid Build Coastguard Worker * * `src`: Source IPv6 address and port number.
977*cfb92d14SAndroid Build Coastguard Worker * * `dst`: Destination IPv6 address and port number (port number is valid
978*cfb92d14SAndroid Build Coastguard Worker for UDP/TCP, otherwise it is 0).
979*cfb92d14SAndroid Build Coastguard Worker * * Len: IPv6 payload length (excluding the IPv6 header).
980*cfb92d14SAndroid Build Coastguard Worker * * Chksum: Message checksum (valid for UDP, TCP, or ICMP6 messages).
981*cfb92d14SAndroid Build Coastguard Worker * * Sec: Indicates if link-layer security was used.
982*cfb92d14SAndroid Build Coastguard Worker * * Prio: Message priority. Possible values are `low`, `norm`, `high`, or
983*cfb92d14SAndroid Build Coastguard Worker * `net` (for Thread control messages).
984*cfb92d14SAndroid Build Coastguard Worker * * RSS: Received Signal Strength (in dBm), averaged over all received fragment
985*cfb92d14SAndroid Build Coastguard Worker * frames that formed the message. For TX history, `NA` (not applicable)
986*cfb92d14SAndroid Build Coastguard Worker is displayed.
987*cfb92d14SAndroid Build Coastguard Worker * * Dir: Shows whether the message was sent (`TX`) or received (`RX`). A failed
988*cfb92d14SAndroid Build Coastguard Worker * transmission is indicated with `TX-F` in table format or
989*cfb92d14SAndroid Build Coastguard Worker * `tx-success:no` in list format. Examples of a failed transmission
990*cfb92d14SAndroid Build Coastguard Worker * include a `tx`getting aborted and no `ack` getting sent from the peer for
991*cfb92d14SAndroid Build Coastguard Worker * any of the message fragments.
992*cfb92d14SAndroid Build Coastguard Worker * * Neighb: Short address (RLOC16) of the neighbor with whom the message was
993*cfb92d14SAndroid Build Coastguard Worker * sent/received. If the frame was broadcast, it is shown as
994*cfb92d14SAndroid Build Coastguard Worker * `bcast` in table format or `0xffff` in list format. If the short
995*cfb92d14SAndroid Build Coastguard Worker * address of the neighbor is not available, it is shown as `unknwn` in
996*cfb92d14SAndroid Build Coastguard Worker * table format or `0xfffe` in list format.
997*cfb92d14SAndroid Build Coastguard Worker * * Radio: Radio link on which the message was sent/received (useful when
998*cfb92d14SAndroid Build Coastguard Worker `OPENTHREAD_CONFIG_MULTI_RADIO` is enabled). Can be `15.4`, `trel`,
999*cfb92d14SAndroid Build Coastguard Worker or `all` (if sent on all radio links).
1000*cfb92d14SAndroid Build Coastguard Worker * @sa otHistoryTrackerIterateTxHistory
1001*cfb92d14SAndroid Build Coastguard Worker */
Process(Arg aArgs[])1002*cfb92d14SAndroid Build Coastguard Worker template <> otError History::Process<Cmd("tx")>(Arg aArgs[]) { return ProcessRxTxHistory(kTx, aArgs); }
1003*cfb92d14SAndroid Build Coastguard Worker
MessagePriorityToString(uint8_t aPriority)1004*cfb92d14SAndroid Build Coastguard Worker const char *History::MessagePriorityToString(uint8_t aPriority)
1005*cfb92d14SAndroid Build Coastguard Worker {
1006*cfb92d14SAndroid Build Coastguard Worker static const char *const kPriorityStrings[] = {
1007*cfb92d14SAndroid Build Coastguard Worker "low", // (0) OT_HISTORY_TRACKER_MSG_PRIORITY_LOW
1008*cfb92d14SAndroid Build Coastguard Worker "norm", // (1) OT_HISTORY_TRACKER_MSG_PRIORITY_NORMAL
1009*cfb92d14SAndroid Build Coastguard Worker "high", // (2) OT_HISTORY_TRACKER_MSG_PRIORITY_HIGH
1010*cfb92d14SAndroid Build Coastguard Worker "net", // (3) OT_HISTORY_TRACKER_MSG_PRIORITY_NET
1011*cfb92d14SAndroid Build Coastguard Worker };
1012*cfb92d14SAndroid Build Coastguard Worker
1013*cfb92d14SAndroid Build Coastguard Worker static_assert(0 == OT_HISTORY_TRACKER_MSG_PRIORITY_LOW, "MSG_PRIORITY_LOW value is incorrect");
1014*cfb92d14SAndroid Build Coastguard Worker static_assert(1 == OT_HISTORY_TRACKER_MSG_PRIORITY_NORMAL, "MSG_PRIORITY_NORMAL value is incorrect");
1015*cfb92d14SAndroid Build Coastguard Worker static_assert(2 == OT_HISTORY_TRACKER_MSG_PRIORITY_HIGH, "MSG_PRIORITY_HIGH value is incorrect");
1016*cfb92d14SAndroid Build Coastguard Worker static_assert(3 == OT_HISTORY_TRACKER_MSG_PRIORITY_NET, "MSG_PRIORITY_NET value is incorrect");
1017*cfb92d14SAndroid Build Coastguard Worker
1018*cfb92d14SAndroid Build Coastguard Worker return Stringify(aPriority, kPriorityStrings, "unkn");
1019*cfb92d14SAndroid Build Coastguard Worker }
1020*cfb92d14SAndroid Build Coastguard Worker
RadioTypeToString(const otHistoryTrackerMessageInfo & aInfo)1021*cfb92d14SAndroid Build Coastguard Worker const char *History::RadioTypeToString(const otHistoryTrackerMessageInfo &aInfo)
1022*cfb92d14SAndroid Build Coastguard Worker {
1023*cfb92d14SAndroid Build Coastguard Worker const char *str = "none";
1024*cfb92d14SAndroid Build Coastguard Worker
1025*cfb92d14SAndroid Build Coastguard Worker if (aInfo.mRadioTrelUdp6 && aInfo.mRadioIeee802154)
1026*cfb92d14SAndroid Build Coastguard Worker {
1027*cfb92d14SAndroid Build Coastguard Worker str = "all";
1028*cfb92d14SAndroid Build Coastguard Worker }
1029*cfb92d14SAndroid Build Coastguard Worker else if (aInfo.mRadioIeee802154)
1030*cfb92d14SAndroid Build Coastguard Worker {
1031*cfb92d14SAndroid Build Coastguard Worker str = "15.4";
1032*cfb92d14SAndroid Build Coastguard Worker }
1033*cfb92d14SAndroid Build Coastguard Worker else if (aInfo.mRadioTrelUdp6)
1034*cfb92d14SAndroid Build Coastguard Worker {
1035*cfb92d14SAndroid Build Coastguard Worker str = "trel";
1036*cfb92d14SAndroid Build Coastguard Worker }
1037*cfb92d14SAndroid Build Coastguard Worker
1038*cfb92d14SAndroid Build Coastguard Worker return str;
1039*cfb92d14SAndroid Build Coastguard Worker }
1040*cfb92d14SAndroid Build Coastguard Worker
MessageTypeToString(const otHistoryTrackerMessageInfo & aInfo)1041*cfb92d14SAndroid Build Coastguard Worker const char *History::MessageTypeToString(const otHistoryTrackerMessageInfo &aInfo)
1042*cfb92d14SAndroid Build Coastguard Worker {
1043*cfb92d14SAndroid Build Coastguard Worker const char *str = otIp6ProtoToString(aInfo.mIpProto);
1044*cfb92d14SAndroid Build Coastguard Worker
1045*cfb92d14SAndroid Build Coastguard Worker if (aInfo.mIpProto == OT_IP6_PROTO_ICMP6)
1046*cfb92d14SAndroid Build Coastguard Worker {
1047*cfb92d14SAndroid Build Coastguard Worker switch (aInfo.mIcmp6Type)
1048*cfb92d14SAndroid Build Coastguard Worker {
1049*cfb92d14SAndroid Build Coastguard Worker case OT_ICMP6_TYPE_DST_UNREACH:
1050*cfb92d14SAndroid Build Coastguard Worker str = "ICMP6(Unreach)";
1051*cfb92d14SAndroid Build Coastguard Worker break;
1052*cfb92d14SAndroid Build Coastguard Worker case OT_ICMP6_TYPE_PACKET_TO_BIG:
1053*cfb92d14SAndroid Build Coastguard Worker str = "ICMP6(TooBig)";
1054*cfb92d14SAndroid Build Coastguard Worker break;
1055*cfb92d14SAndroid Build Coastguard Worker case OT_ICMP6_TYPE_ECHO_REQUEST:
1056*cfb92d14SAndroid Build Coastguard Worker str = "ICMP6(EchoReqst)";
1057*cfb92d14SAndroid Build Coastguard Worker break;
1058*cfb92d14SAndroid Build Coastguard Worker case OT_ICMP6_TYPE_ECHO_REPLY:
1059*cfb92d14SAndroid Build Coastguard Worker str = "ICMP6(EchoReply)";
1060*cfb92d14SAndroid Build Coastguard Worker break;
1061*cfb92d14SAndroid Build Coastguard Worker case OT_ICMP6_TYPE_ROUTER_SOLICIT:
1062*cfb92d14SAndroid Build Coastguard Worker str = "ICMP6(RouterSol)";
1063*cfb92d14SAndroid Build Coastguard Worker break;
1064*cfb92d14SAndroid Build Coastguard Worker case OT_ICMP6_TYPE_ROUTER_ADVERT:
1065*cfb92d14SAndroid Build Coastguard Worker str = "ICMP6(RouterAdv)";
1066*cfb92d14SAndroid Build Coastguard Worker break;
1067*cfb92d14SAndroid Build Coastguard Worker default:
1068*cfb92d14SAndroid Build Coastguard Worker str = "ICMP6(Other)";
1069*cfb92d14SAndroid Build Coastguard Worker break;
1070*cfb92d14SAndroid Build Coastguard Worker }
1071*cfb92d14SAndroid Build Coastguard Worker }
1072*cfb92d14SAndroid Build Coastguard Worker
1073*cfb92d14SAndroid Build Coastguard Worker return str;
1074*cfb92d14SAndroid Build Coastguard Worker }
1075*cfb92d14SAndroid Build Coastguard Worker
ProcessRxTxHistory(RxTx aRxTx,Arg aArgs[])1076*cfb92d14SAndroid Build Coastguard Worker otError History::ProcessRxTxHistory(RxTx aRxTx, Arg aArgs[])
1077*cfb92d14SAndroid Build Coastguard Worker {
1078*cfb92d14SAndroid Build Coastguard Worker otError error;
1079*cfb92d14SAndroid Build Coastguard Worker bool isList;
1080*cfb92d14SAndroid Build Coastguard Worker uint16_t numEntries;
1081*cfb92d14SAndroid Build Coastguard Worker otHistoryTrackerIterator rxIterator;
1082*cfb92d14SAndroid Build Coastguard Worker otHistoryTrackerIterator txIterator;
1083*cfb92d14SAndroid Build Coastguard Worker bool isRx = false;
1084*cfb92d14SAndroid Build Coastguard Worker const otHistoryTrackerMessageInfo *info = nullptr;
1085*cfb92d14SAndroid Build Coastguard Worker const otHistoryTrackerMessageInfo *rxInfo = nullptr;
1086*cfb92d14SAndroid Build Coastguard Worker const otHistoryTrackerMessageInfo *txInfo = nullptr;
1087*cfb92d14SAndroid Build Coastguard Worker uint32_t entryAge;
1088*cfb92d14SAndroid Build Coastguard Worker uint32_t rxEntryAge;
1089*cfb92d14SAndroid Build Coastguard Worker uint32_t txEntryAge;
1090*cfb92d14SAndroid Build Coastguard Worker
1091*cfb92d14SAndroid Build Coastguard Worker // | Age | Type | Len | Chksum | Sec | Prio | RSS |Dir | Neighb | Radio |
1092*cfb92d14SAndroid Build Coastguard Worker // +----------------------+------------------+-------+--------+-----+------+------+----+--------+-------+
1093*cfb92d14SAndroid Build Coastguard Worker
1094*cfb92d14SAndroid Build Coastguard Worker static const char *const kTableTitles[] = {"Age", "Type", "Len", "Chksum", "Sec",
1095*cfb92d14SAndroid Build Coastguard Worker "Prio", "RSS", "Dir", "Neighb", "Radio"};
1096*cfb92d14SAndroid Build Coastguard Worker
1097*cfb92d14SAndroid Build Coastguard Worker static const uint8_t kTableColumnWidths[] = {22, 18, 7, 8, 5, 6, 6, 4, 8, 7};
1098*cfb92d14SAndroid Build Coastguard Worker
1099*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = ParseArgs(aArgs, isList, numEntries));
1100*cfb92d14SAndroid Build Coastguard Worker
1101*cfb92d14SAndroid Build Coastguard Worker if (!isList)
1102*cfb92d14SAndroid Build Coastguard Worker {
1103*cfb92d14SAndroid Build Coastguard Worker OutputTableHeader(kTableTitles, kTableColumnWidths);
1104*cfb92d14SAndroid Build Coastguard Worker }
1105*cfb92d14SAndroid Build Coastguard Worker
1106*cfb92d14SAndroid Build Coastguard Worker otHistoryTrackerInitIterator(&txIterator);
1107*cfb92d14SAndroid Build Coastguard Worker otHistoryTrackerInitIterator(&rxIterator);
1108*cfb92d14SAndroid Build Coastguard Worker
1109*cfb92d14SAndroid Build Coastguard Worker for (uint16_t index = 0; (numEntries == 0) || (index < numEntries); index++)
1110*cfb92d14SAndroid Build Coastguard Worker {
1111*cfb92d14SAndroid Build Coastguard Worker switch (aRxTx)
1112*cfb92d14SAndroid Build Coastguard Worker {
1113*cfb92d14SAndroid Build Coastguard Worker case kRx:
1114*cfb92d14SAndroid Build Coastguard Worker info = otHistoryTrackerIterateRxHistory(GetInstancePtr(), &rxIterator, &entryAge);
1115*cfb92d14SAndroid Build Coastguard Worker isRx = true;
1116*cfb92d14SAndroid Build Coastguard Worker break;
1117*cfb92d14SAndroid Build Coastguard Worker
1118*cfb92d14SAndroid Build Coastguard Worker case kTx:
1119*cfb92d14SAndroid Build Coastguard Worker info = otHistoryTrackerIterateTxHistory(GetInstancePtr(), &txIterator, &entryAge);
1120*cfb92d14SAndroid Build Coastguard Worker isRx = false;
1121*cfb92d14SAndroid Build Coastguard Worker break;
1122*cfb92d14SAndroid Build Coastguard Worker
1123*cfb92d14SAndroid Build Coastguard Worker case kRxTx:
1124*cfb92d14SAndroid Build Coastguard Worker // Iterate through both RX and TX lists and determine the entry
1125*cfb92d14SAndroid Build Coastguard Worker // with earlier age.
1126*cfb92d14SAndroid Build Coastguard Worker
1127*cfb92d14SAndroid Build Coastguard Worker if (rxInfo == nullptr)
1128*cfb92d14SAndroid Build Coastguard Worker {
1129*cfb92d14SAndroid Build Coastguard Worker rxInfo = otHistoryTrackerIterateRxHistory(GetInstancePtr(), &rxIterator, &rxEntryAge);
1130*cfb92d14SAndroid Build Coastguard Worker }
1131*cfb92d14SAndroid Build Coastguard Worker
1132*cfb92d14SAndroid Build Coastguard Worker if (txInfo == nullptr)
1133*cfb92d14SAndroid Build Coastguard Worker {
1134*cfb92d14SAndroid Build Coastguard Worker txInfo = otHistoryTrackerIterateTxHistory(GetInstancePtr(), &txIterator, &txEntryAge);
1135*cfb92d14SAndroid Build Coastguard Worker }
1136*cfb92d14SAndroid Build Coastguard Worker
1137*cfb92d14SAndroid Build Coastguard Worker if ((rxInfo != nullptr) && ((txInfo == nullptr) || (rxEntryAge <= txEntryAge)))
1138*cfb92d14SAndroid Build Coastguard Worker {
1139*cfb92d14SAndroid Build Coastguard Worker info = rxInfo;
1140*cfb92d14SAndroid Build Coastguard Worker entryAge = rxEntryAge;
1141*cfb92d14SAndroid Build Coastguard Worker isRx = true;
1142*cfb92d14SAndroid Build Coastguard Worker rxInfo = nullptr;
1143*cfb92d14SAndroid Build Coastguard Worker }
1144*cfb92d14SAndroid Build Coastguard Worker else
1145*cfb92d14SAndroid Build Coastguard Worker {
1146*cfb92d14SAndroid Build Coastguard Worker info = txInfo;
1147*cfb92d14SAndroid Build Coastguard Worker entryAge = txEntryAge;
1148*cfb92d14SAndroid Build Coastguard Worker isRx = false;
1149*cfb92d14SAndroid Build Coastguard Worker txInfo = nullptr;
1150*cfb92d14SAndroid Build Coastguard Worker }
1151*cfb92d14SAndroid Build Coastguard Worker
1152*cfb92d14SAndroid Build Coastguard Worker break;
1153*cfb92d14SAndroid Build Coastguard Worker }
1154*cfb92d14SAndroid Build Coastguard Worker
1155*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(info != nullptr);
1156*cfb92d14SAndroid Build Coastguard Worker
1157*cfb92d14SAndroid Build Coastguard Worker if (isList)
1158*cfb92d14SAndroid Build Coastguard Worker {
1159*cfb92d14SAndroid Build Coastguard Worker OutputRxTxEntryListFormat(*info, entryAge, isRx);
1160*cfb92d14SAndroid Build Coastguard Worker }
1161*cfb92d14SAndroid Build Coastguard Worker else
1162*cfb92d14SAndroid Build Coastguard Worker {
1163*cfb92d14SAndroid Build Coastguard Worker if (index != 0)
1164*cfb92d14SAndroid Build Coastguard Worker {
1165*cfb92d14SAndroid Build Coastguard Worker OutputTableSeparator(kTableColumnWidths);
1166*cfb92d14SAndroid Build Coastguard Worker }
1167*cfb92d14SAndroid Build Coastguard Worker
1168*cfb92d14SAndroid Build Coastguard Worker OutputRxTxEntryTableFormat(*info, entryAge, isRx);
1169*cfb92d14SAndroid Build Coastguard Worker }
1170*cfb92d14SAndroid Build Coastguard Worker }
1171*cfb92d14SAndroid Build Coastguard Worker
1172*cfb92d14SAndroid Build Coastguard Worker exit:
1173*cfb92d14SAndroid Build Coastguard Worker return error;
1174*cfb92d14SAndroid Build Coastguard Worker }
1175*cfb92d14SAndroid Build Coastguard Worker
OutputRxTxEntryListFormat(const otHistoryTrackerMessageInfo & aInfo,uint32_t aEntryAge,bool aIsRx)1176*cfb92d14SAndroid Build Coastguard Worker void History::OutputRxTxEntryListFormat(const otHistoryTrackerMessageInfo &aInfo, uint32_t aEntryAge, bool aIsRx)
1177*cfb92d14SAndroid Build Coastguard Worker {
1178*cfb92d14SAndroid Build Coastguard Worker constexpr uint8_t kIndentSize = 4;
1179*cfb92d14SAndroid Build Coastguard Worker
1180*cfb92d14SAndroid Build Coastguard Worker char ageString[OT_HISTORY_TRACKER_ENTRY_AGE_STRING_SIZE];
1181*cfb92d14SAndroid Build Coastguard Worker
1182*cfb92d14SAndroid Build Coastguard Worker otHistoryTrackerEntryAgeToString(aEntryAge, ageString, sizeof(ageString));
1183*cfb92d14SAndroid Build Coastguard Worker
1184*cfb92d14SAndroid Build Coastguard Worker OutputLine("%s", ageString);
1185*cfb92d14SAndroid Build Coastguard Worker OutputFormat(kIndentSize, "type:%s len:%u checksum:0x%04x sec:%s prio:%s ", MessageTypeToString(aInfo),
1186*cfb92d14SAndroid Build Coastguard Worker aInfo.mPayloadLength, aInfo.mChecksum, aInfo.mLinkSecurity ? "yes" : "no",
1187*cfb92d14SAndroid Build Coastguard Worker MessagePriorityToString(aInfo.mPriority));
1188*cfb92d14SAndroid Build Coastguard Worker if (aIsRx)
1189*cfb92d14SAndroid Build Coastguard Worker {
1190*cfb92d14SAndroid Build Coastguard Worker OutputFormat("rss:%d", aInfo.mAveRxRss);
1191*cfb92d14SAndroid Build Coastguard Worker }
1192*cfb92d14SAndroid Build Coastguard Worker else
1193*cfb92d14SAndroid Build Coastguard Worker {
1194*cfb92d14SAndroid Build Coastguard Worker OutputFormat("tx-success:%s", aInfo.mTxSuccess ? "yes" : "no");
1195*cfb92d14SAndroid Build Coastguard Worker }
1196*cfb92d14SAndroid Build Coastguard Worker
1197*cfb92d14SAndroid Build Coastguard Worker OutputLine(" %s:0x%04x radio:%s", aIsRx ? "from" : "to", aInfo.mNeighborRloc16, RadioTypeToString(aInfo));
1198*cfb92d14SAndroid Build Coastguard Worker
1199*cfb92d14SAndroid Build Coastguard Worker OutputFormat(kIndentSize, "src:");
1200*cfb92d14SAndroid Build Coastguard Worker OutputSockAddrLine(aInfo.mSource);
1201*cfb92d14SAndroid Build Coastguard Worker
1202*cfb92d14SAndroid Build Coastguard Worker OutputFormat(kIndentSize, "dst:");
1203*cfb92d14SAndroid Build Coastguard Worker OutputSockAddrLine(aInfo.mDestination);
1204*cfb92d14SAndroid Build Coastguard Worker }
1205*cfb92d14SAndroid Build Coastguard Worker
OutputRxTxEntryTableFormat(const otHistoryTrackerMessageInfo & aInfo,uint32_t aEntryAge,bool aIsRx)1206*cfb92d14SAndroid Build Coastguard Worker void History::OutputRxTxEntryTableFormat(const otHistoryTrackerMessageInfo &aInfo, uint32_t aEntryAge, bool aIsRx)
1207*cfb92d14SAndroid Build Coastguard Worker {
1208*cfb92d14SAndroid Build Coastguard Worker char ageString[OT_HISTORY_TRACKER_ENTRY_AGE_STRING_SIZE];
1209*cfb92d14SAndroid Build Coastguard Worker char addrString[OT_IP6_SOCK_ADDR_STRING_SIZE];
1210*cfb92d14SAndroid Build Coastguard Worker
1211*cfb92d14SAndroid Build Coastguard Worker otHistoryTrackerEntryAgeToString(aEntryAge, ageString, sizeof(ageString));
1212*cfb92d14SAndroid Build Coastguard Worker
1213*cfb92d14SAndroid Build Coastguard Worker OutputFormat("| %20s | %-16.16s | %5u | 0x%04x | %3s | %4s | ", "", MessageTypeToString(aInfo),
1214*cfb92d14SAndroid Build Coastguard Worker aInfo.mPayloadLength, aInfo.mChecksum, aInfo.mLinkSecurity ? "yes" : "no",
1215*cfb92d14SAndroid Build Coastguard Worker MessagePriorityToString(aInfo.mPriority));
1216*cfb92d14SAndroid Build Coastguard Worker
1217*cfb92d14SAndroid Build Coastguard Worker if (aIsRx)
1218*cfb92d14SAndroid Build Coastguard Worker {
1219*cfb92d14SAndroid Build Coastguard Worker OutputFormat("%4d | RX ", aInfo.mAveRxRss);
1220*cfb92d14SAndroid Build Coastguard Worker }
1221*cfb92d14SAndroid Build Coastguard Worker else
1222*cfb92d14SAndroid Build Coastguard Worker {
1223*cfb92d14SAndroid Build Coastguard Worker OutputFormat(" NA |");
1224*cfb92d14SAndroid Build Coastguard Worker OutputFormat(aInfo.mTxSuccess ? " TX " : "TX-F");
1225*cfb92d14SAndroid Build Coastguard Worker }
1226*cfb92d14SAndroid Build Coastguard Worker
1227*cfb92d14SAndroid Build Coastguard Worker if (aInfo.mNeighborRloc16 == kShortAddrBroadcast)
1228*cfb92d14SAndroid Build Coastguard Worker {
1229*cfb92d14SAndroid Build Coastguard Worker OutputFormat("| bcast ");
1230*cfb92d14SAndroid Build Coastguard Worker }
1231*cfb92d14SAndroid Build Coastguard Worker else if (aInfo.mNeighborRloc16 == kShortAddrInvalid)
1232*cfb92d14SAndroid Build Coastguard Worker {
1233*cfb92d14SAndroid Build Coastguard Worker OutputFormat("| unknwn ");
1234*cfb92d14SAndroid Build Coastguard Worker }
1235*cfb92d14SAndroid Build Coastguard Worker else
1236*cfb92d14SAndroid Build Coastguard Worker {
1237*cfb92d14SAndroid Build Coastguard Worker OutputFormat("| 0x%04x ", aInfo.mNeighborRloc16);
1238*cfb92d14SAndroid Build Coastguard Worker }
1239*cfb92d14SAndroid Build Coastguard Worker
1240*cfb92d14SAndroid Build Coastguard Worker OutputLine("| %5.5s |", RadioTypeToString(aInfo));
1241*cfb92d14SAndroid Build Coastguard Worker
1242*cfb92d14SAndroid Build Coastguard Worker otIp6SockAddrToString(&aInfo.mSource, addrString, sizeof(addrString));
1243*cfb92d14SAndroid Build Coastguard Worker OutputLine("| %20s | src: %-70s |", ageString, addrString);
1244*cfb92d14SAndroid Build Coastguard Worker
1245*cfb92d14SAndroid Build Coastguard Worker otIp6SockAddrToString(&aInfo.mDestination, addrString, sizeof(addrString));
1246*cfb92d14SAndroid Build Coastguard Worker OutputLine("| %20s | dst: %-70s |", "", addrString);
1247*cfb92d14SAndroid Build Coastguard Worker }
1248*cfb92d14SAndroid Build Coastguard Worker
1249*cfb92d14SAndroid Build Coastguard Worker /**
1250*cfb92d14SAndroid Build Coastguard Worker * @cli history prefix
1251*cfb92d14SAndroid Build Coastguard Worker * @code
1252*cfb92d14SAndroid Build Coastguard Worker * history prefix
1253*cfb92d14SAndroid Build Coastguard Worker * | Age | Event | Prefix | Flags | Pref | RLOC16 |
1254*cfb92d14SAndroid Build Coastguard Worker * +----------------------+---------+---------------------------------------------+-----------+------+--------+
1255*cfb92d14SAndroid Build Coastguard Worker * | 00:00:10.663 | Added | fd00:1111:2222:3333::/64 | paro | med | 0x5400 |
1256*cfb92d14SAndroid Build Coastguard Worker * | 00:01:02.054 | Removed | fd00:dead:beef:1::/64 | paros | high | 0x5400 |
1257*cfb92d14SAndroid Build Coastguard Worker * | 00:01:21.136 | Added | fd00:abba:cddd:0::/64 | paos | med | 0x5400 |
1258*cfb92d14SAndroid Build Coastguard Worker * | 00:01:45.144 | Added | fd00:dead:beef:1::/64 | paros | high | 0x3c00 |
1259*cfb92d14SAndroid Build Coastguard Worker * | 00:01:50.944 | Added | fd00:dead:beef:1::/64 | paros | high | 0x5400 |
1260*cfb92d14SAndroid Build Coastguard Worker * | 00:01:59.887 | Added | fd00:dead:beef:1::/64 | paros | med | 0x8800 |
1261*cfb92d14SAndroid Build Coastguard Worker * Done
1262*cfb92d14SAndroid Build Coastguard Worker * @endcode
1263*cfb92d14SAndroid Build Coastguard Worker * @code
1264*cfb92d14SAndroid Build Coastguard Worker * history prefix list
1265*cfb92d14SAndroid Build Coastguard Worker * 00:04:12.487 -> event:Added prefix:fd00:1111:2222:3333::/64 flags:paro pref:med rloc16:0x5400
1266*cfb92d14SAndroid Build Coastguard Worker * 00:05:03.878 -> event:Removed prefix:fd00:dead:beef:1::/64 flags:paros pref:high rloc16:0x5400
1267*cfb92d14SAndroid Build Coastguard Worker * 00:05:22.960 -> event:Added prefix:fd00:abba:cddd:0::/64 flags:paos pref:med rloc16:0x5400
1268*cfb92d14SAndroid Build Coastguard Worker * 00:05:46.968 -> event:Added prefix:fd00:dead:beef:1::/64 flags:paros pref:high rloc16:0x3c00
1269*cfb92d14SAndroid Build Coastguard Worker * 00:05:52.768 -> event:Added prefix:fd00:dead:beef:1::/64 flags:paros pref:high rloc16:0x5400
1270*cfb92d14SAndroid Build Coastguard Worker * 00:06:01.711 -> event:Added prefix:fd00:dead:beef:1::/64 flags:paros pref:med rloc16:0x8800
1271*cfb92d14SAndroid Build Coastguard Worker * Done
1272*cfb92d14SAndroid Build Coastguard Worker * @endcode
1273*cfb92d14SAndroid Build Coastguard Worker * @cparam history prefix [@ca{list}] [@ca{num-entries}]
1274*cfb92d14SAndroid Build Coastguard Worker * * Use the `list` option to display the output in list format. Otherwise,
1275*cfb92d14SAndroid Build Coastguard Worker * the output is shown in table format.
1276*cfb92d14SAndroid Build Coastguard Worker * * Use the `num-entries` option to limit the output to the number of
1277*cfb92d14SAndroid Build Coastguard Worker * most-recent entries specified. If this option is not used, all stored
1278*cfb92d14SAndroid Build Coastguard Worker * entries are shown in the output.
1279*cfb92d14SAndroid Build Coastguard Worker * @par
1280*cfb92d14SAndroid Build Coastguard Worker * Displays the network data for the mesh prefix history in table or list format.
1281*cfb92d14SAndroid Build Coastguard Worker * @par
1282*cfb92d14SAndroid Build Coastguard Worker * Each table or list entry provides:
1283*cfb92d14SAndroid Build Coastguard Worker * * Age: Time elapsed since the command was issued, and given in the format:
1284*cfb92d14SAndroid Build Coastguard Worker * `hours`:`minutes`:`seconds`:`milliseconds`
1285*cfb92d14SAndroid Build Coastguard Worker * * Event: Possible values are `Added` or `Removed`.
1286*cfb92d14SAndroid Build Coastguard Worker * * Prefix
1287*cfb92d14SAndroid Build Coastguard Worker * * Flags/meaning:
1288*cfb92d14SAndroid Build Coastguard Worker * * `p`: Preferred flag
1289*cfb92d14SAndroid Build Coastguard Worker * * `a`: Stateless IPv6 address auto-configuration flag.
1290*cfb92d14SAndroid Build Coastguard Worker * * `d`: DHCPv6 IPv6 address configuration flag.
1291*cfb92d14SAndroid Build Coastguard Worker * * `c`: DHCPv6 other-configuration flag.
1292*cfb92d14SAndroid Build Coastguard Worker * * `r`: Default route flag.
1293*cfb92d14SAndroid Build Coastguard Worker * * `o`: On mesh flag.
1294*cfb92d14SAndroid Build Coastguard Worker * * `s`: Stable flag.
1295*cfb92d14SAndroid Build Coastguard Worker * * `n`: Nd Dns flag.
1296*cfb92d14SAndroid Build Coastguard Worker * * `D`: Domain prefix flag.
1297*cfb92d14SAndroid Build Coastguard Worker * * Pref: Preference. Values can be either `high`, `med`, or `low`.
1298*cfb92d14SAndroid Build Coastguard Worker * * RLOC16
1299*cfb92d14SAndroid Build Coastguard Worker * @sa otHistoryTrackerIterateOnMeshPrefixHistory
1300*cfb92d14SAndroid Build Coastguard Worker */
Process(Arg aArgs[])1301*cfb92d14SAndroid Build Coastguard Worker template <> otError History::Process<Cmd("prefix")>(Arg aArgs[])
1302*cfb92d14SAndroid Build Coastguard Worker {
1303*cfb92d14SAndroid Build Coastguard Worker otError error;
1304*cfb92d14SAndroid Build Coastguard Worker bool isList;
1305*cfb92d14SAndroid Build Coastguard Worker uint16_t numEntries;
1306*cfb92d14SAndroid Build Coastguard Worker otHistoryTrackerIterator iterator;
1307*cfb92d14SAndroid Build Coastguard Worker const otHistoryTrackerOnMeshPrefixInfo *info;
1308*cfb92d14SAndroid Build Coastguard Worker uint32_t entryAge;
1309*cfb92d14SAndroid Build Coastguard Worker char ageString[OT_HISTORY_TRACKER_ENTRY_AGE_STRING_SIZE];
1310*cfb92d14SAndroid Build Coastguard Worker char prefixString[OT_IP6_PREFIX_STRING_SIZE];
1311*cfb92d14SAndroid Build Coastguard Worker NetworkData::FlagsString flagsString;
1312*cfb92d14SAndroid Build Coastguard Worker
1313*cfb92d14SAndroid Build Coastguard Worker static_assert(0 == OT_HISTORY_TRACKER_NET_DATA_ENTRY_ADDED, "NET_DATA_ENTRY_ADDED value is incorrect");
1314*cfb92d14SAndroid Build Coastguard Worker static_assert(1 == OT_HISTORY_TRACKER_NET_DATA_ENTRY_REMOVED, "NET_DATA_ENTRY_REMOVED value is incorrect");
1315*cfb92d14SAndroid Build Coastguard Worker
1316*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = ParseArgs(aArgs, isList, numEntries));
1317*cfb92d14SAndroid Build Coastguard Worker
1318*cfb92d14SAndroid Build Coastguard Worker if (!isList)
1319*cfb92d14SAndroid Build Coastguard Worker {
1320*cfb92d14SAndroid Build Coastguard Worker // | Age | Event | Prefix | Flags | Pref | RLOC16 |
1321*cfb92d14SAndroid Build Coastguard Worker // +----------------------+---------+---------------------------------------------+-----------+------+--------+
1322*cfb92d14SAndroid Build Coastguard Worker
1323*cfb92d14SAndroid Build Coastguard Worker static const char *const kPrefixTitles[] = {"Age", "Event", "Prefix", "Flags", "Pref", "RLOC16"};
1324*cfb92d14SAndroid Build Coastguard Worker static const uint8_t kPrefixColumnWidths[] = {22, 9, 45, 11, 6, 8};
1325*cfb92d14SAndroid Build Coastguard Worker
1326*cfb92d14SAndroid Build Coastguard Worker OutputTableHeader(kPrefixTitles, kPrefixColumnWidths);
1327*cfb92d14SAndroid Build Coastguard Worker }
1328*cfb92d14SAndroid Build Coastguard Worker
1329*cfb92d14SAndroid Build Coastguard Worker otHistoryTrackerInitIterator(&iterator);
1330*cfb92d14SAndroid Build Coastguard Worker
1331*cfb92d14SAndroid Build Coastguard Worker for (uint16_t index = 0; (numEntries == 0) || (index < numEntries); index++)
1332*cfb92d14SAndroid Build Coastguard Worker {
1333*cfb92d14SAndroid Build Coastguard Worker info = otHistoryTrackerIterateOnMeshPrefixHistory(GetInstancePtr(), &iterator, &entryAge);
1334*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(info != nullptr);
1335*cfb92d14SAndroid Build Coastguard Worker
1336*cfb92d14SAndroid Build Coastguard Worker otHistoryTrackerEntryAgeToString(entryAge, ageString, sizeof(ageString));
1337*cfb92d14SAndroid Build Coastguard Worker
1338*cfb92d14SAndroid Build Coastguard Worker otIp6PrefixToString(&info->mPrefix.mPrefix, prefixString, sizeof(prefixString));
1339*cfb92d14SAndroid Build Coastguard Worker NetworkData::PrefixFlagsToString(info->mPrefix, flagsString);
1340*cfb92d14SAndroid Build Coastguard Worker
1341*cfb92d14SAndroid Build Coastguard Worker OutputLine(isList ? "%s -> event:%s prefix:%s flags:%s pref:%s rloc16:0x%04x"
1342*cfb92d14SAndroid Build Coastguard Worker : "| %20s | %-7s | %-43s | %-9s | %-4s | 0x%04x |",
1343*cfb92d14SAndroid Build Coastguard Worker ageString, Stringify(info->mEvent, kSimpleEventStrings), prefixString, flagsString,
1344*cfb92d14SAndroid Build Coastguard Worker PreferenceToString(info->mPrefix.mPreference), info->mPrefix.mRloc16);
1345*cfb92d14SAndroid Build Coastguard Worker }
1346*cfb92d14SAndroid Build Coastguard Worker
1347*cfb92d14SAndroid Build Coastguard Worker exit:
1348*cfb92d14SAndroid Build Coastguard Worker return error;
1349*cfb92d14SAndroid Build Coastguard Worker }
1350*cfb92d14SAndroid Build Coastguard Worker
1351*cfb92d14SAndroid Build Coastguard Worker /**
1352*cfb92d14SAndroid Build Coastguard Worker * @cli history route
1353*cfb92d14SAndroid Build Coastguard Worker * @code
1354*cfb92d14SAndroid Build Coastguard Worker * history route
1355*cfb92d14SAndroid Build Coastguard Worker * | Age | Event | Route | Flags | Pref | RLOC16 |
1356*cfb92d14SAndroid Build Coastguard Worker * +----------------------+---------+---------------------------------------------+-----------+------+--------+
1357*cfb92d14SAndroid Build Coastguard Worker * | 00:00:05.456 | Removed | fd00:1111:0::/48 | s | med | 0x3c00 |
1358*cfb92d14SAndroid Build Coastguard Worker * | 00:00:29.310 | Added | fd00:1111:0::/48 | s | med | 0x3c00 |
1359*cfb92d14SAndroid Build Coastguard Worker * | 00:00:42.822 | Added | fd00:1111:0::/48 | s | med | 0x5400 |
1360*cfb92d14SAndroid Build Coastguard Worker * | 00:01:27.688 | Added | fd00:aaaa:bbbb:cccc::/64 | s | med | 0x8800 |
1361*cfb92d14SAndroid Build Coastguard Worker * Done
1362*cfb92d14SAndroid Build Coastguard Worker * @endcode
1363*cfb92d14SAndroid Build Coastguard Worker * @code
1364*cfb92d14SAndroid Build Coastguard Worker * history route list 2
1365*cfb92d14SAndroid Build Coastguard Worker * 00:00:48.704 -> event:Removed route:fd00:1111:0::/48 flags:s pref:med rloc16:0x3c00
1366*cfb92d14SAndroid Build Coastguard Worker * 00:01:12.558 -> event:Added route:fd00:1111:0::/48 flags:s pref:med rloc16:0x3c00
1367*cfb92d14SAndroid Build Coastguard Worker * Done
1368*cfb92d14SAndroid Build Coastguard Worker * @endcode
1369*cfb92d14SAndroid Build Coastguard Worker * @cparam history route [@ca{list}] [@ca{num-entries}]
1370*cfb92d14SAndroid Build Coastguard Worker * * Use the `list` option to display the output in list format. Otherwise,
1371*cfb92d14SAndroid Build Coastguard Worker * the output is shown in table format.
1372*cfb92d14SAndroid Build Coastguard Worker * * Use the `num-entries` option to limit the output to the number of
1373*cfb92d14SAndroid Build Coastguard Worker * most-recent entries specified. If this option is not used, all stored
1374*cfb92d14SAndroid Build Coastguard Worker * entries are shown in the output.
1375*cfb92d14SAndroid Build Coastguard Worker * @par
1376*cfb92d14SAndroid Build Coastguard Worker * Displays the network data external-route history in table or list format.
1377*cfb92d14SAndroid Build Coastguard Worker * @par
1378*cfb92d14SAndroid Build Coastguard Worker * Each table or list entry provides:
1379*cfb92d14SAndroid Build Coastguard Worker * * Age: Time elapsed since the command was issued, and given in the format:
1380*cfb92d14SAndroid Build Coastguard Worker * `hours`:`minutes`:`seconds`:`milliseconds`
1381*cfb92d14SAndroid Build Coastguard Worker * * Event: Possible values are `Added` or `Removed`.
1382*cfb92d14SAndroid Build Coastguard Worker * * Route
1383*cfb92d14SAndroid Build Coastguard Worker * * Flags/meaning:
1384*cfb92d14SAndroid Build Coastguard Worker * * `s`: Stable flag.
1385*cfb92d14SAndroid Build Coastguard Worker * * `n`: NAT64 flag.
1386*cfb92d14SAndroid Build Coastguard Worker * * Pref: Preference. Values can be either `high`, `med`, or `low`.
1387*cfb92d14SAndroid Build Coastguard Worker * * RLOC16
1388*cfb92d14SAndroid Build Coastguard Worker * @sa otHistoryTrackerIterateExternalRouteHistory
1389*cfb92d14SAndroid Build Coastguard Worker */
Process(Arg aArgs[])1390*cfb92d14SAndroid Build Coastguard Worker template <> otError History::Process<Cmd("route")>(Arg aArgs[])
1391*cfb92d14SAndroid Build Coastguard Worker {
1392*cfb92d14SAndroid Build Coastguard Worker otError error;
1393*cfb92d14SAndroid Build Coastguard Worker bool isList;
1394*cfb92d14SAndroid Build Coastguard Worker uint16_t numEntries;
1395*cfb92d14SAndroid Build Coastguard Worker otHistoryTrackerIterator iterator;
1396*cfb92d14SAndroid Build Coastguard Worker const otHistoryTrackerExternalRouteInfo *info;
1397*cfb92d14SAndroid Build Coastguard Worker uint32_t entryAge;
1398*cfb92d14SAndroid Build Coastguard Worker char ageString[OT_HISTORY_TRACKER_ENTRY_AGE_STRING_SIZE];
1399*cfb92d14SAndroid Build Coastguard Worker char prefixString[OT_IP6_PREFIX_STRING_SIZE];
1400*cfb92d14SAndroid Build Coastguard Worker NetworkData::FlagsString flagsString;
1401*cfb92d14SAndroid Build Coastguard Worker
1402*cfb92d14SAndroid Build Coastguard Worker static_assert(0 == OT_HISTORY_TRACKER_NET_DATA_ENTRY_ADDED, "NET_DATA_ENTRY_ADDED value is incorrect");
1403*cfb92d14SAndroid Build Coastguard Worker static_assert(1 == OT_HISTORY_TRACKER_NET_DATA_ENTRY_REMOVED, "NET_DATA_ENTRY_REMOVED value is incorrect");
1404*cfb92d14SAndroid Build Coastguard Worker
1405*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = ParseArgs(aArgs, isList, numEntries));
1406*cfb92d14SAndroid Build Coastguard Worker
1407*cfb92d14SAndroid Build Coastguard Worker if (!isList)
1408*cfb92d14SAndroid Build Coastguard Worker {
1409*cfb92d14SAndroid Build Coastguard Worker // | Age | Event | Route | Flags | Pref | RLOC16 |
1410*cfb92d14SAndroid Build Coastguard Worker // +----------------------+---------+---------------------------------------------+-----------+------+--------+
1411*cfb92d14SAndroid Build Coastguard Worker
1412*cfb92d14SAndroid Build Coastguard Worker static const char *const kRouteTitles[] = {"Age", "Event", "Route", "Flags", "Pref", "RLOC16"};
1413*cfb92d14SAndroid Build Coastguard Worker static const uint8_t kRouteColumnWidths[] = {22, 9, 45, 11, 6, 8};
1414*cfb92d14SAndroid Build Coastguard Worker
1415*cfb92d14SAndroid Build Coastguard Worker OutputTableHeader(kRouteTitles, kRouteColumnWidths);
1416*cfb92d14SAndroid Build Coastguard Worker }
1417*cfb92d14SAndroid Build Coastguard Worker
1418*cfb92d14SAndroid Build Coastguard Worker otHistoryTrackerInitIterator(&iterator);
1419*cfb92d14SAndroid Build Coastguard Worker
1420*cfb92d14SAndroid Build Coastguard Worker for (uint16_t index = 0; (numEntries == 0) || (index < numEntries); index++)
1421*cfb92d14SAndroid Build Coastguard Worker {
1422*cfb92d14SAndroid Build Coastguard Worker info = otHistoryTrackerIterateExternalRouteHistory(GetInstancePtr(), &iterator, &entryAge);
1423*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(info != nullptr);
1424*cfb92d14SAndroid Build Coastguard Worker
1425*cfb92d14SAndroid Build Coastguard Worker otHistoryTrackerEntryAgeToString(entryAge, ageString, sizeof(ageString));
1426*cfb92d14SAndroid Build Coastguard Worker
1427*cfb92d14SAndroid Build Coastguard Worker otIp6PrefixToString(&info->mRoute.mPrefix, prefixString, sizeof(prefixString));
1428*cfb92d14SAndroid Build Coastguard Worker NetworkData::RouteFlagsToString(info->mRoute, flagsString);
1429*cfb92d14SAndroid Build Coastguard Worker
1430*cfb92d14SAndroid Build Coastguard Worker OutputLine(isList ? "%s -> event:%s route:%s flags:%s pref:%s rloc16:0x%04x"
1431*cfb92d14SAndroid Build Coastguard Worker : "| %20s | %-7s | %-43s | %-9s | %-4s | 0x%04x |",
1432*cfb92d14SAndroid Build Coastguard Worker ageString, Stringify(info->mEvent, kSimpleEventStrings), prefixString, flagsString,
1433*cfb92d14SAndroid Build Coastguard Worker PreferenceToString(info->mRoute.mPreference), info->mRoute.mRloc16);
1434*cfb92d14SAndroid Build Coastguard Worker }
1435*cfb92d14SAndroid Build Coastguard Worker
1436*cfb92d14SAndroid Build Coastguard Worker exit:
1437*cfb92d14SAndroid Build Coastguard Worker return error;
1438*cfb92d14SAndroid Build Coastguard Worker }
1439*cfb92d14SAndroid Build Coastguard Worker
Process(Arg aArgs[])1440*cfb92d14SAndroid Build Coastguard Worker otError History::Process(Arg aArgs[])
1441*cfb92d14SAndroid Build Coastguard Worker {
1442*cfb92d14SAndroid Build Coastguard Worker #define CmdEntry(aCommandString) \
1443*cfb92d14SAndroid Build Coastguard Worker { \
1444*cfb92d14SAndroid Build Coastguard Worker aCommandString, &History::Process<Cmd(aCommandString)> \
1445*cfb92d14SAndroid Build Coastguard Worker }
1446*cfb92d14SAndroid Build Coastguard Worker
1447*cfb92d14SAndroid Build Coastguard Worker static constexpr Command kCommands[] = {
1448*cfb92d14SAndroid Build Coastguard Worker CmdEntry("ipaddr"), CmdEntry("ipmaddr"), CmdEntry("neighbor"), CmdEntry("netinfo"), CmdEntry("prefix"),
1449*cfb92d14SAndroid Build Coastguard Worker CmdEntry("route"), CmdEntry("router"), CmdEntry("rx"), CmdEntry("rxtx"), CmdEntry("tx"),
1450*cfb92d14SAndroid Build Coastguard Worker };
1451*cfb92d14SAndroid Build Coastguard Worker
1452*cfb92d14SAndroid Build Coastguard Worker #undef CmdEntry
1453*cfb92d14SAndroid Build Coastguard Worker
1454*cfb92d14SAndroid Build Coastguard Worker static_assert(BinarySearch::IsSorted(kCommands), "kCommands is not sorted");
1455*cfb92d14SAndroid Build Coastguard Worker
1456*cfb92d14SAndroid Build Coastguard Worker otError error = OT_ERROR_INVALID_COMMAND;
1457*cfb92d14SAndroid Build Coastguard Worker const Command *command;
1458*cfb92d14SAndroid Build Coastguard Worker
1459*cfb92d14SAndroid Build Coastguard Worker if (aArgs[0].IsEmpty() || (aArgs[0] == "help"))
1460*cfb92d14SAndroid Build Coastguard Worker {
1461*cfb92d14SAndroid Build Coastguard Worker OutputCommandTable(kCommands);
1462*cfb92d14SAndroid Build Coastguard Worker ExitNow(error = aArgs[0].IsEmpty() ? error : OT_ERROR_NONE);
1463*cfb92d14SAndroid Build Coastguard Worker }
1464*cfb92d14SAndroid Build Coastguard Worker
1465*cfb92d14SAndroid Build Coastguard Worker command = BinarySearch::Find(aArgs[0].GetCString(), kCommands);
1466*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(command != nullptr);
1467*cfb92d14SAndroid Build Coastguard Worker
1468*cfb92d14SAndroid Build Coastguard Worker error = (this->*command->mHandler)(aArgs + 1);
1469*cfb92d14SAndroid Build Coastguard Worker
1470*cfb92d14SAndroid Build Coastguard Worker exit:
1471*cfb92d14SAndroid Build Coastguard Worker return error;
1472*cfb92d14SAndroid Build Coastguard Worker }
1473*cfb92d14SAndroid Build Coastguard Worker
1474*cfb92d14SAndroid Build Coastguard Worker } // namespace Cli
1475*cfb92d14SAndroid Build Coastguard Worker } // namespace ot
1476*cfb92d14SAndroid Build Coastguard Worker
1477*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
1478