/src/openthread/src/cli/cli.hpp
Line | Count | Source |
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 | | */ |
142 | | static Interpreter &GetInterpreter(void) |
143 | 7.40k | { |
144 | 7.40k | OT_ASSERT(sInterpreter != nullptr); |
145 | | |
146 | 7.40k | return *sInterpreter; |
147 | 7.40k | } |
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 | | */ |
163 | 0 | 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 OutputEnhRoute(uint8_t aIndentSize, const otNetworkDiagEnhRoute &aEnhRoute); |
266 | | void OutputLeaderData(uint8_t aIndentSize, const otLeaderData &aLeaderData); |
267 | | void OutputIp6AddrList(uint8_t aIndentSize, const otNetworkDiagIp6AddrList &aIp6Addrs); |
268 | | void OutputNetworkDiagMacCounters(uint8_t aIndentSize, const otNetworkDiagMacCounters &aMacCounters); |
269 | | void OutputNetworkDiagMleCounters(uint8_t aIndentSize, const otNetworkDiagMleCounters &aMleCounters); |
270 | | void OutputChildTableEntry(uint8_t aIndentSize, const otNetworkDiagChildEntry &aChildEntry); |
271 | | #endif |
272 | | |
273 | | #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE |
274 | | void OutputTrelCounters(const otTrelCounters &aCounters); |
275 | | #endif |
276 | | #if OPENTHREAD_CONFIG_NAT64_TRANSLATOR_ENABLE |
277 | | void OutputNat64Counters(const otNat64Counters &aCounters); |
278 | | #endif |
279 | | #if OPENTHREAD_CONFIG_RADIO_STATS_ENABLE |
280 | | void OutputRadioStatsTime(const char *aTimeName, uint64_t aTimeUs, uint64_t aTotalTime); |
281 | | #endif |
282 | | |
283 | | #if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE |
284 | | static void HandleSntpResponse(void *aContext, uint64_t aTime, otError aResult); |
285 | | #endif |
286 | | |
287 | | void HandleActiveScanResult(otActiveScanResult *aResult); |
288 | | void HandleEnergyScanResult(otEnergyScanResult *aResult); |
289 | | void HandleLinkPcapReceive(const otRadioFrame *aFrame, bool aIsTx); |
290 | | #if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE |
291 | | void HandleSntpResponse(uint64_t aTime, otError aResult); |
292 | | #endif |
293 | | |
294 | | #if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE |
295 | | void OutputBorderAgentCounters(const otBorderAgentCounters &aCounters); |
296 | | #if OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE |
297 | | static void HandleBorderAgentEphemeralKeyStateChange(void *aContext); |
298 | | void HandleBorderAgentEphemeralKeyStateChange(void); |
299 | | #endif |
300 | | #endif |
301 | | |
302 | | static void HandleDetachGracefullyResult(void *aContext); |
303 | | void HandleDetachGracefullyResult(void); |
304 | | |
305 | | #if OPENTHREAD_FTD |
306 | | static void HandleDiscoveryRequest(const otThreadDiscoveryRequestInfo *aInfo, void *aContext); |
307 | | void HandleDiscoveryRequest(const otThreadDiscoveryRequestInfo &aInfo); |
308 | | #endif |
309 | | |
310 | | #if OPENTHREAD_CONFIG_CLI_REGISTER_IP6_RECV_CALLBACK |
311 | | static void HandleIp6Receive(otMessage *aMessage, void *aContext); |
312 | | #endif |
313 | | |
314 | | #if OPENTHREAD_CONFIG_P2P_ENABLE |
315 | | #if OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE |
316 | | static void HandleP2pLinkDone(void *aContext); |
317 | | void HandleP2pLinkDone(void); |
318 | | #endif |
319 | | |
320 | | static void HandleP2pUnlinkDone(void *aContext); |
321 | | void HandleP2pUnlinkDone(void); |
322 | | #endif |
323 | | |
324 | | #if OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE |
325 | | static void HandleWakeupResult(otError aError, void *aContext); |
326 | | void HandleWakeupResult(otError aError); |
327 | | #endif |
328 | | |
329 | | #endif // OPENTHREAD_FTD || OPENTHREAD_MTD |
330 | | |
331 | | #if OPENTHREAD_CONFIG_DIAG_ENABLE |
332 | | static void HandleDiagOutput(const char *aFormat, va_list aArguments, void *aContext); |
333 | | void HandleDiagOutput(const char *aFormat, va_list aArguments); |
334 | | #endif |
335 | | |
336 | | void SetCommandTimeout(uint32_t aTimeoutMilli); |
337 | | |
338 | | static void HandleTimer(Timer &aTimer); |
339 | | void HandleTimer(void); |
340 | | |
341 | | struct UserCommandsEntry |
342 | | { |
343 | | const otCliCommand *mCommands; |
344 | | uint8_t mLength; |
345 | | void *mContext; |
346 | | }; |
347 | | |
348 | | UserCommandsEntry mUserCommands[kMaxUserCommandEntries]; |
349 | | bool mCommandIsPending; |
350 | | bool mInternalDebugCommand; |
351 | | |
352 | | TimerMilliContext mTimer; |
353 | | |
354 | | #if OPENTHREAD_FTD || OPENTHREAD_MTD |
355 | | #if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE |
356 | | bool mSntpQueryingInProgress; |
357 | | #endif |
358 | | |
359 | | Dataset mDataset; |
360 | | NetworkData mNetworkData; |
361 | | UdpExample mUdp; |
362 | | |
363 | | #if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE |
364 | | MacFilter mMacFilter; |
365 | | #endif |
366 | | |
367 | | #if OPENTHREAD_CLI_DNS_ENABLE |
368 | | Dns mDns; |
369 | | #endif |
370 | | |
371 | | #if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE && OPENTHREAD_CONFIG_MULTICAST_DNS_PUBLIC_API_ENABLE |
372 | | Mdns mMdns; |
373 | | #endif |
374 | | |
375 | | #if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) |
376 | | Bbr mBbr; |
377 | | #endif |
378 | | |
379 | | #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE |
380 | | Br mBr; |
381 | | #endif |
382 | | |
383 | | #if OPENTHREAD_CONFIG_TCP_ENABLE && OPENTHREAD_CONFIG_CLI_TCP_ENABLE |
384 | | TcpExample mTcp; |
385 | | #endif |
386 | | |
387 | | #if OPENTHREAD_CONFIG_COAP_API_ENABLE |
388 | | Coap mCoap; |
389 | | #endif |
390 | | |
391 | | #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE |
392 | | CoapSecure mCoapSecure; |
393 | | #endif |
394 | | |
395 | | #if OPENTHREAD_CONFIG_COMMISSIONER_ENABLE && OPENTHREAD_FTD |
396 | | Commissioner mCommissioner; |
397 | | #endif |
398 | | |
399 | | #if OPENTHREAD_CONFIG_JOINER_ENABLE |
400 | | Joiner mJoiner; |
401 | | #endif |
402 | | |
403 | | #if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE |
404 | | SrpClient mSrpClient; |
405 | | #endif |
406 | | |
407 | | #if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE |
408 | | SrpServer mSrpServer; |
409 | | #endif |
410 | | |
411 | | #if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE |
412 | | History mHistory; |
413 | | #endif |
414 | | #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE |
415 | | LinkMetrics mLinkMetrics; |
416 | | #endif |
417 | | #if OPENTHREAD_CONFIG_BLE_TCAT_ENABLE && OPENTHREAD_CONFIG_CLI_BLE_SECURE_ENABLE |
418 | | Tcat mTcat; |
419 | | #endif |
420 | | #if OPENTHREAD_CONFIG_PING_SENDER_ENABLE |
421 | | PingSender mPing; |
422 | | #endif |
423 | | #if OPENTHREAD_CONFIG_MESH_DIAG_ENABLE && OPENTHREAD_FTD |
424 | | MeshDiag mMeshDiag; |
425 | | #endif |
426 | | #endif // OPENTHREAD_FTD || OPENTHREAD_MTD |
427 | | |
428 | | #if OPENTHREAD_CONFIG_TMF_ANYCAST_LOCATOR_ENABLE |
429 | | bool mLocateInProgress : 1; |
430 | | #endif |
431 | | }; |
432 | | |
433 | | } // namespace Cli |
434 | | } // namespace ot |
435 | | |
436 | | #endif // CLI_HPP_ |