xref: /aosp_15_r20/external/openthread/src/cli/cli.hpp (revision cfb92d1480a9e65faed56933e9c12405f45898b4)
1 /*
2  *  Copyright (c) 2016, The OpenThread Authors.
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions are met:
7  *  1. Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  *  2. Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *  3. Neither the name of the copyright holder nor the
13  *     names of its contributors may be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  *  POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 /**
30  * @file
31  *   This file contains definitions for the CLI interpreter.
32  */
33 
34 #ifndef CLI_HPP_
35 #define CLI_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include "cli_config.h"
40 
41 #include <stdarg.h>
42 
43 #include <openthread/border_agent.h>
44 #include <openthread/cli.h>
45 #include <openthread/dataset.h>
46 #include <openthread/dns_client.h>
47 #include <openthread/instance.h>
48 #include <openthread/ip6.h>
49 #include <openthread/link.h>
50 #include <openthread/logging.h>
51 #include <openthread/mesh_diag.h>
52 #include <openthread/netdata.h>
53 #include <openthread/ping_sender.h>
54 #include <openthread/sntp.h>
55 #include <openthread/tcp.h>
56 #include <openthread/thread.h>
57 #include <openthread/thread_ftd.h>
58 #include <openthread/udp.h>
59 
60 #include "cli/cli_bbr.hpp"
61 #include "cli/cli_br.hpp"
62 #include "cli/cli_coap.hpp"
63 #include "cli/cli_coap_secure.hpp"
64 #include "cli/cli_commissioner.hpp"
65 #include "cli/cli_config.h"
66 #include "cli/cli_dataset.hpp"
67 #include "cli/cli_dns.hpp"
68 #include "cli/cli_history.hpp"
69 #include "cli/cli_joiner.hpp"
70 #include "cli/cli_link_metrics.hpp"
71 #include "cli/cli_mac_filter.hpp"
72 #include "cli/cli_mdns.hpp"
73 #include "cli/cli_network_data.hpp"
74 #include "cli/cli_ping.hpp"
75 #include "cli/cli_srp_client.hpp"
76 #include "cli/cli_srp_server.hpp"
77 #include "cli/cli_tcat.hpp"
78 #include "cli/cli_tcp.hpp"
79 #include "cli/cli_udp.hpp"
80 #include "cli/cli_utils.hpp"
81 
82 #include "common/array.hpp"
83 #include "common/code_utils.hpp"
84 #include "common/debug.hpp"
85 #include "common/type_traits.hpp"
86 #include "instance/instance.hpp"
87 
88 namespace ot {
89 
90 /**
91  * @namespace ot::Cli
92  *
93  * @brief
94  *   This namespace contains definitions for the CLI interpreter.
95  *
96  */
97 namespace Cli {
98 
99 extern "C" void otCliPlatLogv(otLogLevel, otLogRegion, const char *, va_list);
100 extern "C" void otCliAppendResult(otError aError);
101 extern "C" void otCliOutputBytes(const uint8_t *aBytes, uint8_t aLength);
102 extern "C" void otCliOutputFormat(const char *aFmt, ...);
103 
104 /**
105  * Implements the CLI interpreter.
106  *
107  */
108 class Interpreter : public OutputImplementer, public Utils
109 {
110 #if OPENTHREAD_FTD || OPENTHREAD_MTD
111     friend class Br;
112     friend class Bbr;
113     friend class Commissioner;
114     friend class Dns;
115     friend class Joiner;
116     friend class LinkMetrics;
117     friend class Mdns;
118     friend class NetworkData;
119     friend class PingSender;
120     friend class SrpClient;
121     friend class SrpServer;
122 #endif
123     friend void otCliPlatLogv(otLogLevel, otLogRegion, const char *, va_list);
124     friend void otCliAppendResult(otError aError);
125     friend void otCliOutputBytes(const uint8_t *aBytes, uint8_t aLength);
126     friend void otCliOutputFormat(const char *aFmt, ...);
127 
128 public:
129     /**
130      * Constructor
131      *
132      * @param[in]  aInstance    The OpenThread instance structure.
133      * @param[in]  aCallback    A callback method called to process CLI output.
134      * @param[in]  aContext     A user context pointer.
135      */
136     explicit Interpreter(Instance *aInstance, otCliOutputCallback aCallback, void *aContext);
137 
138     /**
139      * Returns a reference to the interpreter object.
140      *
141      * @returns A reference to the interpreter object.
142      *
143      */
GetInterpreter(void)144     static Interpreter &GetInterpreter(void)
145     {
146         OT_ASSERT(sInterpreter != nullptr);
147 
148         return *sInterpreter;
149     }
150 
151     /**
152      * Initializes the Console interpreter.
153      *
154      * @param[in]  aInstance  The OpenThread instance structure.
155      * @param[in]  aCallback  A pointer to a callback method.
156      * @param[in]  aContext   A pointer to a user context.
157      *
158      */
159     static void Initialize(otInstance *aInstance, otCliOutputCallback aCallback, void *aContext);
160 
161     /**
162      * Returns whether the interpreter is initialized.
163      *
164      * @returns  Whether the interpreter is initialized.
165      *
166      */
IsInitialized(void)167     static bool IsInitialized(void) { return sInterpreter != nullptr; }
168 
169     /**
170      * Interprets a CLI command.
171      *
172      * @param[in]  aBuf        A pointer to a string.
173      *
174      */
175     void ProcessLine(char *aBuf);
176 
177     /**
178      * Adds commands to the user command table.
179      *
180      * @param[in]  aCommands  A pointer to an array with user commands.
181      * @param[in]  aLength    @p aUserCommands length.
182      * @param[in]  aContext   @p aUserCommands length.
183      *
184      * @retval OT_ERROR_NONE    Successfully updated command table with commands from @p aCommands.
185      * @retval OT_ERROR_FAILED  No available UserCommandsEntry to register requested user commands.
186      */
187     otError SetUserCommands(const otCliCommand *aCommands, uint8_t aLength, void *aContext);
188 
189 protected:
190     static Interpreter *sInterpreter;
191 
192 private:
193     static constexpr uint8_t  kIndentSize            = 4;
194     static constexpr uint16_t kMaxArgs               = 32;
195     static constexpr uint16_t kMaxLineLength         = OPENTHREAD_CONFIG_CLI_MAX_LINE_LENGTH;
196     static constexpr uint16_t kMaxUserCommandEntries = OPENTHREAD_CONFIG_CLI_MAX_USER_CMD_ENTRIES;
197 
198     static constexpr uint32_t kNetworkDiagnosticTimeoutMsecs = 5000;
199     static constexpr uint32_t kLocateTimeoutMsecs            = 2500;
200 
201     static constexpr uint16_t kMaxTxtDataSize = OPENTHREAD_CONFIG_CLI_TXT_RECORD_MAX_SIZE;
202 
203     using Command = CommandEntry<Interpreter>;
204 
205     void OutputPrompt(void);
206     void OutputResult(otError aError);
207 
208 #if OPENTHREAD_CONFIG_IP6_BR_COUNTERS_ENABLE
209     void OutputBorderRouterCounters(void);
210 #endif
211 
212     otError ProcessCommand(Arg aArgs[]);
213 
214     template <CommandId kCommandId> otError Process(Arg aArgs[]);
215 
216     otError ProcessUserCommands(Arg aArgs[]);
217 
218 #if OPENTHREAD_FTD || OPENTHREAD_MTD
219 
220 #if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
221 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
222     otError ProcessBackboneRouterLocal(Arg aArgs[]);
223 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
224     otError ProcessBackboneRouterMgmtMlr(Arg aArgs[]);
225     void    PrintMulticastListenersTable(void);
226 #endif
227 #endif
228 #endif
229 
230 #if OPENTHREAD_FTD
231     void OutputEidCacheEntry(const otCacheEntryInfo &aEntry);
232 #endif
233 #if OPENTHREAD_CONFIG_TMF_ANYCAST_LOCATOR_ENABLE
234     static void HandleLocateResult(void               *aContext,
235                                    otError             aError,
236                                    const otIp6Address *aMeshLocalAddress,
237                                    uint16_t            aRloc16);
238     void        HandleLocateResult(otError aError, const otIp6Address *aMeshLocalAddress, uint16_t aRloc16);
239 #endif
240 #if OPENTHREAD_CONFIG_MESH_DIAG_ENABLE && OPENTHREAD_FTD
241     static void HandleMeshDiagDiscoverDone(otError aError, otMeshDiagRouterInfo *aRouterInfo, void *aContext);
242     void        HandleMeshDiagDiscoverDone(otError aError, otMeshDiagRouterInfo *aRouterInfo);
243     static void HandleMeshDiagQueryChildTableResult(otError                     aError,
244                                                     const otMeshDiagChildEntry *aChildEntry,
245                                                     void                       *aContext);
246     void        HandleMeshDiagQueryChildTableResult(otError aError, const otMeshDiagChildEntry *aChildEntry);
247     static void HandleMeshDiagQueryChildIp6Addrs(otError                    aError,
248                                                  uint16_t                   aChildRloc16,
249                                                  otMeshDiagIp6AddrIterator *aIp6AddrIterator,
250                                                  void                      *aContext);
251     void        HandleMeshDiagQueryChildIp6Addrs(otError                    aError,
252                                                  uint16_t                   aChildRloc16,
253                                                  otMeshDiagIp6AddrIterator *aIp6AddrIterator);
254     static void HandleMeshDiagQueryRouterNeighborTableResult(otError                              aError,
255                                                              const otMeshDiagRouterNeighborEntry *aNeighborEntry,
256                                                              void                                *aContext);
257     void        HandleMeshDiagQueryRouterNeighborTableResult(otError                              aError,
258                                                              const otMeshDiagRouterNeighborEntry *aNeighborEntry);
259 
260 #endif
261 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE && OPENTHREAD_CONFIG_COMMISSIONER_ENABLE
262     static void HandleMlrRegResult(void               *aContext,
263                                    otError             aError,
264                                    uint8_t             aMlrStatus,
265                                    const otIp6Address *aFailedAddresses,
266                                    uint8_t             aFailedAddressNum);
267     void        HandleMlrRegResult(otError             aError,
268                                    uint8_t             aMlrStatus,
269                                    const otIp6Address *aFailedAddresses,
270                                    uint8_t             aFailedAddressNum);
271 #endif
272 #if OPENTHREAD_CONFIG_MULTI_RADIO
273     void OutputMultiRadioInfo(const otMultiRadioNeighborInfo &aMultiRadioInfo);
274 #endif
275 
276     static void HandleActiveScanResult(otActiveScanResult *aResult, void *aContext);
277     static void HandleEnergyScanResult(otEnergyScanResult *aResult, void *aContext);
278     static void HandleLinkPcapReceive(const otRadioFrame *aFrame, bool aIsTx, void *aContext);
279 
280 #if OPENTHREAD_CONFIG_TMF_NETDIAG_CLIENT_ENABLE
281     void HandleDiagnosticGetResponse(otError aError, const otMessage *aMessage, const Ip6::MessageInfo *aMessageInfo);
282     static void HandleDiagnosticGetResponse(otError              aError,
283                                             otMessage           *aMessage,
284                                             const otMessageInfo *aMessageInfo,
285                                             void                *aContext);
286 
287     void OutputMode(uint8_t aIndentSize, const otLinkModeConfig &aMode);
288     void OutputConnectivity(uint8_t aIndentSize, const otNetworkDiagConnectivity &aConnectivity);
289     void OutputRoute(uint8_t aIndentSize, const otNetworkDiagRoute &aRoute);
290     void OutputRouteData(uint8_t aIndentSize, const otNetworkDiagRouteData &aRouteData);
291     void OutputLeaderData(uint8_t aIndentSize, const otLeaderData &aLeaderData);
292     void OutputNetworkDiagMacCounters(uint8_t aIndentSize, const otNetworkDiagMacCounters &aMacCounters);
293     void OutputNetworkDiagMleCounters(uint8_t aIndentSize, const otNetworkDiagMleCounters &aMleCounters);
294     void OutputChildTableEntry(uint8_t aIndentSize, const otNetworkDiagChildEntry &aChildEntry);
295 #endif
296 
297 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
298     void OutputTrelCounters(const otTrelCounters &aCounters);
299 #endif
300 #if OPENTHREAD_CONFIG_NAT64_TRANSLATOR_ENABLE
301     void OutputNat64Counters(const otNat64Counters &aCounters);
302 #endif
303 #if OPENTHREAD_CONFIG_RADIO_STATS_ENABLE
304     void OutputRadioStatsTime(const char *aTimeName, uint64_t aTimeUs, uint64_t aTotalTime);
305 #endif
306 
307 #if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
308     static void HandleSntpResponse(void *aContext, uint64_t aTime, otError aResult);
309 #endif
310 
311     void HandleActiveScanResult(otActiveScanResult *aResult);
312     void HandleEnergyScanResult(otEnergyScanResult *aResult);
313     void HandleLinkPcapReceive(const otRadioFrame *aFrame, bool aIsTx);
314 #if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
315     void HandleSntpResponse(uint64_t aTime, otError aResult);
316 #endif
317 
318 #if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE
319     void OutputBorderAgentCounters(const otBorderAgentCounters &aCounters);
320 #if OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE
321     static void HandleBorderAgentEphemeralKeyStateChange(void *aContext);
322     void        HandleBorderAgentEphemeralKeyStateChange(void);
323 #endif
324 #endif
325 
326     static void HandleDetachGracefullyResult(void *aContext);
327     void        HandleDetachGracefullyResult(void);
328 
329 #if OPENTHREAD_FTD
330     static void HandleDiscoveryRequest(const otThreadDiscoveryRequestInfo *aInfo, void *aContext);
331     void        HandleDiscoveryRequest(const otThreadDiscoveryRequestInfo &aInfo);
332 #endif
333 
334 #if OPENTHREAD_CONFIG_CLI_REGISTER_IP6_RECV_CALLBACK
335     static void HandleIp6Receive(otMessage *aMessage, void *aContext);
336 #endif
337 
338 #endif // OPENTHREAD_FTD || OPENTHREAD_MTD
339 
340 #if OPENTHREAD_CONFIG_DIAG_ENABLE
341     static void HandleDiagOutput(const char *aFormat, va_list aArguments, void *aContext);
342     void        HandleDiagOutput(const char *aFormat, va_list aArguments);
343 #endif
344 
345     void SetCommandTimeout(uint32_t aTimeoutMilli);
346 
347     static void HandleTimer(Timer &aTimer);
348     void        HandleTimer(void);
349 
350     struct UserCommandsEntry
351     {
352         const otCliCommand *mCommands;
353         uint8_t             mLength;
354         void               *mContext;
355     };
356 
357     UserCommandsEntry mUserCommands[kMaxUserCommandEntries];
358     bool              mCommandIsPending;
359     bool              mInternalDebugCommand;
360 
361     TimerMilliContext mTimer;
362 
363 #if OPENTHREAD_FTD || OPENTHREAD_MTD
364 #if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
365     bool mSntpQueryingInProgress;
366 #endif
367 
368     Dataset     mDataset;
369     NetworkData mNetworkData;
370     UdpExample  mUdp;
371 
372 #if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
373     MacFilter mMacFilter;
374 #endif
375 
376 #if OPENTHREAD_CLI_DNS_ENABLE
377     Dns mDns;
378 #endif
379 
380 #if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE && OPENTHREAD_CONFIG_MULTICAST_DNS_PUBLIC_API_ENABLE
381     Mdns mMdns;
382 #endif
383 
384 #if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
385     Bbr mBbr;
386 #endif
387 
388 #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
389     Br mBr;
390 #endif
391 
392 #if OPENTHREAD_CONFIG_TCP_ENABLE && OPENTHREAD_CONFIG_CLI_TCP_ENABLE
393     TcpExample mTcp;
394 #endif
395 
396 #if OPENTHREAD_CONFIG_COAP_API_ENABLE
397     Coap mCoap;
398 #endif
399 
400 #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
401     CoapSecure mCoapSecure;
402 #endif
403 
404 #if OPENTHREAD_CONFIG_COMMISSIONER_ENABLE && OPENTHREAD_FTD
405     Commissioner mCommissioner;
406 #endif
407 
408 #if OPENTHREAD_CONFIG_JOINER_ENABLE
409     Joiner mJoiner;
410 #endif
411 
412 #if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
413     SrpClient mSrpClient;
414 #endif
415 
416 #if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
417     SrpServer mSrpServer;
418 #endif
419 
420 #if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
421     History mHistory;
422 #endif
423 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
424     LinkMetrics mLinkMetrics;
425 #endif
426 #if OPENTHREAD_CONFIG_BLE_TCAT_ENABLE && OPENTHREAD_CONFIG_CLI_BLE_SECURE_ENABLE
427     Tcat mTcat;
428 #endif
429 #if OPENTHREAD_CONFIG_PING_SENDER_ENABLE
430     PingSender mPing;
431 #endif
432 #endif // OPENTHREAD_FTD || OPENTHREAD_MTD
433 
434 #if OPENTHREAD_CONFIG_TMF_ANYCAST_LOCATOR_ENABLE
435     bool mLocateInProgress : 1;
436 #endif
437 };
438 
439 } // namespace Cli
440 } // namespace ot
441 
442 #endif // CLI_HPP_
443