• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/netdata.h>
52 #include <openthread/ping_sender.h>
53 #include <openthread/sntp.h>
54 #include <openthread/tcp.h>
55 #include <openthread/thread.h>
56 #include <openthread/thread_ftd.h>
57 #include <openthread/udp.h>
58 
59 #include "cli/cli_bbr.hpp"
60 #include "cli/cli_br.hpp"
61 #include "cli/cli_coap.hpp"
62 #include "cli/cli_coap_secure.hpp"
63 #include "cli/cli_commissioner.hpp"
64 #include "cli/cli_config.h"
65 #include "cli/cli_dataset.hpp"
66 #include "cli/cli_dns.hpp"
67 #include "cli/cli_history.hpp"
68 #include "cli/cli_joiner.hpp"
69 #include "cli/cli_link_metrics.hpp"
70 #include "cli/cli_mac_filter.hpp"
71 #include "cli/cli_mdns.hpp"
72 #include "cli/cli_mesh_diag.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 namespace Cli {
97 
98 extern "C" void otCliPlatLogv(otLogLevel, otLogRegion, const char *, va_list);
99 extern "C" void otCliAppendResult(otError aError);
100 extern "C" void otCliOutputBytes(const uint8_t *aBytes, uint8_t aLength);
101 extern "C" void otCliOutputFormat(const char *aFmt, ...);
102 
103 /**
104  * Implements the CLI interpreter.
105  */
106 class Interpreter : public OutputImplementer, public Utils
107 {
108 #if OPENTHREAD_FTD || OPENTHREAD_MTD
109     friend class Br;
110     friend class Bbr;
111     friend class Commissioner;
112     friend class Dns;
113     friend class Joiner;
114     friend class LinkMetrics;
115     friend class Mdns;
116     friend class MeshDiag;
117     friend class NetworkData;
118     friend class PingSender;
119     friend class SrpClient;
120     friend class SrpServer;
121 #endif
122     friend void otCliPlatLogv(otLogLevel, otLogRegion, const char *, va_list);
123     friend void otCliAppendResult(otError aError);
124     friend void otCliOutputBytes(const uint8_t *aBytes, uint8_t aLength);
125     friend void otCliOutputFormat(const char *aFmt, ...);
126 
127 public:
128     /**
129      * Constructor
130      *
131      * @param[in]  aInstance    The OpenThread instance structure.
132      * @param[in]  aCallback    A callback method called to process CLI output.
133      * @param[in]  aContext     A user context pointer.
134      */
135     explicit Interpreter(Instance *aInstance, otCliOutputCallback aCallback, void *aContext);
136 
137     /**
138      * Returns a reference to the interpreter object.
139      *
140      * @returns A reference to the interpreter object.
141      */
GetInterpreter(void)142     static Interpreter &GetInterpreter(void)
143     {
144         OT_ASSERT(sInterpreter != nullptr);
145 
146         return *sInterpreter;
147     }
148 
149     /**
150      * Initializes the Console interpreter.
151      *
152      * @param[in]  aInstance  The OpenThread instance structure.
153      * @param[in]  aCallback  A pointer to a callback method.
154      * @param[in]  aContext   A pointer to a user context.
155      */
156     static void Initialize(otInstance *aInstance, otCliOutputCallback aCallback, void *aContext);
157 
158     /**
159      * Returns whether the interpreter is initialized.
160      *
161      * @returns  Whether the interpreter is initialized.
162      */
IsInitialized(void)163     static bool IsInitialized(void) { return sInterpreter != nullptr; }
164 
165     /**
166      * Interprets a CLI command.
167      *
168      * @param[in]  aLine        A pointer to a command string.
169      */
170     void ProcessLine(char *aLine);
171 
172     /**
173      * Adds commands to the user command table.
174      *
175      * @param[in]  aCommands  A pointer to an array with user commands.
176      * @param[in]  aLength    @p aUserCommands length.
177      * @param[in]  aContext   @p aUserCommands length.
178      *
179      * @retval OT_ERROR_NONE    Successfully updated command table with commands from @p aCommands.
180      * @retval OT_ERROR_FAILED  No available UserCommandsEntry to register requested user commands.
181      */
182     otError SetUserCommands(const otCliCommand *aCommands, uint8_t aLength, void *aContext);
183 
184 protected:
185     static Interpreter *sInterpreter;
186 
187 private:
188     static constexpr uint8_t  kIndentSize            = 4;
189     static constexpr uint16_t kMaxArgs               = 32;
190     static constexpr uint16_t kMaxLineLength         = OPENTHREAD_CONFIG_CLI_MAX_LINE_LENGTH;
191     static constexpr uint16_t kMaxUserCommandEntries = OPENTHREAD_CONFIG_CLI_MAX_USER_CMD_ENTRIES;
192 
193     static constexpr uint32_t kNetworkDiagnosticTimeoutMsecs = 5000;
194     static constexpr uint32_t kLocateTimeoutMsecs            = 2500;
195 
196     static constexpr uint16_t kMaxTxtDataSize = OPENTHREAD_CONFIG_CLI_TXT_RECORD_MAX_SIZE;
197 
198     using Command = CommandEntry<Interpreter>;
199 
200     void OutputPrompt(void);
201     void OutputResult(otError aError);
202 
203 #if OPENTHREAD_CONFIG_IP6_BR_COUNTERS_ENABLE
204     void OutputBorderRouterCounters(void);
205 #endif
206 
207     otError ProcessCommand(Arg aArgs[]);
208 
209     template <CommandId kCommandId> otError Process(Arg aArgs[]);
210 
211     otError ProcessUserCommands(Arg aArgs[]);
212 
213 #if OPENTHREAD_FTD || OPENTHREAD_MTD
214 
215 #if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
216 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
217     otError ProcessBackboneRouterLocal(Arg aArgs[]);
218 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
219     otError ProcessBackboneRouterMgmtMlr(Arg aArgs[]);
220     void    PrintMulticastListenersTable(void);
221 #endif
222 #endif
223 #endif
224 
225 #if OPENTHREAD_FTD
226     void OutputEidCacheEntry(const otCacheEntryInfo &aEntry);
227 #endif
228 #if OPENTHREAD_CONFIG_TMF_ANYCAST_LOCATOR_ENABLE
229     static void HandleLocateResult(void               *aContext,
230                                    otError             aError,
231                                    const otIp6Address *aMeshLocalAddress,
232                                    uint16_t            aRloc16);
233     void        HandleLocateResult(otError aError, const otIp6Address *aMeshLocalAddress, uint16_t aRloc16);
234 #endif
235 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE && OPENTHREAD_CONFIG_COMMISSIONER_ENABLE
236     static void HandleMlrRegResult(void               *aContext,
237                                    otError             aError,
238                                    uint8_t             aMlrStatus,
239                                    const otIp6Address *aFailedAddresses,
240                                    uint8_t             aFailedAddressNum);
241     void        HandleMlrRegResult(otError             aError,
242                                    uint8_t             aMlrStatus,
243                                    const otIp6Address *aFailedAddresses,
244                                    uint8_t             aFailedAddressNum);
245 #endif
246 #if OPENTHREAD_CONFIG_MULTI_RADIO
247     void OutputMultiRadioInfo(const otMultiRadioNeighborInfo &aMultiRadioInfo);
248 #endif
249 
250     static void HandleActiveScanResult(otActiveScanResult *aResult, void *aContext);
251     static void HandleEnergyScanResult(otEnergyScanResult *aResult, void *aContext);
252     static void HandleLinkPcapReceive(const otRadioFrame *aFrame, bool aIsTx, void *aContext);
253 
254 #if OPENTHREAD_CONFIG_TMF_NETDIAG_CLIENT_ENABLE
255     void HandleDiagnosticGetResponse(otError aError, const otMessage *aMessage, const Ip6::MessageInfo *aMessageInfo);
256     static void HandleDiagnosticGetResponse(otError              aError,
257                                             otMessage           *aMessage,
258                                             const otMessageInfo *aMessageInfo,
259                                             void                *aContext);
260 
261     void OutputMode(uint8_t aIndentSize, const otLinkModeConfig &aMode);
262     void OutputConnectivity(uint8_t aIndentSize, const otNetworkDiagConnectivity &aConnectivity);
263     void OutputRoute(uint8_t aIndentSize, const otNetworkDiagRoute &aRoute);
264     void OutputRouteData(uint8_t aIndentSize, const otNetworkDiagRouteData &aRouteData);
265     void OutputLeaderData(uint8_t aIndentSize, const otLeaderData &aLeaderData);
266     void OutputNetworkDiagMacCounters(uint8_t aIndentSize, const otNetworkDiagMacCounters &aMacCounters);
267     void OutputNetworkDiagMleCounters(uint8_t aIndentSize, const otNetworkDiagMleCounters &aMleCounters);
268     void OutputChildTableEntry(uint8_t aIndentSize, const otNetworkDiagChildEntry &aChildEntry);
269 #endif
270 
271 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
272     void OutputTrelCounters(const otTrelCounters &aCounters);
273 #endif
274 #if OPENTHREAD_CONFIG_NAT64_TRANSLATOR_ENABLE
275     void OutputNat64Counters(const otNat64Counters &aCounters);
276 #endif
277 #if OPENTHREAD_CONFIG_RADIO_STATS_ENABLE
278     void OutputRadioStatsTime(const char *aTimeName, uint64_t aTimeUs, uint64_t aTotalTime);
279 #endif
280 
281 #if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
282     static void HandleSntpResponse(void *aContext, uint64_t aTime, otError aResult);
283 #endif
284 
285     void HandleActiveScanResult(otActiveScanResult *aResult);
286     void HandleEnergyScanResult(otEnergyScanResult *aResult);
287     void HandleLinkPcapReceive(const otRadioFrame *aFrame, bool aIsTx);
288 #if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
289     void HandleSntpResponse(uint64_t aTime, otError aResult);
290 #endif
291 
292 #if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE
293     void OutputBorderAgentCounters(const otBorderAgentCounters &aCounters);
294 #if OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE
295     static void HandleBorderAgentEphemeralKeyStateChange(void *aContext);
296     void        HandleBorderAgentEphemeralKeyStateChange(void);
297 #endif
298 #endif
299 
300     static void HandleDetachGracefullyResult(void *aContext);
301     void        HandleDetachGracefullyResult(void);
302 
303 #if OPENTHREAD_FTD
304     static void HandleDiscoveryRequest(const otThreadDiscoveryRequestInfo *aInfo, void *aContext);
305     void        HandleDiscoveryRequest(const otThreadDiscoveryRequestInfo &aInfo);
306 #endif
307 
308 #if OPENTHREAD_CONFIG_CLI_REGISTER_IP6_RECV_CALLBACK
309     static void HandleIp6Receive(otMessage *aMessage, void *aContext);
310 #endif
311 
312 #if OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE
313     static void HandleWakeupResult(otError aError, void *aContext);
314     void        HandleWakeupResult(otError aError);
315 #endif
316 
317 #endif // OPENTHREAD_FTD || OPENTHREAD_MTD
318 
319 #if OPENTHREAD_CONFIG_DIAG_ENABLE
320     static void HandleDiagOutput(const char *aFormat, va_list aArguments, void *aContext);
321     void        HandleDiagOutput(const char *aFormat, va_list aArguments);
322 #endif
323 
324     void SetCommandTimeout(uint32_t aTimeoutMilli);
325 
326     static void HandleTimer(Timer &aTimer);
327     void        HandleTimer(void);
328 
329     struct UserCommandsEntry
330     {
331         const otCliCommand *mCommands;
332         uint8_t             mLength;
333         void               *mContext;
334     };
335 
336     UserCommandsEntry mUserCommands[kMaxUserCommandEntries];
337     bool              mCommandIsPending;
338     bool              mInternalDebugCommand;
339 
340     TimerMilliContext mTimer;
341 
342 #if OPENTHREAD_FTD || OPENTHREAD_MTD
343 #if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
344     bool mSntpQueryingInProgress;
345 #endif
346 
347     Dataset     mDataset;
348     NetworkData mNetworkData;
349     UdpExample  mUdp;
350 
351 #if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
352     MacFilter mMacFilter;
353 #endif
354 
355 #if OPENTHREAD_CLI_DNS_ENABLE
356     Dns mDns;
357 #endif
358 
359 #if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE && OPENTHREAD_CONFIG_MULTICAST_DNS_PUBLIC_API_ENABLE
360     Mdns mMdns;
361 #endif
362 
363 #if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
364     Bbr mBbr;
365 #endif
366 
367 #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
368     Br mBr;
369 #endif
370 
371 #if OPENTHREAD_CONFIG_TCP_ENABLE && OPENTHREAD_CONFIG_CLI_TCP_ENABLE
372     TcpExample mTcp;
373 #endif
374 
375 #if OPENTHREAD_CONFIG_COAP_API_ENABLE
376     Coap mCoap;
377 #endif
378 
379 #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
380     CoapSecure mCoapSecure;
381 #endif
382 
383 #if OPENTHREAD_CONFIG_COMMISSIONER_ENABLE && OPENTHREAD_FTD
384     Commissioner mCommissioner;
385 #endif
386 
387 #if OPENTHREAD_CONFIG_JOINER_ENABLE
388     Joiner mJoiner;
389 #endif
390 
391 #if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
392     SrpClient mSrpClient;
393 #endif
394 
395 #if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
396     SrpServer mSrpServer;
397 #endif
398 
399 #if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
400     History mHistory;
401 #endif
402 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
403     LinkMetrics mLinkMetrics;
404 #endif
405 #if OPENTHREAD_CONFIG_BLE_TCAT_ENABLE && OPENTHREAD_CONFIG_CLI_BLE_SECURE_ENABLE
406     Tcat mTcat;
407 #endif
408 #if OPENTHREAD_CONFIG_PING_SENDER_ENABLE
409     PingSender mPing;
410 #endif
411 #if OPENTHREAD_CONFIG_MESH_DIAG_ENABLE && OPENTHREAD_FTD
412     MeshDiag mMeshDiag;
413 #endif
414 #endif // OPENTHREAD_FTD || OPENTHREAD_MTD
415 
416 #if OPENTHREAD_CONFIG_TMF_ANYCAST_LOCATOR_ENABLE
417     bool mLocateInProgress : 1;
418 #endif
419 };
420 
421 } // namespace Cli
422 } // namespace ot
423 
424 #endif // CLI_HPP_
425