xref: /aosp_15_r20/external/openthread/src/cli/cli_br.cpp (revision cfb92d1480a9e65faed56933e9c12405f45898b4)
1*cfb92d14SAndroid Build Coastguard Worker /*
2*cfb92d14SAndroid Build Coastguard Worker  *  Copyright (c) 2023, 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 Border Router.
32*cfb92d14SAndroid Build Coastguard Worker  */
33*cfb92d14SAndroid Build Coastguard Worker 
34*cfb92d14SAndroid Build Coastguard Worker #include "cli_br.hpp"
35*cfb92d14SAndroid Build Coastguard Worker 
36*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_BORDER_ROUTING_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 /**
46*cfb92d14SAndroid Build Coastguard Worker  * @cli br init
47*cfb92d14SAndroid Build Coastguard Worker  * @code
48*cfb92d14SAndroid Build Coastguard Worker  * br init 2 1
49*cfb92d14SAndroid Build Coastguard Worker  * Done
50*cfb92d14SAndroid Build Coastguard Worker  * @endcode
51*cfb92d14SAndroid Build Coastguard Worker  * @cparam br init @ca{infrastructure-network-index} @ca{is-running}
52*cfb92d14SAndroid Build Coastguard Worker  * @par
53*cfb92d14SAndroid Build Coastguard Worker  * Initializes the Border Routing Manager.
54*cfb92d14SAndroid Build Coastguard Worker  * @sa otBorderRoutingInit
55*cfb92d14SAndroid Build Coastguard Worker  */
Process(Arg aArgs[])56*cfb92d14SAndroid Build Coastguard Worker template <> otError Br::Process<Cmd("init")>(Arg aArgs[])
57*cfb92d14SAndroid Build Coastguard Worker {
58*cfb92d14SAndroid Build Coastguard Worker     otError  error = OT_ERROR_NONE;
59*cfb92d14SAndroid Build Coastguard Worker     uint32_t ifIndex;
60*cfb92d14SAndroid Build Coastguard Worker     bool     isRunning;
61*cfb92d14SAndroid Build Coastguard Worker 
62*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = aArgs[0].ParseAsUint32(ifIndex));
63*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = aArgs[1].ParseAsBool(isRunning));
64*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(aArgs[2].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
65*cfb92d14SAndroid Build Coastguard Worker     error = otBorderRoutingInit(GetInstancePtr(), ifIndex, isRunning);
66*cfb92d14SAndroid Build Coastguard Worker 
67*cfb92d14SAndroid Build Coastguard Worker exit:
68*cfb92d14SAndroid Build Coastguard Worker     return error;
69*cfb92d14SAndroid Build Coastguard Worker }
70*cfb92d14SAndroid Build Coastguard Worker 
71*cfb92d14SAndroid Build Coastguard Worker /**
72*cfb92d14SAndroid Build Coastguard Worker  * @cli br enable
73*cfb92d14SAndroid Build Coastguard Worker  * @code
74*cfb92d14SAndroid Build Coastguard Worker  * br enable
75*cfb92d14SAndroid Build Coastguard Worker  * Done
76*cfb92d14SAndroid Build Coastguard Worker  * @endcode
77*cfb92d14SAndroid Build Coastguard Worker  * @par
78*cfb92d14SAndroid Build Coastguard Worker  * Enables the Border Routing Manager.
79*cfb92d14SAndroid Build Coastguard Worker  * @sa otBorderRoutingSetEnabled
80*cfb92d14SAndroid Build Coastguard Worker  */
Process(Arg aArgs[])81*cfb92d14SAndroid Build Coastguard Worker template <> otError Br::Process<Cmd("enable")>(Arg aArgs[])
82*cfb92d14SAndroid Build Coastguard Worker {
83*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
84*cfb92d14SAndroid Build Coastguard Worker 
85*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(aArgs[0].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
86*cfb92d14SAndroid Build Coastguard Worker     error = otBorderRoutingSetEnabled(GetInstancePtr(), true);
87*cfb92d14SAndroid Build Coastguard Worker 
88*cfb92d14SAndroid Build Coastguard Worker exit:
89*cfb92d14SAndroid Build Coastguard Worker     return error;
90*cfb92d14SAndroid Build Coastguard Worker }
91*cfb92d14SAndroid Build Coastguard Worker 
92*cfb92d14SAndroid Build Coastguard Worker /**
93*cfb92d14SAndroid Build Coastguard Worker  * @cli br disable
94*cfb92d14SAndroid Build Coastguard Worker  * @code
95*cfb92d14SAndroid Build Coastguard Worker  * br disable
96*cfb92d14SAndroid Build Coastguard Worker  * Done
97*cfb92d14SAndroid Build Coastguard Worker  * @endcode
98*cfb92d14SAndroid Build Coastguard Worker  * @par
99*cfb92d14SAndroid Build Coastguard Worker  * Disables the Border Routing Manager.
100*cfb92d14SAndroid Build Coastguard Worker  * @sa otBorderRoutingSetEnabled
101*cfb92d14SAndroid Build Coastguard Worker  */
Process(Arg aArgs[])102*cfb92d14SAndroid Build Coastguard Worker template <> otError Br::Process<Cmd("disable")>(Arg aArgs[])
103*cfb92d14SAndroid Build Coastguard Worker {
104*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
105*cfb92d14SAndroid Build Coastguard Worker 
106*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(aArgs[0].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
107*cfb92d14SAndroid Build Coastguard Worker     error = otBorderRoutingSetEnabled(GetInstancePtr(), false);
108*cfb92d14SAndroid Build Coastguard Worker 
109*cfb92d14SAndroid Build Coastguard Worker exit:
110*cfb92d14SAndroid Build Coastguard Worker     return error;
111*cfb92d14SAndroid Build Coastguard Worker }
112*cfb92d14SAndroid Build Coastguard Worker 
113*cfb92d14SAndroid Build Coastguard Worker /**
114*cfb92d14SAndroid Build Coastguard Worker  * @cli br state
115*cfb92d14SAndroid Build Coastguard Worker  * @code
116*cfb92d14SAndroid Build Coastguard Worker  * br state
117*cfb92d14SAndroid Build Coastguard Worker  * running
118*cfb92d14SAndroid Build Coastguard Worker  * @endcode
119*cfb92d14SAndroid Build Coastguard Worker  * @par api_copy
120*cfb92d14SAndroid Build Coastguard Worker  * #otBorderRoutingGetState
121*cfb92d14SAndroid Build Coastguard Worker  */
Process(Arg aArgs[])122*cfb92d14SAndroid Build Coastguard Worker template <> otError Br::Process<Cmd("state")>(Arg aArgs[])
123*cfb92d14SAndroid Build Coastguard Worker {
124*cfb92d14SAndroid Build Coastguard Worker     static const char *const kStateStrings[] = {
125*cfb92d14SAndroid Build Coastguard Worker 
126*cfb92d14SAndroid Build Coastguard Worker         "uninitialized", // (0) OT_BORDER_ROUTING_STATE_UNINITIALIZED
127*cfb92d14SAndroid Build Coastguard Worker         "disabled",      // (1) OT_BORDER_ROUTING_STATE_DISABLED
128*cfb92d14SAndroid Build Coastguard Worker         "stopped",       // (2) OT_BORDER_ROUTING_STATE_STOPPED
129*cfb92d14SAndroid Build Coastguard Worker         "running",       // (3) OT_BORDER_ROUTING_STATE_RUNNING
130*cfb92d14SAndroid Build Coastguard Worker     };
131*cfb92d14SAndroid Build Coastguard Worker 
132*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
133*cfb92d14SAndroid Build Coastguard Worker 
134*cfb92d14SAndroid Build Coastguard Worker     static_assert(0 == OT_BORDER_ROUTING_STATE_UNINITIALIZED, "STATE_UNINITIALIZED value is incorrect");
135*cfb92d14SAndroid Build Coastguard Worker     static_assert(1 == OT_BORDER_ROUTING_STATE_DISABLED, "STATE_DISABLED value is incorrect");
136*cfb92d14SAndroid Build Coastguard Worker     static_assert(2 == OT_BORDER_ROUTING_STATE_STOPPED, "STATE_STOPPED value is incorrect");
137*cfb92d14SAndroid Build Coastguard Worker     static_assert(3 == OT_BORDER_ROUTING_STATE_RUNNING, "STATE_RUNNING value is incorrect");
138*cfb92d14SAndroid Build Coastguard Worker 
139*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(aArgs[0].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
140*cfb92d14SAndroid Build Coastguard Worker     OutputLine("%s", Stringify(otBorderRoutingGetState(GetInstancePtr()), kStateStrings));
141*cfb92d14SAndroid Build Coastguard Worker 
142*cfb92d14SAndroid Build Coastguard Worker exit:
143*cfb92d14SAndroid Build Coastguard Worker     return error;
144*cfb92d14SAndroid Build Coastguard Worker }
145*cfb92d14SAndroid Build Coastguard Worker 
ParsePrefixTypeArgs(Arg aArgs[],PrefixType & aFlags)146*cfb92d14SAndroid Build Coastguard Worker otError Br::ParsePrefixTypeArgs(Arg aArgs[], PrefixType &aFlags)
147*cfb92d14SAndroid Build Coastguard Worker {
148*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
149*cfb92d14SAndroid Build Coastguard Worker 
150*cfb92d14SAndroid Build Coastguard Worker     aFlags = 0;
151*cfb92d14SAndroid Build Coastguard Worker 
152*cfb92d14SAndroid Build Coastguard Worker     if (aArgs[0].IsEmpty())
153*cfb92d14SAndroid Build Coastguard Worker     {
154*cfb92d14SAndroid Build Coastguard Worker         aFlags = kPrefixTypeFavored | kPrefixTypeLocal;
155*cfb92d14SAndroid Build Coastguard Worker         ExitNow();
156*cfb92d14SAndroid Build Coastguard Worker     }
157*cfb92d14SAndroid Build Coastguard Worker 
158*cfb92d14SAndroid Build Coastguard Worker     if (aArgs[0] == "local")
159*cfb92d14SAndroid Build Coastguard Worker     {
160*cfb92d14SAndroid Build Coastguard Worker         aFlags = kPrefixTypeLocal;
161*cfb92d14SAndroid Build Coastguard Worker     }
162*cfb92d14SAndroid Build Coastguard Worker     else if (aArgs[0] == "favored")
163*cfb92d14SAndroid Build Coastguard Worker     {
164*cfb92d14SAndroid Build Coastguard Worker         aFlags = kPrefixTypeFavored;
165*cfb92d14SAndroid Build Coastguard Worker     }
166*cfb92d14SAndroid Build Coastguard Worker     else
167*cfb92d14SAndroid Build Coastguard Worker     {
168*cfb92d14SAndroid Build Coastguard Worker         ExitNow(error = OT_ERROR_INVALID_ARGS);
169*cfb92d14SAndroid Build Coastguard Worker     }
170*cfb92d14SAndroid Build Coastguard Worker 
171*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(aArgs[1].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
172*cfb92d14SAndroid Build Coastguard Worker 
173*cfb92d14SAndroid Build Coastguard Worker exit:
174*cfb92d14SAndroid Build Coastguard Worker     return error;
175*cfb92d14SAndroid Build Coastguard Worker }
176*cfb92d14SAndroid Build Coastguard Worker 
177*cfb92d14SAndroid Build Coastguard Worker /**
178*cfb92d14SAndroid Build Coastguard Worker  * @cli br omrprefix
179*cfb92d14SAndroid Build Coastguard Worker  * @code
180*cfb92d14SAndroid Build Coastguard Worker  * br omrprefix
181*cfb92d14SAndroid Build Coastguard Worker  * Local: fdfc:1ff5:1512:5622::/64
182*cfb92d14SAndroid Build Coastguard Worker  * Favored: fdfc:1ff5:1512:5622::/64 prf:low
183*cfb92d14SAndroid Build Coastguard Worker  * Done
184*cfb92d14SAndroid Build Coastguard Worker  * @endcode
185*cfb92d14SAndroid Build Coastguard Worker  * @par
186*cfb92d14SAndroid Build Coastguard Worker  * Outputs both local and favored OMR prefix.
187*cfb92d14SAndroid Build Coastguard Worker  * @sa otBorderRoutingGetOmrPrefix
188*cfb92d14SAndroid Build Coastguard Worker  * @sa otBorderRoutingGetFavoredOmrPrefix
189*cfb92d14SAndroid Build Coastguard Worker  */
Process(Arg aArgs[])190*cfb92d14SAndroid Build Coastguard Worker template <> otError Br::Process<Cmd("omrprefix")>(Arg aArgs[])
191*cfb92d14SAndroid Build Coastguard Worker {
192*cfb92d14SAndroid Build Coastguard Worker     otError    error = OT_ERROR_NONE;
193*cfb92d14SAndroid Build Coastguard Worker     PrefixType outputPrefixTypes;
194*cfb92d14SAndroid Build Coastguard Worker 
195*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = ParsePrefixTypeArgs(aArgs, outputPrefixTypes));
196*cfb92d14SAndroid Build Coastguard Worker 
197*cfb92d14SAndroid Build Coastguard Worker     /**
198*cfb92d14SAndroid Build Coastguard Worker      * @cli br omrprefix local
199*cfb92d14SAndroid Build Coastguard Worker      * @code
200*cfb92d14SAndroid Build Coastguard Worker      * br omrprefix local
201*cfb92d14SAndroid Build Coastguard Worker      * fdfc:1ff5:1512:5622::/64
202*cfb92d14SAndroid Build Coastguard Worker      * Done
203*cfb92d14SAndroid Build Coastguard Worker      * @endcode
204*cfb92d14SAndroid Build Coastguard Worker      * @par api_copy
205*cfb92d14SAndroid Build Coastguard Worker      * #otBorderRoutingGetOmrPrefix
206*cfb92d14SAndroid Build Coastguard Worker      */
207*cfb92d14SAndroid Build Coastguard Worker     if (outputPrefixTypes & kPrefixTypeLocal)
208*cfb92d14SAndroid Build Coastguard Worker     {
209*cfb92d14SAndroid Build Coastguard Worker         otIp6Prefix local;
210*cfb92d14SAndroid Build Coastguard Worker 
211*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = otBorderRoutingGetOmrPrefix(GetInstancePtr(), &local));
212*cfb92d14SAndroid Build Coastguard Worker 
213*cfb92d14SAndroid Build Coastguard Worker         OutputFormat("%s", outputPrefixTypes == kPrefixTypeLocal ? "" : "Local: ");
214*cfb92d14SAndroid Build Coastguard Worker         OutputIp6PrefixLine(local);
215*cfb92d14SAndroid Build Coastguard Worker     }
216*cfb92d14SAndroid Build Coastguard Worker 
217*cfb92d14SAndroid Build Coastguard Worker     /**
218*cfb92d14SAndroid Build Coastguard Worker      * @cli br omrprefix favored
219*cfb92d14SAndroid Build Coastguard Worker      * @code
220*cfb92d14SAndroid Build Coastguard Worker      * br omrprefix favored
221*cfb92d14SAndroid Build Coastguard Worker      * fdfc:1ff5:1512:5622::/64 prf:low
222*cfb92d14SAndroid Build Coastguard Worker      * Done
223*cfb92d14SAndroid Build Coastguard Worker      * @endcode
224*cfb92d14SAndroid Build Coastguard Worker      * @par api_copy
225*cfb92d14SAndroid Build Coastguard Worker      * #otBorderRoutingGetFavoredOmrPrefix
226*cfb92d14SAndroid Build Coastguard Worker      */
227*cfb92d14SAndroid Build Coastguard Worker     if (outputPrefixTypes & kPrefixTypeFavored)
228*cfb92d14SAndroid Build Coastguard Worker     {
229*cfb92d14SAndroid Build Coastguard Worker         otIp6Prefix       favored;
230*cfb92d14SAndroid Build Coastguard Worker         otRoutePreference preference;
231*cfb92d14SAndroid Build Coastguard Worker 
232*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = otBorderRoutingGetFavoredOmrPrefix(GetInstancePtr(), &favored, &preference));
233*cfb92d14SAndroid Build Coastguard Worker 
234*cfb92d14SAndroid Build Coastguard Worker         OutputFormat("%s", outputPrefixTypes == kPrefixTypeFavored ? "" : "Favored: ");
235*cfb92d14SAndroid Build Coastguard Worker         OutputIp6Prefix(favored);
236*cfb92d14SAndroid Build Coastguard Worker         OutputLine(" prf:%s", PreferenceToString(preference));
237*cfb92d14SAndroid Build Coastguard Worker     }
238*cfb92d14SAndroid Build Coastguard Worker 
239*cfb92d14SAndroid Build Coastguard Worker exit:
240*cfb92d14SAndroid Build Coastguard Worker     return error;
241*cfb92d14SAndroid Build Coastguard Worker }
242*cfb92d14SAndroid Build Coastguard Worker 
243*cfb92d14SAndroid Build Coastguard Worker /**
244*cfb92d14SAndroid Build Coastguard Worker  * @cli br onlinkprefix
245*cfb92d14SAndroid Build Coastguard Worker  * @code
246*cfb92d14SAndroid Build Coastguard Worker  * br onlinkprefix
247*cfb92d14SAndroid Build Coastguard Worker  * Local: fd41:2650:a6f5:0::/64
248*cfb92d14SAndroid Build Coastguard Worker  * Favored: 2600::0:1234:da12::/64
249*cfb92d14SAndroid Build Coastguard Worker  * Done
250*cfb92d14SAndroid Build Coastguard Worker  * @endcode
251*cfb92d14SAndroid Build Coastguard Worker  * @par
252*cfb92d14SAndroid Build Coastguard Worker  * Outputs both local and favored on-link prefixes.
253*cfb92d14SAndroid Build Coastguard Worker  * @sa otBorderRoutingGetOnLinkPrefix
254*cfb92d14SAndroid Build Coastguard Worker  * @sa otBorderRoutingGetFavoredOnLinkPrefix
255*cfb92d14SAndroid Build Coastguard Worker  */
Process(Arg aArgs[])256*cfb92d14SAndroid Build Coastguard Worker template <> otError Br::Process<Cmd("onlinkprefix")>(Arg aArgs[])
257*cfb92d14SAndroid Build Coastguard Worker {
258*cfb92d14SAndroid Build Coastguard Worker     otError    error = OT_ERROR_NONE;
259*cfb92d14SAndroid Build Coastguard Worker     PrefixType outputPrefixTypes;
260*cfb92d14SAndroid Build Coastguard Worker 
261*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_BORDER_ROUTING_TESTING_API_ENABLE
262*cfb92d14SAndroid Build Coastguard Worker     if (aArgs[0] == "test")
263*cfb92d14SAndroid Build Coastguard Worker     {
264*cfb92d14SAndroid Build Coastguard Worker         otIp6Prefix prefix;
265*cfb92d14SAndroid Build Coastguard Worker 
266*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = aArgs[1].ParseAsIp6Prefix(prefix));
267*cfb92d14SAndroid Build Coastguard Worker         otBorderRoutingSetOnLinkPrefix(GetInstancePtr(), &prefix);
268*cfb92d14SAndroid Build Coastguard Worker         ExitNow();
269*cfb92d14SAndroid Build Coastguard Worker     }
270*cfb92d14SAndroid Build Coastguard Worker #endif
271*cfb92d14SAndroid Build Coastguard Worker 
272*cfb92d14SAndroid Build Coastguard Worker     error = ParsePrefixTypeArgs(aArgs, outputPrefixTypes);
273*cfb92d14SAndroid Build Coastguard Worker 
274*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error);
275*cfb92d14SAndroid Build Coastguard Worker 
276*cfb92d14SAndroid Build Coastguard Worker     /**
277*cfb92d14SAndroid Build Coastguard Worker      * @cli br onlinkprefix local
278*cfb92d14SAndroid Build Coastguard Worker      * @code
279*cfb92d14SAndroid Build Coastguard Worker      * br onlinkprefix local
280*cfb92d14SAndroid Build Coastguard Worker      * fd41:2650:a6f5:0::/64
281*cfb92d14SAndroid Build Coastguard Worker      * Done
282*cfb92d14SAndroid Build Coastguard Worker      * @endcode
283*cfb92d14SAndroid Build Coastguard Worker      * @par api_copy
284*cfb92d14SAndroid Build Coastguard Worker      * #otBorderRoutingGetOnLinkPrefix
285*cfb92d14SAndroid Build Coastguard Worker      */
286*cfb92d14SAndroid Build Coastguard Worker     if (outputPrefixTypes & kPrefixTypeLocal)
287*cfb92d14SAndroid Build Coastguard Worker     {
288*cfb92d14SAndroid Build Coastguard Worker         otIp6Prefix local;
289*cfb92d14SAndroid Build Coastguard Worker 
290*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = otBorderRoutingGetOnLinkPrefix(GetInstancePtr(), &local));
291*cfb92d14SAndroid Build Coastguard Worker 
292*cfb92d14SAndroid Build Coastguard Worker         OutputFormat("%s", outputPrefixTypes == kPrefixTypeLocal ? "" : "Local: ");
293*cfb92d14SAndroid Build Coastguard Worker         OutputIp6PrefixLine(local);
294*cfb92d14SAndroid Build Coastguard Worker     }
295*cfb92d14SAndroid Build Coastguard Worker 
296*cfb92d14SAndroid Build Coastguard Worker     /**
297*cfb92d14SAndroid Build Coastguard Worker      * @cli br onlinkprefix favored
298*cfb92d14SAndroid Build Coastguard Worker      * @code
299*cfb92d14SAndroid Build Coastguard Worker      * br onlinkprefix favored
300*cfb92d14SAndroid Build Coastguard Worker      * 2600::0:1234:da12::/64
301*cfb92d14SAndroid Build Coastguard Worker      * Done
302*cfb92d14SAndroid Build Coastguard Worker      * @endcode
303*cfb92d14SAndroid Build Coastguard Worker      * @par api_copy
304*cfb92d14SAndroid Build Coastguard Worker      * #otBorderRoutingGetFavoredOnLinkPrefix
305*cfb92d14SAndroid Build Coastguard Worker      */
306*cfb92d14SAndroid Build Coastguard Worker     if (outputPrefixTypes & kPrefixTypeFavored)
307*cfb92d14SAndroid Build Coastguard Worker     {
308*cfb92d14SAndroid Build Coastguard Worker         otIp6Prefix favored;
309*cfb92d14SAndroid Build Coastguard Worker 
310*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = otBorderRoutingGetFavoredOnLinkPrefix(GetInstancePtr(), &favored));
311*cfb92d14SAndroid Build Coastguard Worker 
312*cfb92d14SAndroid Build Coastguard Worker         OutputFormat("%s", outputPrefixTypes == kPrefixTypeFavored ? "" : "Favored: ");
313*cfb92d14SAndroid Build Coastguard Worker         OutputIp6PrefixLine(favored);
314*cfb92d14SAndroid Build Coastguard Worker     }
315*cfb92d14SAndroid Build Coastguard Worker 
316*cfb92d14SAndroid Build Coastguard Worker exit:
317*cfb92d14SAndroid Build Coastguard Worker     return error;
318*cfb92d14SAndroid Build Coastguard Worker }
319*cfb92d14SAndroid Build Coastguard Worker 
320*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_NAT64_BORDER_ROUTING_ENABLE
321*cfb92d14SAndroid Build Coastguard Worker 
322*cfb92d14SAndroid Build Coastguard Worker /**
323*cfb92d14SAndroid Build Coastguard Worker  * @cli br nat64prefix
324*cfb92d14SAndroid Build Coastguard Worker  * @code
325*cfb92d14SAndroid Build Coastguard Worker  * br nat64prefix
326*cfb92d14SAndroid Build Coastguard Worker  * Local: fd14:1078:b3d5:b0b0:0:0::/96
327*cfb92d14SAndroid Build Coastguard Worker  * Favored: fd14:1078:b3d5:b0b0:0:0::/96 prf:low
328*cfb92d14SAndroid Build Coastguard Worker  * Done
329*cfb92d14SAndroid Build Coastguard Worker  * @endcode
330*cfb92d14SAndroid Build Coastguard Worker  * @par
331*cfb92d14SAndroid Build Coastguard Worker  * Outputs both local and favored NAT64 prefixes.
332*cfb92d14SAndroid Build Coastguard Worker  * @sa otBorderRoutingGetNat64Prefix
333*cfb92d14SAndroid Build Coastguard Worker  * @sa otBorderRoutingGetFavoredNat64Prefix
334*cfb92d14SAndroid Build Coastguard Worker  */
Process(Arg aArgs[])335*cfb92d14SAndroid Build Coastguard Worker template <> otError Br::Process<Cmd("nat64prefix")>(Arg aArgs[])
336*cfb92d14SAndroid Build Coastguard Worker {
337*cfb92d14SAndroid Build Coastguard Worker     otError    error = OT_ERROR_NONE;
338*cfb92d14SAndroid Build Coastguard Worker     PrefixType outputPrefixTypes;
339*cfb92d14SAndroid Build Coastguard Worker 
340*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = ParsePrefixTypeArgs(aArgs, outputPrefixTypes));
341*cfb92d14SAndroid Build Coastguard Worker 
342*cfb92d14SAndroid Build Coastguard Worker     /**
343*cfb92d14SAndroid Build Coastguard Worker      * @cli br nat64prefix local
344*cfb92d14SAndroid Build Coastguard Worker      * @code
345*cfb92d14SAndroid Build Coastguard Worker      * br nat64prefix local
346*cfb92d14SAndroid Build Coastguard Worker      * fd14:1078:b3d5:b0b0:0:0::/96
347*cfb92d14SAndroid Build Coastguard Worker      * Done
348*cfb92d14SAndroid Build Coastguard Worker      * @endcode
349*cfb92d14SAndroid Build Coastguard Worker      * @par api_copy
350*cfb92d14SAndroid Build Coastguard Worker      * #otBorderRoutingGetNat64Prefix
351*cfb92d14SAndroid Build Coastguard Worker      */
352*cfb92d14SAndroid Build Coastguard Worker     if (outputPrefixTypes & kPrefixTypeLocal)
353*cfb92d14SAndroid Build Coastguard Worker     {
354*cfb92d14SAndroid Build Coastguard Worker         otIp6Prefix local;
355*cfb92d14SAndroid Build Coastguard Worker 
356*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = otBorderRoutingGetNat64Prefix(GetInstancePtr(), &local));
357*cfb92d14SAndroid Build Coastguard Worker 
358*cfb92d14SAndroid Build Coastguard Worker         OutputFormat("%s", outputPrefixTypes == kPrefixTypeLocal ? "" : "Local: ");
359*cfb92d14SAndroid Build Coastguard Worker         OutputIp6PrefixLine(local);
360*cfb92d14SAndroid Build Coastguard Worker     }
361*cfb92d14SAndroid Build Coastguard Worker 
362*cfb92d14SAndroid Build Coastguard Worker     /**
363*cfb92d14SAndroid Build Coastguard Worker      * @cli br nat64prefix favored
364*cfb92d14SAndroid Build Coastguard Worker      * @code
365*cfb92d14SAndroid Build Coastguard Worker      * br nat64prefix favored
366*cfb92d14SAndroid Build Coastguard Worker      * fd14:1078:b3d5:b0b0:0:0::/96 prf:low
367*cfb92d14SAndroid Build Coastguard Worker      * Done
368*cfb92d14SAndroid Build Coastguard Worker      * @endcode
369*cfb92d14SAndroid Build Coastguard Worker      * @par api_copy
370*cfb92d14SAndroid Build Coastguard Worker      * #otBorderRoutingGetFavoredNat64Prefix
371*cfb92d14SAndroid Build Coastguard Worker      */
372*cfb92d14SAndroid Build Coastguard Worker     if (outputPrefixTypes & kPrefixTypeFavored)
373*cfb92d14SAndroid Build Coastguard Worker     {
374*cfb92d14SAndroid Build Coastguard Worker         otIp6Prefix       favored;
375*cfb92d14SAndroid Build Coastguard Worker         otRoutePreference preference;
376*cfb92d14SAndroid Build Coastguard Worker 
377*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = otBorderRoutingGetFavoredNat64Prefix(GetInstancePtr(), &favored, &preference));
378*cfb92d14SAndroid Build Coastguard Worker 
379*cfb92d14SAndroid Build Coastguard Worker         OutputFormat("%s", outputPrefixTypes == kPrefixTypeFavored ? "" : "Favored: ");
380*cfb92d14SAndroid Build Coastguard Worker         OutputIp6Prefix(favored);
381*cfb92d14SAndroid Build Coastguard Worker         OutputLine(" prf:%s", PreferenceToString(preference));
382*cfb92d14SAndroid Build Coastguard Worker     }
383*cfb92d14SAndroid Build Coastguard Worker 
384*cfb92d14SAndroid Build Coastguard Worker exit:
385*cfb92d14SAndroid Build Coastguard Worker     return error;
386*cfb92d14SAndroid Build Coastguard Worker }
387*cfb92d14SAndroid Build Coastguard Worker 
388*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_NAT64_BORDER_ROUTING_ENABLE
389*cfb92d14SAndroid Build Coastguard Worker 
390*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_BORDER_ROUTING_TRACK_PEER_BR_INFO_ENABLE
391*cfb92d14SAndroid Build Coastguard Worker 
Process(Arg aArgs[])392*cfb92d14SAndroid Build Coastguard Worker template <> otError Br::Process<Cmd("peers")>(Arg aArgs[])
393*cfb92d14SAndroid Build Coastguard Worker {
394*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
395*cfb92d14SAndroid Build Coastguard Worker 
396*cfb92d14SAndroid Build Coastguard Worker     /**
397*cfb92d14SAndroid Build Coastguard Worker      * @cli br peers
398*cfb92d14SAndroid Build Coastguard Worker      * @code
399*cfb92d14SAndroid Build Coastguard Worker      * br peers
400*cfb92d14SAndroid Build Coastguard Worker      * rloc16:0x5c00 age:00:00:49
401*cfb92d14SAndroid Build Coastguard Worker      * rloc16:0xf800 age:00:01:51
402*cfb92d14SAndroid Build Coastguard Worker      * Done
403*cfb92d14SAndroid Build Coastguard Worker      * @endcode
404*cfb92d14SAndroid Build Coastguard Worker      * @par
405*cfb92d14SAndroid Build Coastguard Worker      * Get the list of peer BRs found in Network Data entries.
406*cfb92d14SAndroid Build Coastguard Worker      * `OPENTHREAD_CONFIG_BORDER_ROUTING_TRACK_PEER_BR_INFO_ENABLE` is required.
407*cfb92d14SAndroid Build Coastguard Worker      * Peer BRs are other devices within the Thread mesh that provide external IP connectivity. A device is considered
408*cfb92d14SAndroid Build Coastguard Worker      * to provide external IP connectivity if at least one of the following conditions is met regarding its Network
409*cfb92d14SAndroid Build Coastguard Worker      * Data entries:
410*cfb92d14SAndroid Build Coastguard Worker      * - It has added at least one external route entry.
411*cfb92d14SAndroid Build Coastguard Worker      * - It has added at least one prefix entry with both the default-route and on-mesh flags set.
412*cfb92d14SAndroid Build Coastguard Worker      * - It has added at least one domain prefix (with both the domain and on-mesh flags set).
413*cfb92d14SAndroid Build Coastguard Worker      * The list of peer BRs specifically excludes the current device, even if its is itself acting as a BR.
414*cfb92d14SAndroid Build Coastguard Worker      * Info per BR entry:
415*cfb92d14SAndroid Build Coastguard Worker      * - RLOC16 of the BR
416*cfb92d14SAndroid Build Coastguard Worker      * - Age as the duration interval since this BR appeared in Network Data. It is formatted as `{hh}:{mm}:{ss}` for
417*cfb92d14SAndroid Build Coastguard Worker      *   hours, minutes, seconds, if the duration is less than 24 hours. If the duration is 24 hours or more, the
418*cfb92d14SAndroid Build Coastguard Worker      *   format is `{dd}d.{hh}:{mm}:{ss}` for days, hours, minutes, seconds.
419*cfb92d14SAndroid Build Coastguard Worker      * @sa otBorderRoutingGetNextPrefixTableEntry
420*cfb92d14SAndroid Build Coastguard Worker      */
421*cfb92d14SAndroid Build Coastguard Worker     if (aArgs[0].IsEmpty())
422*cfb92d14SAndroid Build Coastguard Worker     {
423*cfb92d14SAndroid Build Coastguard Worker         otBorderRoutingPrefixTableIterator   iterator;
424*cfb92d14SAndroid Build Coastguard Worker         otBorderRoutingPeerBorderRouterEntry peerBrEntry;
425*cfb92d14SAndroid Build Coastguard Worker         char                                 ageString[OT_DURATION_STRING_SIZE];
426*cfb92d14SAndroid Build Coastguard Worker 
427*cfb92d14SAndroid Build Coastguard Worker         otBorderRoutingPrefixTableInitIterator(GetInstancePtr(), &iterator);
428*cfb92d14SAndroid Build Coastguard Worker 
429*cfb92d14SAndroid Build Coastguard Worker         while (otBorderRoutingGetNextPeerBrEntry(GetInstancePtr(), &iterator, &peerBrEntry) == OT_ERROR_NONE)
430*cfb92d14SAndroid Build Coastguard Worker         {
431*cfb92d14SAndroid Build Coastguard Worker             otConvertDurationInSecondsToString(peerBrEntry.mAge, ageString, sizeof(ageString));
432*cfb92d14SAndroid Build Coastguard Worker             OutputLine("rloc16:0x%04x age:%s", peerBrEntry.mRloc16, ageString);
433*cfb92d14SAndroid Build Coastguard Worker         }
434*cfb92d14SAndroid Build Coastguard Worker     }
435*cfb92d14SAndroid Build Coastguard Worker     /**
436*cfb92d14SAndroid Build Coastguard Worker      * @cli br peers count
437*cfb92d14SAndroid Build Coastguard Worker      * @code
438*cfb92d14SAndroid Build Coastguard Worker      * br peers count
439*cfb92d14SAndroid Build Coastguard Worker      * 2 min-age:00:00:47
440*cfb92d14SAndroid Build Coastguard Worker      * Done
441*cfb92d14SAndroid Build Coastguard Worker      * @endcode
442*cfb92d14SAndroid Build Coastguard Worker      * @par api_copy
443*cfb92d14SAndroid Build Coastguard Worker      * #otBorderRoutingCountPeerBrs
444*cfb92d14SAndroid Build Coastguard Worker      */
445*cfb92d14SAndroid Build Coastguard Worker     else if (aArgs[0] == "count")
446*cfb92d14SAndroid Build Coastguard Worker     {
447*cfb92d14SAndroid Build Coastguard Worker         uint32_t minAge;
448*cfb92d14SAndroid Build Coastguard Worker         uint16_t count;
449*cfb92d14SAndroid Build Coastguard Worker         char     ageString[OT_DURATION_STRING_SIZE];
450*cfb92d14SAndroid Build Coastguard Worker 
451*cfb92d14SAndroid Build Coastguard Worker         VerifyOrExit(aArgs[1].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
452*cfb92d14SAndroid Build Coastguard Worker 
453*cfb92d14SAndroid Build Coastguard Worker         count = otBorderRoutingCountPeerBrs(GetInstancePtr(), &minAge);
454*cfb92d14SAndroid Build Coastguard Worker         otConvertDurationInSecondsToString(minAge, ageString, sizeof(ageString));
455*cfb92d14SAndroid Build Coastguard Worker         OutputLine("%u min-age:%s", count, ageString);
456*cfb92d14SAndroid Build Coastguard Worker     }
457*cfb92d14SAndroid Build Coastguard Worker     else
458*cfb92d14SAndroid Build Coastguard Worker     {
459*cfb92d14SAndroid Build Coastguard Worker         error = OT_ERROR_INVALID_ARGS;
460*cfb92d14SAndroid Build Coastguard Worker     }
461*cfb92d14SAndroid Build Coastguard Worker 
462*cfb92d14SAndroid Build Coastguard Worker exit:
463*cfb92d14SAndroid Build Coastguard Worker     return error;
464*cfb92d14SAndroid Build Coastguard Worker }
465*cfb92d14SAndroid Build Coastguard Worker 
466*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_BORDER_ROUTING_TRACK_PEER_BR_INFO_ENABLE
467*cfb92d14SAndroid Build Coastguard Worker 
468*cfb92d14SAndroid Build Coastguard Worker /**
469*cfb92d14SAndroid Build Coastguard Worker  * @cli br prefixtable
470*cfb92d14SAndroid Build Coastguard Worker  * @code
471*cfb92d14SAndroid Build Coastguard Worker  * br prefixtable
472*cfb92d14SAndroid Build Coastguard Worker  * prefix:fd00:1234:5678:0::/64, on-link:no, ms-since-rx:29526, lifetime:1800, route-prf:med,
473*cfb92d14SAndroid Build Coastguard Worker  * router:ff02:0:0:0:0:0:0:1 (M:0 O:0 Stub:1)
474*cfb92d14SAndroid Build Coastguard Worker  * prefix:1200:abba:baba:0::/64, on-link:yes, ms-since-rx:29527, lifetime:1800, preferred:1800,
475*cfb92d14SAndroid Build Coastguard Worker  * router:ff02:0:0:0:0:0:0:1 (M:0 O:0 Stub:1)
476*cfb92d14SAndroid Build Coastguard Worker  * Done
477*cfb92d14SAndroid Build Coastguard Worker  * @endcode
478*cfb92d14SAndroid Build Coastguard Worker  * @par
479*cfb92d14SAndroid Build Coastguard Worker  * Get the discovered prefixes by Border Routing Manager on the infrastructure link.
480*cfb92d14SAndroid Build Coastguard Worker  * Info per prefix entry:
481*cfb92d14SAndroid Build Coastguard Worker  * - The prefix
482*cfb92d14SAndroid Build Coastguard Worker  * - Whether the prefix is on-link or route
483*cfb92d14SAndroid Build Coastguard Worker  * - Milliseconds since last received Router Advertisement containing this prefix
484*cfb92d14SAndroid Build Coastguard Worker  * - Prefix lifetime in seconds
485*cfb92d14SAndroid Build Coastguard Worker  * - Preferred lifetime in seconds only if prefix is on-link
486*cfb92d14SAndroid Build Coastguard Worker  * - Route preference (low, med, high) only if prefix is route (not on-link)
487*cfb92d14SAndroid Build Coastguard Worker  * - The router IPv6 address which advertising this prefix
488*cfb92d14SAndroid Build Coastguard Worker  * - Flags in received Router Advertisement header:
489*cfb92d14SAndroid Build Coastguard Worker  *   - M: Managed Address Config flag
490*cfb92d14SAndroid Build Coastguard Worker  *   - O: Other Config flag
491*cfb92d14SAndroid Build Coastguard Worker  *   - Stub: Stub Router flag (indicates whether the router is a stub router)
492*cfb92d14SAndroid Build Coastguard Worker  * @sa otBorderRoutingGetNextPrefixTableEntry
493*cfb92d14SAndroid Build Coastguard Worker  */
Process(Arg aArgs[])494*cfb92d14SAndroid Build Coastguard Worker template <> otError Br::Process<Cmd("prefixtable")>(Arg aArgs[])
495*cfb92d14SAndroid Build Coastguard Worker {
496*cfb92d14SAndroid Build Coastguard Worker     otError                            error = OT_ERROR_NONE;
497*cfb92d14SAndroid Build Coastguard Worker     otBorderRoutingPrefixTableIterator iterator;
498*cfb92d14SAndroid Build Coastguard Worker     otBorderRoutingPrefixTableEntry    entry;
499*cfb92d14SAndroid Build Coastguard Worker 
500*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(aArgs[0].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
501*cfb92d14SAndroid Build Coastguard Worker 
502*cfb92d14SAndroid Build Coastguard Worker     otBorderRoutingPrefixTableInitIterator(GetInstancePtr(), &iterator);
503*cfb92d14SAndroid Build Coastguard Worker 
504*cfb92d14SAndroid Build Coastguard Worker     while (otBorderRoutingGetNextPrefixTableEntry(GetInstancePtr(), &iterator, &entry) == OT_ERROR_NONE)
505*cfb92d14SAndroid Build Coastguard Worker     {
506*cfb92d14SAndroid Build Coastguard Worker         char string[OT_IP6_PREFIX_STRING_SIZE];
507*cfb92d14SAndroid Build Coastguard Worker 
508*cfb92d14SAndroid Build Coastguard Worker         otIp6PrefixToString(&entry.mPrefix, string, sizeof(string));
509*cfb92d14SAndroid Build Coastguard Worker         OutputFormat("prefix:%s, on-link:%s, ms-since-rx:%lu, lifetime:%lu, ", string, entry.mIsOnLink ? "yes" : "no",
510*cfb92d14SAndroid Build Coastguard Worker                      ToUlong(entry.mMsecSinceLastUpdate), ToUlong(entry.mValidLifetime));
511*cfb92d14SAndroid Build Coastguard Worker 
512*cfb92d14SAndroid Build Coastguard Worker         if (entry.mIsOnLink)
513*cfb92d14SAndroid Build Coastguard Worker         {
514*cfb92d14SAndroid Build Coastguard Worker             OutputFormat("preferred:%lu, ", ToUlong(entry.mPreferredLifetime));
515*cfb92d14SAndroid Build Coastguard Worker         }
516*cfb92d14SAndroid Build Coastguard Worker         else
517*cfb92d14SAndroid Build Coastguard Worker         {
518*cfb92d14SAndroid Build Coastguard Worker             OutputFormat("route-prf:%s, ", PreferenceToString(entry.mRoutePreference));
519*cfb92d14SAndroid Build Coastguard Worker         }
520*cfb92d14SAndroid Build Coastguard Worker 
521*cfb92d14SAndroid Build Coastguard Worker         OutputFormat("router:");
522*cfb92d14SAndroid Build Coastguard Worker         OutputRouterInfo(entry.mRouter, kShortVersion);
523*cfb92d14SAndroid Build Coastguard Worker     }
524*cfb92d14SAndroid Build Coastguard Worker 
525*cfb92d14SAndroid Build Coastguard Worker exit:
526*cfb92d14SAndroid Build Coastguard Worker     return error;
527*cfb92d14SAndroid Build Coastguard Worker }
528*cfb92d14SAndroid Build Coastguard Worker 
529*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE
Process(Arg aArgs[])530*cfb92d14SAndroid Build Coastguard Worker template <> otError Br::Process<Cmd("pd")>(Arg aArgs[])
531*cfb92d14SAndroid Build Coastguard Worker {
532*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
533*cfb92d14SAndroid Build Coastguard Worker 
534*cfb92d14SAndroid Build Coastguard Worker     /**
535*cfb92d14SAndroid Build Coastguard Worker      * @cli br pd (enable,disable)
536*cfb92d14SAndroid Build Coastguard Worker      * @code
537*cfb92d14SAndroid Build Coastguard Worker      * br pd enable
538*cfb92d14SAndroid Build Coastguard Worker      * Done
539*cfb92d14SAndroid Build Coastguard Worker      * @endcode
540*cfb92d14SAndroid Build Coastguard Worker      * @code
541*cfb92d14SAndroid Build Coastguard Worker      * br pd disable
542*cfb92d14SAndroid Build Coastguard Worker      * Done
543*cfb92d14SAndroid Build Coastguard Worker      * @endcode
544*cfb92d14SAndroid Build Coastguard Worker      * @cparam br pd @ca{enable|disable}
545*cfb92d14SAndroid Build Coastguard Worker      * @par api_copy
546*cfb92d14SAndroid Build Coastguard Worker      * #otBorderRoutingDhcp6PdSetEnabled
547*cfb92d14SAndroid Build Coastguard Worker      *
548*cfb92d14SAndroid Build Coastguard Worker      */
549*cfb92d14SAndroid Build Coastguard Worker     if (ProcessEnableDisable(aArgs, otBorderRoutingDhcp6PdSetEnabled) == OT_ERROR_NONE)
550*cfb92d14SAndroid Build Coastguard Worker     {
551*cfb92d14SAndroid Build Coastguard Worker     }
552*cfb92d14SAndroid Build Coastguard Worker     /**
553*cfb92d14SAndroid Build Coastguard Worker      * @cli br pd state
554*cfb92d14SAndroid Build Coastguard Worker      * @code
555*cfb92d14SAndroid Build Coastguard Worker      * br pd state
556*cfb92d14SAndroid Build Coastguard Worker      * running
557*cfb92d14SAndroid Build Coastguard Worker      * Done
558*cfb92d14SAndroid Build Coastguard Worker      * @endcode
559*cfb92d14SAndroid Build Coastguard Worker      * @par api_copy
560*cfb92d14SAndroid Build Coastguard Worker      * #otBorderRoutingDhcp6PdGetState
561*cfb92d14SAndroid Build Coastguard Worker      */
562*cfb92d14SAndroid Build Coastguard Worker     else if (aArgs[0] == "state")
563*cfb92d14SAndroid Build Coastguard Worker     {
564*cfb92d14SAndroid Build Coastguard Worker         static const char *const kDhcpv6PdStateStrings[] = {
565*cfb92d14SAndroid Build Coastguard Worker             "disabled", // (0) OT_BORDER_ROUTING_DHCP6_PD_STATE_DISABLED
566*cfb92d14SAndroid Build Coastguard Worker             "stopped",  // (1) OT_BORDER_ROUTING_DHCP6_PD_STATE_STOPPED
567*cfb92d14SAndroid Build Coastguard Worker             "running",  // (2) OT_BORDER_ROUTING_DHCP6_PD_STATE_RUNNING
568*cfb92d14SAndroid Build Coastguard Worker         };
569*cfb92d14SAndroid Build Coastguard Worker 
570*cfb92d14SAndroid Build Coastguard Worker         static_assert(0 == OT_BORDER_ROUTING_DHCP6_PD_STATE_DISABLED,
571*cfb92d14SAndroid Build Coastguard Worker                       "OT_BORDER_ROUTING_DHCP6_PD_STATE_DISABLED value is not expected!");
572*cfb92d14SAndroid Build Coastguard Worker         static_assert(1 == OT_BORDER_ROUTING_DHCP6_PD_STATE_STOPPED,
573*cfb92d14SAndroid Build Coastguard Worker                       "OT_BORDER_ROUTING_DHCP6_PD_STATE_STOPPED value is not expected!");
574*cfb92d14SAndroid Build Coastguard Worker         static_assert(2 == OT_BORDER_ROUTING_DHCP6_PD_STATE_RUNNING,
575*cfb92d14SAndroid Build Coastguard Worker                       "OT_BORDER_ROUTING_DHCP6_PD_STATE_RUNNING value is not expected!");
576*cfb92d14SAndroid Build Coastguard Worker 
577*cfb92d14SAndroid Build Coastguard Worker         OutputLine("%s", Stringify(otBorderRoutingDhcp6PdGetState(GetInstancePtr()), kDhcpv6PdStateStrings));
578*cfb92d14SAndroid Build Coastguard Worker     }
579*cfb92d14SAndroid Build Coastguard Worker     /**
580*cfb92d14SAndroid Build Coastguard Worker      * @cli br pd omrprefix
581*cfb92d14SAndroid Build Coastguard Worker      * @code
582*cfb92d14SAndroid Build Coastguard Worker      * br pd omrprefix
583*cfb92d14SAndroid Build Coastguard Worker      * 2001:db8:cafe:0:0/64 lifetime:1800 preferred:1800
584*cfb92d14SAndroid Build Coastguard Worker      * Done
585*cfb92d14SAndroid Build Coastguard Worker      * @endcode
586*cfb92d14SAndroid Build Coastguard Worker      * @par api_copy
587*cfb92d14SAndroid Build Coastguard Worker      * #otBorderRoutingGetPdOmrPrefix
588*cfb92d14SAndroid Build Coastguard Worker      */
589*cfb92d14SAndroid Build Coastguard Worker     else if (aArgs[0] == "omrprefix")
590*cfb92d14SAndroid Build Coastguard Worker     {
591*cfb92d14SAndroid Build Coastguard Worker         otBorderRoutingPrefixTableEntry entry;
592*cfb92d14SAndroid Build Coastguard Worker 
593*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = otBorderRoutingGetPdOmrPrefix(GetInstancePtr(), &entry));
594*cfb92d14SAndroid Build Coastguard Worker 
595*cfb92d14SAndroid Build Coastguard Worker         OutputIp6Prefix(entry.mPrefix);
596*cfb92d14SAndroid Build Coastguard Worker         OutputLine(" lifetime:%lu preferred:%lu", ToUlong(entry.mValidLifetime), ToUlong(entry.mPreferredLifetime));
597*cfb92d14SAndroid Build Coastguard Worker     }
598*cfb92d14SAndroid Build Coastguard Worker     else
599*cfb92d14SAndroid Build Coastguard Worker     {
600*cfb92d14SAndroid Build Coastguard Worker         ExitNow(error = OT_ERROR_INVALID_COMMAND);
601*cfb92d14SAndroid Build Coastguard Worker     }
602*cfb92d14SAndroid Build Coastguard Worker 
603*cfb92d14SAndroid Build Coastguard Worker exit:
604*cfb92d14SAndroid Build Coastguard Worker     return error;
605*cfb92d14SAndroid Build Coastguard Worker }
606*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE
607*cfb92d14SAndroid Build Coastguard Worker 
608*cfb92d14SAndroid Build Coastguard Worker /**
609*cfb92d14SAndroid Build Coastguard Worker  * @cli br routers
610*cfb92d14SAndroid Build Coastguard Worker  * @code
611*cfb92d14SAndroid Build Coastguard Worker  * br routers
612*cfb92d14SAndroid Build Coastguard Worker  * ff02:0:0:0:0:0:0:1 (M:0 O:0 Stub:1) ms-since-rx:1505 reachable:yes age:00:18:13
613*cfb92d14SAndroid Build Coastguard Worker  * Done
614*cfb92d14SAndroid Build Coastguard Worker  * @endcode
615*cfb92d14SAndroid Build Coastguard Worker  * @par
616*cfb92d14SAndroid Build Coastguard Worker  * Get the list of discovered routers by Border Routing Manager on the infrastructure link.
617*cfb92d14SAndroid Build Coastguard Worker  * Info per router:
618*cfb92d14SAndroid Build Coastguard Worker  * - The router IPv6 address
619*cfb92d14SAndroid Build Coastguard Worker  * - Flags in received Router Advertisement header:
620*cfb92d14SAndroid Build Coastguard Worker  *   - M: Managed Address Config flag
621*cfb92d14SAndroid Build Coastguard Worker  *   - O: Other Config flag
622*cfb92d14SAndroid Build Coastguard Worker  *   - Stub: Stub Router flag (indicates whether the router is a stub router)
623*cfb92d14SAndroid Build Coastguard Worker  * - Milliseconds since last received message from this router
624*cfb92d14SAndroid Build Coastguard Worker  * - Reachability flag: A router is marked as unreachable if it fails to respond to multiple Neighbor Solicitation
625*cfb92d14SAndroid Build Coastguard Worker  *   probes.
626*cfb92d14SAndroid Build Coastguard Worker  * - Age: Duration interval since this router was first discovered. It is formatted as `{hh}:{mm}:{ss}` for  hours,
627*cfb92d14SAndroid Build Coastguard Worker  *   minutes, seconds, if the duration is less than 24 hours. If the duration is 24 hours or more, the format is
628*cfb92d14SAndroid Build Coastguard Worker  *   `{dd}d.{hh}:{mm}:{ss}` for days, hours, minutes, seconds.
629*cfb92d14SAndroid Build Coastguard Worker  * - `(this BR)` is appended when the router is the local device itself.
630*cfb92d14SAndroid Build Coastguard Worker  * - `(peer BR)` is appended when the router is likely a peer BR connected to the same Thread mesh. This requires
631*cfb92d14SAndroid Build Coastguard Worker  *   `OPENTHREAD_CONFIG_BORDER_ROUTING_TRACK_PEER_BR_INFO_ENABLE`.
632*cfb92d14SAndroid Build Coastguard Worker  * @sa otBorderRoutingGetNextRouterEntry
633*cfb92d14SAndroid Build Coastguard Worker  */
Process(Arg aArgs[])634*cfb92d14SAndroid Build Coastguard Worker template <> otError Br::Process<Cmd("routers")>(Arg aArgs[])
635*cfb92d14SAndroid Build Coastguard Worker {
636*cfb92d14SAndroid Build Coastguard Worker     otError                            error = OT_ERROR_NONE;
637*cfb92d14SAndroid Build Coastguard Worker     otBorderRoutingPrefixTableIterator iterator;
638*cfb92d14SAndroid Build Coastguard Worker     otBorderRoutingRouterEntry         entry;
639*cfb92d14SAndroid Build Coastguard Worker 
640*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(aArgs[0].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
641*cfb92d14SAndroid Build Coastguard Worker 
642*cfb92d14SAndroid Build Coastguard Worker     otBorderRoutingPrefixTableInitIterator(GetInstancePtr(), &iterator);
643*cfb92d14SAndroid Build Coastguard Worker 
644*cfb92d14SAndroid Build Coastguard Worker     while (otBorderRoutingGetNextRouterEntry(GetInstancePtr(), &iterator, &entry) == OT_ERROR_NONE)
645*cfb92d14SAndroid Build Coastguard Worker     {
646*cfb92d14SAndroid Build Coastguard Worker         OutputRouterInfo(entry, kLongVersion);
647*cfb92d14SAndroid Build Coastguard Worker     }
648*cfb92d14SAndroid Build Coastguard Worker 
649*cfb92d14SAndroid Build Coastguard Worker exit:
650*cfb92d14SAndroid Build Coastguard Worker     return error;
651*cfb92d14SAndroid Build Coastguard Worker }
652*cfb92d14SAndroid Build Coastguard Worker 
OutputRouterInfo(const otBorderRoutingRouterEntry & aEntry,RouterOutputMode aMode)653*cfb92d14SAndroid Build Coastguard Worker void Br::OutputRouterInfo(const otBorderRoutingRouterEntry &aEntry, RouterOutputMode aMode)
654*cfb92d14SAndroid Build Coastguard Worker {
655*cfb92d14SAndroid Build Coastguard Worker     OutputIp6Address(aEntry.mAddress);
656*cfb92d14SAndroid Build Coastguard Worker     OutputFormat(" (M:%u O:%u Stub:%u)", aEntry.mManagedAddressConfigFlag, aEntry.mOtherConfigFlag,
657*cfb92d14SAndroid Build Coastguard Worker                  aEntry.mStubRouterFlag);
658*cfb92d14SAndroid Build Coastguard Worker 
659*cfb92d14SAndroid Build Coastguard Worker     if (aMode == kLongVersion)
660*cfb92d14SAndroid Build Coastguard Worker     {
661*cfb92d14SAndroid Build Coastguard Worker         char ageString[OT_DURATION_STRING_SIZE];
662*cfb92d14SAndroid Build Coastguard Worker 
663*cfb92d14SAndroid Build Coastguard Worker         otConvertDurationInSecondsToString(aEntry.mAge, ageString, sizeof(ageString));
664*cfb92d14SAndroid Build Coastguard Worker 
665*cfb92d14SAndroid Build Coastguard Worker         OutputFormat(" ms-since-rx:%lu reachable:%s age:%s", ToUlong(aEntry.mMsecSinceLastUpdate),
666*cfb92d14SAndroid Build Coastguard Worker                      aEntry.mIsReachable ? "yes" : "no", ageString);
667*cfb92d14SAndroid Build Coastguard Worker 
668*cfb92d14SAndroid Build Coastguard Worker         if (aEntry.mIsLocalDevice)
669*cfb92d14SAndroid Build Coastguard Worker         {
670*cfb92d14SAndroid Build Coastguard Worker             OutputFormat(" (this BR)");
671*cfb92d14SAndroid Build Coastguard Worker         }
672*cfb92d14SAndroid Build Coastguard Worker 
673*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_BORDER_ROUTING_TRACK_PEER_BR_INFO_ENABLE
674*cfb92d14SAndroid Build Coastguard Worker         if (aEntry.mIsPeerBr)
675*cfb92d14SAndroid Build Coastguard Worker         {
676*cfb92d14SAndroid Build Coastguard Worker             OutputFormat(" (peer BR)");
677*cfb92d14SAndroid Build Coastguard Worker         }
678*cfb92d14SAndroid Build Coastguard Worker #endif
679*cfb92d14SAndroid Build Coastguard Worker     }
680*cfb92d14SAndroid Build Coastguard Worker 
681*cfb92d14SAndroid Build Coastguard Worker     OutputNewLine();
682*cfb92d14SAndroid Build Coastguard Worker }
683*cfb92d14SAndroid Build Coastguard Worker 
Process(Arg aArgs[])684*cfb92d14SAndroid Build Coastguard Worker template <> otError Br::Process<Cmd("raoptions")>(Arg aArgs[])
685*cfb92d14SAndroid Build Coastguard Worker {
686*cfb92d14SAndroid Build Coastguard Worker     static constexpr uint16_t kMaxExtraOptions = 800;
687*cfb92d14SAndroid Build Coastguard Worker 
688*cfb92d14SAndroid Build Coastguard Worker     otError  error = OT_ERROR_NONE;
689*cfb92d14SAndroid Build Coastguard Worker     uint8_t  options[kMaxExtraOptions];
690*cfb92d14SAndroid Build Coastguard Worker     uint16_t length;
691*cfb92d14SAndroid Build Coastguard Worker 
692*cfb92d14SAndroid Build Coastguard Worker     /**
693*cfb92d14SAndroid Build Coastguard Worker      * @cli br raoptions (set,clear)
694*cfb92d14SAndroid Build Coastguard Worker      * @code
695*cfb92d14SAndroid Build Coastguard Worker      * br raoptions 0400ff00020001
696*cfb92d14SAndroid Build Coastguard Worker      * Done
697*cfb92d14SAndroid Build Coastguard Worker      * @endcode
698*cfb92d14SAndroid Build Coastguard Worker      * @code
699*cfb92d14SAndroid Build Coastguard Worker      * br raoptions clear
700*cfb92d14SAndroid Build Coastguard Worker      * Done
701*cfb92d14SAndroid Build Coastguard Worker      * @endcode
702*cfb92d14SAndroid Build Coastguard Worker      * @cparam br raoptions @ca{options|clear}
703*cfb92d14SAndroid Build Coastguard Worker      * `br raoptions clear` passes a `nullptr` to #otBorderRoutingSetExtraRouterAdvertOptions.
704*cfb92d14SAndroid Build Coastguard Worker      * Otherwise, you can pass the `options` byte as hex data.
705*cfb92d14SAndroid Build Coastguard Worker      * @par api_copy
706*cfb92d14SAndroid Build Coastguard Worker      * #otBorderRoutingSetExtraRouterAdvertOptions
707*cfb92d14SAndroid Build Coastguard Worker      */
708*cfb92d14SAndroid Build Coastguard Worker     if (aArgs[0] == "clear")
709*cfb92d14SAndroid Build Coastguard Worker     {
710*cfb92d14SAndroid Build Coastguard Worker         length = 0;
711*cfb92d14SAndroid Build Coastguard Worker     }
712*cfb92d14SAndroid Build Coastguard Worker     else
713*cfb92d14SAndroid Build Coastguard Worker     {
714*cfb92d14SAndroid Build Coastguard Worker         length = sizeof(options);
715*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = aArgs[0].ParseAsHexString(length, options));
716*cfb92d14SAndroid Build Coastguard Worker     }
717*cfb92d14SAndroid Build Coastguard Worker 
718*cfb92d14SAndroid Build Coastguard Worker     error = otBorderRoutingSetExtraRouterAdvertOptions(GetInstancePtr(), length > 0 ? options : nullptr, length);
719*cfb92d14SAndroid Build Coastguard Worker 
720*cfb92d14SAndroid Build Coastguard Worker exit:
721*cfb92d14SAndroid Build Coastguard Worker     return error;
722*cfb92d14SAndroid Build Coastguard Worker }
723*cfb92d14SAndroid Build Coastguard Worker 
Process(Arg aArgs[])724*cfb92d14SAndroid Build Coastguard Worker template <> otError Br::Process<Cmd("rioprf")>(Arg aArgs[])
725*cfb92d14SAndroid Build Coastguard Worker {
726*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
727*cfb92d14SAndroid Build Coastguard Worker 
728*cfb92d14SAndroid Build Coastguard Worker     /**
729*cfb92d14SAndroid Build Coastguard Worker      * @cli br rioprf
730*cfb92d14SAndroid Build Coastguard Worker      * @code
731*cfb92d14SAndroid Build Coastguard Worker      * br rioprf
732*cfb92d14SAndroid Build Coastguard Worker      * med
733*cfb92d14SAndroid Build Coastguard Worker      * Done
734*cfb92d14SAndroid Build Coastguard Worker      * @endcode
735*cfb92d14SAndroid Build Coastguard Worker      * @par api_copy
736*cfb92d14SAndroid Build Coastguard Worker      * #otBorderRoutingGetRouteInfoOptionPreference
737*cfb92d14SAndroid Build Coastguard Worker      */
738*cfb92d14SAndroid Build Coastguard Worker     if (aArgs[0].IsEmpty())
739*cfb92d14SAndroid Build Coastguard Worker     {
740*cfb92d14SAndroid Build Coastguard Worker         OutputLine("%s", PreferenceToString(otBorderRoutingGetRouteInfoOptionPreference(GetInstancePtr())));
741*cfb92d14SAndroid Build Coastguard Worker     }
742*cfb92d14SAndroid Build Coastguard Worker     /**
743*cfb92d14SAndroid Build Coastguard Worker      * @cli br rioprf clear
744*cfb92d14SAndroid Build Coastguard Worker      * @code
745*cfb92d14SAndroid Build Coastguard Worker      * br rioprf clear
746*cfb92d14SAndroid Build Coastguard Worker      * Done
747*cfb92d14SAndroid Build Coastguard Worker      * @endcode
748*cfb92d14SAndroid Build Coastguard Worker      * @par api_copy
749*cfb92d14SAndroid Build Coastguard Worker      * #otBorderRoutingClearRouteInfoOptionPreference
750*cfb92d14SAndroid Build Coastguard Worker      */
751*cfb92d14SAndroid Build Coastguard Worker     else if (aArgs[0] == "clear")
752*cfb92d14SAndroid Build Coastguard Worker     {
753*cfb92d14SAndroid Build Coastguard Worker         otBorderRoutingClearRouteInfoOptionPreference(GetInstancePtr());
754*cfb92d14SAndroid Build Coastguard Worker     }
755*cfb92d14SAndroid Build Coastguard Worker     /**
756*cfb92d14SAndroid Build Coastguard Worker      * @cli br rioprf (high,med,low)
757*cfb92d14SAndroid Build Coastguard Worker      * @code
758*cfb92d14SAndroid Build Coastguard Worker      * br rioprf low
759*cfb92d14SAndroid Build Coastguard Worker      * Done
760*cfb92d14SAndroid Build Coastguard Worker      * @endcode
761*cfb92d14SAndroid Build Coastguard Worker      * @cparam br rioprf [@ca{high}|@ca{med}|@ca{low}]
762*cfb92d14SAndroid Build Coastguard Worker      * @par api_copy
763*cfb92d14SAndroid Build Coastguard Worker      * #otBorderRoutingSetRouteInfoOptionPreference
764*cfb92d14SAndroid Build Coastguard Worker      */
765*cfb92d14SAndroid Build Coastguard Worker     else
766*cfb92d14SAndroid Build Coastguard Worker     {
767*cfb92d14SAndroid Build Coastguard Worker         otRoutePreference preference;
768*cfb92d14SAndroid Build Coastguard Worker 
769*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = Interpreter::ParsePreference(aArgs[0], preference));
770*cfb92d14SAndroid Build Coastguard Worker         otBorderRoutingSetRouteInfoOptionPreference(GetInstancePtr(), preference);
771*cfb92d14SAndroid Build Coastguard Worker     }
772*cfb92d14SAndroid Build Coastguard Worker 
773*cfb92d14SAndroid Build Coastguard Worker exit:
774*cfb92d14SAndroid Build Coastguard Worker     return error;
775*cfb92d14SAndroid Build Coastguard Worker }
776*cfb92d14SAndroid Build Coastguard Worker 
Process(Arg aArgs[])777*cfb92d14SAndroid Build Coastguard Worker template <> otError Br::Process<Cmd("routeprf")>(Arg aArgs[])
778*cfb92d14SAndroid Build Coastguard Worker {
779*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
780*cfb92d14SAndroid Build Coastguard Worker 
781*cfb92d14SAndroid Build Coastguard Worker     /**
782*cfb92d14SAndroid Build Coastguard Worker      * @cli br routeprf
783*cfb92d14SAndroid Build Coastguard Worker      * @code
784*cfb92d14SAndroid Build Coastguard Worker      * br routeprf
785*cfb92d14SAndroid Build Coastguard Worker      * med
786*cfb92d14SAndroid Build Coastguard Worker      * Done
787*cfb92d14SAndroid Build Coastguard Worker      * @endcode
788*cfb92d14SAndroid Build Coastguard Worker      * @par api_copy
789*cfb92d14SAndroid Build Coastguard Worker      * #otBorderRoutingGetRoutePreference
790*cfb92d14SAndroid Build Coastguard Worker      */
791*cfb92d14SAndroid Build Coastguard Worker     if (aArgs[0].IsEmpty())
792*cfb92d14SAndroid Build Coastguard Worker     {
793*cfb92d14SAndroid Build Coastguard Worker         OutputLine("%s", PreferenceToString(otBorderRoutingGetRoutePreference(GetInstancePtr())));
794*cfb92d14SAndroid Build Coastguard Worker     }
795*cfb92d14SAndroid Build Coastguard Worker     /**
796*cfb92d14SAndroid Build Coastguard Worker      * @cli br routeprf clear
797*cfb92d14SAndroid Build Coastguard Worker      * @code
798*cfb92d14SAndroid Build Coastguard Worker      * br routeprf clear
799*cfb92d14SAndroid Build Coastguard Worker      * Done
800*cfb92d14SAndroid Build Coastguard Worker      * @endcode
801*cfb92d14SAndroid Build Coastguard Worker      * @par api_copy
802*cfb92d14SAndroid Build Coastguard Worker      * #otBorderRoutingClearRoutePreference
803*cfb92d14SAndroid Build Coastguard Worker      */
804*cfb92d14SAndroid Build Coastguard Worker     else if (aArgs[0] == "clear")
805*cfb92d14SAndroid Build Coastguard Worker     {
806*cfb92d14SAndroid Build Coastguard Worker         otBorderRoutingClearRoutePreference(GetInstancePtr());
807*cfb92d14SAndroid Build Coastguard Worker     }
808*cfb92d14SAndroid Build Coastguard Worker     /**
809*cfb92d14SAndroid Build Coastguard Worker      * @cli br routeprf (high,med,low)
810*cfb92d14SAndroid Build Coastguard Worker      * @code
811*cfb92d14SAndroid Build Coastguard Worker      * br routeprf low
812*cfb92d14SAndroid Build Coastguard Worker      * Done
813*cfb92d14SAndroid Build Coastguard Worker      * @endcode
814*cfb92d14SAndroid Build Coastguard Worker      * @cparam br routeprf [@ca{high}|@ca{med}|@ca{low}]
815*cfb92d14SAndroid Build Coastguard Worker      * @par api_copy
816*cfb92d14SAndroid Build Coastguard Worker      * #otBorderRoutingSetRoutePreference
817*cfb92d14SAndroid Build Coastguard Worker      */
818*cfb92d14SAndroid Build Coastguard Worker     else
819*cfb92d14SAndroid Build Coastguard Worker     {
820*cfb92d14SAndroid Build Coastguard Worker         otRoutePreference preference;
821*cfb92d14SAndroid Build Coastguard Worker 
822*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = Interpreter::ParsePreference(aArgs[0], preference));
823*cfb92d14SAndroid Build Coastguard Worker         otBorderRoutingSetRoutePreference(GetInstancePtr(), preference);
824*cfb92d14SAndroid Build Coastguard Worker     }
825*cfb92d14SAndroid Build Coastguard Worker 
826*cfb92d14SAndroid Build Coastguard Worker exit:
827*cfb92d14SAndroid Build Coastguard Worker     return error;
828*cfb92d14SAndroid Build Coastguard Worker }
829*cfb92d14SAndroid Build Coastguard Worker 
830*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_IP6_BR_COUNTERS_ENABLE
831*cfb92d14SAndroid Build Coastguard Worker 
832*cfb92d14SAndroid Build Coastguard Worker /**
833*cfb92d14SAndroid Build Coastguard Worker  * @cli br counters
834*cfb92d14SAndroid Build Coastguard Worker  * @code
835*cfb92d14SAndroid Build Coastguard Worker  * br counters
836*cfb92d14SAndroid Build Coastguard Worker  * Inbound Unicast: Packets 4 Bytes 320
837*cfb92d14SAndroid Build Coastguard Worker  * Inbound Multicast: Packets 0 Bytes 0
838*cfb92d14SAndroid Build Coastguard Worker  * Outbound Unicast: Packets 2 Bytes 160
839*cfb92d14SAndroid Build Coastguard Worker  * Outbound Multicast: Packets 0 Bytes 0
840*cfb92d14SAndroid Build Coastguard Worker  * RA Rx: 4
841*cfb92d14SAndroid Build Coastguard Worker  * RA TxSuccess: 2
842*cfb92d14SAndroid Build Coastguard Worker  * RA TxFailed: 0
843*cfb92d14SAndroid Build Coastguard Worker  * RS Rx: 0
844*cfb92d14SAndroid Build Coastguard Worker  * RS TxSuccess: 2
845*cfb92d14SAndroid Build Coastguard Worker  * RS TxFailed: 0
846*cfb92d14SAndroid Build Coastguard Worker  * Done
847*cfb92d14SAndroid Build Coastguard Worker  * @endcode
848*cfb92d14SAndroid Build Coastguard Worker  * @par api_copy
849*cfb92d14SAndroid Build Coastguard Worker  * #otIp6GetBorderRoutingCounters
850*cfb92d14SAndroid Build Coastguard Worker  */
Process(Arg aArgs[])851*cfb92d14SAndroid Build Coastguard Worker template <> otError Br::Process<Cmd("counters")>(Arg aArgs[])
852*cfb92d14SAndroid Build Coastguard Worker {
853*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
854*cfb92d14SAndroid Build Coastguard Worker 
855*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(aArgs[0].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
856*cfb92d14SAndroid Build Coastguard Worker     Interpreter::GetInterpreter().OutputBorderRouterCounters();
857*cfb92d14SAndroid Build Coastguard Worker 
858*cfb92d14SAndroid Build Coastguard Worker exit:
859*cfb92d14SAndroid Build Coastguard Worker     return error;
860*cfb92d14SAndroid Build Coastguard Worker }
861*cfb92d14SAndroid Build Coastguard Worker 
862*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_IP6_BR_COUNTERS_ENABLE
863*cfb92d14SAndroid Build Coastguard Worker 
Process(Arg aArgs[])864*cfb92d14SAndroid Build Coastguard Worker otError Br::Process(Arg aArgs[])
865*cfb92d14SAndroid Build Coastguard Worker {
866*cfb92d14SAndroid Build Coastguard Worker #define CmdEntry(aCommandString)                          \
867*cfb92d14SAndroid Build Coastguard Worker     {                                                     \
868*cfb92d14SAndroid Build Coastguard Worker         aCommandString, &Br::Process<Cmd(aCommandString)> \
869*cfb92d14SAndroid Build Coastguard Worker     }
870*cfb92d14SAndroid Build Coastguard Worker 
871*cfb92d14SAndroid Build Coastguard Worker     static constexpr Command kCommands[] = {
872*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_IP6_BR_COUNTERS_ENABLE
873*cfb92d14SAndroid Build Coastguard Worker         CmdEntry("counters"),
874*cfb92d14SAndroid Build Coastguard Worker #endif
875*cfb92d14SAndroid Build Coastguard Worker         CmdEntry("disable"),
876*cfb92d14SAndroid Build Coastguard Worker         CmdEntry("enable"),
877*cfb92d14SAndroid Build Coastguard Worker         CmdEntry("init"),
878*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_NAT64_BORDER_ROUTING_ENABLE
879*cfb92d14SAndroid Build Coastguard Worker         CmdEntry("nat64prefix"),
880*cfb92d14SAndroid Build Coastguard Worker #endif
881*cfb92d14SAndroid Build Coastguard Worker         CmdEntry("omrprefix"),
882*cfb92d14SAndroid Build Coastguard Worker         CmdEntry("onlinkprefix"),
883*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE
884*cfb92d14SAndroid Build Coastguard Worker         CmdEntry("pd"),
885*cfb92d14SAndroid Build Coastguard Worker #endif
886*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_BORDER_ROUTING_TRACK_PEER_BR_INFO_ENABLE
887*cfb92d14SAndroid Build Coastguard Worker         CmdEntry("peers"),
888*cfb92d14SAndroid Build Coastguard Worker #endif
889*cfb92d14SAndroid Build Coastguard Worker         CmdEntry("prefixtable"),
890*cfb92d14SAndroid Build Coastguard Worker         CmdEntry("raoptions"),
891*cfb92d14SAndroid Build Coastguard Worker         CmdEntry("rioprf"),
892*cfb92d14SAndroid Build Coastguard Worker         CmdEntry("routeprf"),
893*cfb92d14SAndroid Build Coastguard Worker         CmdEntry("routers"),
894*cfb92d14SAndroid Build Coastguard Worker         CmdEntry("state"),
895*cfb92d14SAndroid Build Coastguard Worker     };
896*cfb92d14SAndroid Build Coastguard Worker 
897*cfb92d14SAndroid Build Coastguard Worker #undef CmdEntry
898*cfb92d14SAndroid Build Coastguard Worker 
899*cfb92d14SAndroid Build Coastguard Worker     static_assert(BinarySearch::IsSorted(kCommands), "kCommands is not sorted");
900*cfb92d14SAndroid Build Coastguard Worker 
901*cfb92d14SAndroid Build Coastguard Worker     otError        error = OT_ERROR_INVALID_COMMAND;
902*cfb92d14SAndroid Build Coastguard Worker     const Command *command;
903*cfb92d14SAndroid Build Coastguard Worker 
904*cfb92d14SAndroid Build Coastguard Worker     if (aArgs[0].IsEmpty() || (aArgs[0] == "help"))
905*cfb92d14SAndroid Build Coastguard Worker     {
906*cfb92d14SAndroid Build Coastguard Worker         OutputCommandTable(kCommands);
907*cfb92d14SAndroid Build Coastguard Worker         ExitNow(error = aArgs[0].IsEmpty() ? error : OT_ERROR_NONE);
908*cfb92d14SAndroid Build Coastguard Worker     }
909*cfb92d14SAndroid Build Coastguard Worker 
910*cfb92d14SAndroid Build Coastguard Worker     command = BinarySearch::Find(aArgs[0].GetCString(), kCommands);
911*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(command != nullptr);
912*cfb92d14SAndroid Build Coastguard Worker 
913*cfb92d14SAndroid Build Coastguard Worker     error = (this->*command->mHandler)(aArgs + 1);
914*cfb92d14SAndroid Build Coastguard Worker 
915*cfb92d14SAndroid Build Coastguard Worker exit:
916*cfb92d14SAndroid Build Coastguard Worker     return error;
917*cfb92d14SAndroid Build Coastguard Worker }
918*cfb92d14SAndroid Build Coastguard Worker 
919*cfb92d14SAndroid Build Coastguard Worker } // namespace Cli
920*cfb92d14SAndroid Build Coastguard Worker } // namespace ot
921*cfb92d14SAndroid Build Coastguard Worker 
922*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
923