#ifndef CLI_HPP_
#define CLI_HPP_
#include "openthread-core-config.h"
#include "cli_config.h"
#include <stdarg.h>
#include <openthread/cli.h>
#include <openthread/ip6.h>
#include <openthread/udp.h>
#include "cli/cli_commissioner.hpp"
#include "cli/cli_dataset.hpp"
#include "cli/cli_joiner.hpp"
#include "cli/cli_udp.hpp"
#if OPENTHREAD_CONFIG_COAP_API_ENABLE
#include "cli/cli_coap.hpp"
#endif
#if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
#include "cli/cli_coap_secure.hpp"
#endif
#include "common/code_utils.hpp"
#include "common/instance.hpp"
#include <openthread/dns.h>
#include <openthread/sntp.h>
#include "common/timer.hpp"
#include "net/icmp6.hpp"
namespace ot {
namespace Cli {
class Interpreter;
class Server;
struct Command
{
const char *mName; void (Interpreter::*mCommand)(uint8_t aArgsLength, char *aArgs[]); };
class Interpreter
{
friend class Coap;
friend class CoapSecure;
friend class Commissioner;
friend class Dataset;
friend class Joiner;
friend class UdpExample;
public:
explicit Interpreter(Instance *aInstance);
void ProcessLine(char *aBuf, uint16_t aBufLength, Server &aServer);
static otError ParseLong(char *aString, long &aLong);
static otError ParseUnsignedLong(char *aString, unsigned long &aUnsignedLong);
static int Hex2Bin(const char *aHex, uint8_t *aBin, uint16_t aBinLength, bool aAllowTruncate = false);
void AppendResult(otError aError) const;
void OutputBytes(const uint8_t *aBytes, uint8_t aLength) const;
void OutputIp6Address(const otIp6Address &aAddress) const;
void SetUserCommands(const otCliCommand *aCommands, uint8_t aLength);
private:
enum
{
kMaxArgs = 32,
kMaxAutoAddresses = 8,
kDefaultPingInterval = 1000, kDefaultPingLength = 8, kDefaultPingCount = 1,
};
otError ParsePingInterval(const char *aString, uint32_t &aInterval);
void ProcessHelp(uint8_t aArgsLength, char *aArgs[]);
void ProcessBufferInfo(uint8_t aArgsLength, char *aArgs[]);
void ProcessChannel(uint8_t aArgsLength, char *aArgs[]);
#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
void ProcessBackboneRouter(uint8_t aArgsLength, char *aArgs[]);
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
otError ProcessBackboneRouterLocal(uint8_t aArgsLength, char *aArgs[]);
#endif
void ProcessDomainName(uint8_t aArgsLength, char *aArgs[]);
#endif
#if OPENTHREAD_FTD
void ProcessChild(uint8_t aArgsLength, char *aArgs[]);
void ProcessChildIp(uint8_t aArgsLength, char *aArgs[]);
void ProcessChildMax(uint8_t aArgsLength, char *aArgs[]);
#endif
void ProcessChildTimeout(uint8_t aArgsLength, char *aArgs[]);
#if OPENTHREAD_CONFIG_COAP_API_ENABLE
void ProcessCoap(uint8_t aArgsLength, char *aArgs[]);
#endif #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
void ProcessCoapSecure(uint8_t aArgsLength, char *aArgs[]);
#endif #if OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE
void ProcessCoexMetrics(uint8_t aArgsLength, char *aArgs[]);
#endif
#if OPENTHREAD_CONFIG_COMMISSIONER_ENABLE && OPENTHREAD_FTD
void ProcessCommissioner(uint8_t aArgsLength, char *aArgs[]);
#endif
#if OPENTHREAD_FTD
void ProcessContextIdReuseDelay(uint8_t aArgsLength, char *aArgs[]);
#endif
void ProcessCounters(uint8_t aArgsLength, char *aArgs[]);
#if OPENTHREAD_FTD
void ProcessDelayTimerMin(uint8_t aArgsLength, char *aArgs[]);
#endif
#if OPENTHREAD_CONFIG_DIAG_ENABLE
void ProcessDiag(uint8_t aArgsLength, char *aArgs[]);
#endif void ProcessDiscover(uint8_t aArgsLength, char *aArgs[]);
#if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
void ProcessDns(uint8_t aArgsLength, char *aArgs[]);
#endif
#if OPENTHREAD_FTD
void ProcessEidCache(uint8_t aArgsLength, char *aArgs[]);
#endif
void ProcessEui64(uint8_t aArgsLength, char *aArgs[]);
#if OPENTHREAD_POSIX
void ProcessExit(uint8_t aArgsLength, char *aArgs[]);
#endif
void ProcessLog(uint8_t aArgsLength, char *aArgs[]);
void ProcessExtAddress(uint8_t aArgsLength, char *aArgs[]);
void ProcessExtPanId(uint8_t aArgsLength, char *aArgs[]);
void ProcessFactoryReset(uint8_t aArgsLength, char *aArgs[]);
void ProcessIfconfig(uint8_t aArgsLength, char *aArgs[]);
void ProcessIpAddr(uint8_t aArgsLength, char *aArgs[]);
otError ProcessIpAddrAdd(uint8_t aArgsLength, char *aArgs[]);
otError ProcessIpAddrDel(uint8_t aArgsLength, char *aArgs[]);
void ProcessIpMulticastAddr(uint8_t aArgsLength, char *aArgs[]);
otError ProcessIpMulticastAddrAdd(uint8_t aArgsLength, char *aArgs[]);
otError ProcessIpMulticastAddrDel(uint8_t aArgsLength, char *aArgs[]);
otError ProcessMulticastPromiscuous(uint8_t aArgsLength, char *aArgs[]);
#if OPENTHREAD_CONFIG_JOINER_ENABLE
void ProcessJoiner(uint8_t aArgsLength, char *aArgs[]);
#endif
#if OPENTHREAD_FTD
void ProcessJoinerPort(uint8_t aArgsLength, char *aArgs[]);
#endif
void ProcessKeySequence(uint8_t aArgsLength, char *aArgs[]);
void ProcessLeaderData(uint8_t aArgsLength, char *aArgs[]);
#if OPENTHREAD_FTD
void ProcessLeaderPartitionId(uint8_t aArgsLength, char *aArgs[]);
void ProcessLeaderWeight(uint8_t aArgsLength, char *aArgs[]);
#endif
void ProcessMasterKey(uint8_t aArgsLength, char *aArgs[]);
void ProcessMode(uint8_t aArgsLength, char *aArgs[]);
#if OPENTHREAD_FTD
void ProcessNeighbor(uint8_t aArgsLength, char *aArgs[]);
#endif
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
void ProcessNetworkDataRegister(uint8_t aArgsLength, char *aArgs[]);
#endif
void ProcessNetworkDataShow(uint8_t aArgsLength, char *aArgs[]);
#if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE
void ProcessNetif(uint8_t aArgsLength, char *aArgs[]);
#endif
#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
void ProcessService(uint8_t aArgsLength, char *aArgs[]);
#endif
#if OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE
void ProcessNetworkDiagnostic(uint8_t aArgsLength, char *aArgs[]);
#endif #if OPENTHREAD_FTD
void ProcessNetworkIdTimeout(uint8_t aArgsLength, char *aArgs[]);
#endif
void ProcessNetworkName(uint8_t aArgsLength, char *aArgs[]);
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
void ProcessNetworkTime(uint8_t aArgsLength, char *aArgs[]);
#endif
void ProcessPanId(uint8_t aArgsLength, char *aArgs[]);
void ProcessParent(uint8_t aArgsLength, char *aArgs[]);
#if OPENTHREAD_FTD
void ProcessParentPriority(uint8_t aArgsLength, char *aArgs[]);
#endif
void ProcessPing(uint8_t aArgsLength, char *aArgs[]);
void ProcessPollPeriod(uint8_t aArgsLength, char *aArgs[]);
void SignalPingRequest(const Ip6::Address &aPeerAddress,
uint16_t aPingLength,
uint32_t aTimestamp,
uint8_t aHopLimit);
void SignalPingReply(const Ip6::Address &aPeerAddress,
uint16_t aPingLength,
uint32_t aTimestamp,
uint8_t aHopLimit);
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
void ProcessPrefix(uint8_t aArgsLength, char *aArgs[]);
otError ProcessPrefixAdd(uint8_t aArgsLength, char *aArgs[]);
otError ProcessPrefixRemove(uint8_t aArgsLength, char *aArgs[]);
otError ProcessPrefixList(void);
void OutputPrefix(otBorderRouterConfig &aConfig);
#endif
void ProcessPromiscuous(uint8_t aArgsLength, char *aArgs[]);
#if OPENTHREAD_FTD
void ProcessPreferRouterId(uint8_t aArgsLength, char *aArgs[]);
void ProcessPskc(uint8_t aArgsLength, char *aArgs[]);
void ProcessReleaseRouterId(uint8_t aArgsLength, char *aArgs[]);
#endif
void ProcessReset(uint8_t aArgsLength, char *aArgs[]);
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
void ProcessRoute(uint8_t aArgsLength, char *aArgs[]);
otError ProcessRouteAdd(uint8_t aArgsLength, char *aArgs[]);
otError ProcessRouteRemove(uint8_t aArgsLength, char *aArgs[]);
otError ProcessRouteList(void);
#endif
#if OPENTHREAD_FTD
void ProcessRouter(uint8_t aArgsLength, char *aArgs[]);
void ProcessRouterDowngradeThreshold(uint8_t aArgsLength, char *aArgs[]);
void ProcessRouterEligible(uint8_t aArgsLength, char *aArgs[]);
void ProcessRouterSelectionJitter(uint8_t aArgsLength, char *aArgs[]);
void ProcessRouterUpgradeThreshold(uint8_t aArgsLength, char *aArgs[]);
#endif
void ProcessRloc16(uint8_t aArgsLength, char *aArgs[]);
void ProcessScan(uint8_t aArgsLength, char *aArgs[]);
void ProcessSingleton(uint8_t aArgsLength, char *aArgs[]);
#if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
void ProcessSntp(uint8_t aArgsLength, char *aArgs[]);
#endif
void ProcessState(uint8_t aArgsLength, char *aArgs[]);
void ProcessThread(uint8_t aArgsLength, char *aArgs[]);
void ProcessDataset(uint8_t aArgsLength, char *aArgs[]);
void ProcessTxPower(uint8_t aArgsLength, char *aArgs[]);
void ProcessUdp(uint8_t aArgsLength, char *aArgs[]);
void ProcessVersion(uint8_t aArgsLength, char *aArgs[]);
#if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
void ProcessMacFilter(uint8_t aArgsLength, char *aArgs[]);
void PrintMacFilter(void);
otError ProcessMacFilterAddress(uint8_t aArgsLength, char *aArgs[]);
otError ProcessMacFilterRss(uint8_t aArgsLength, char *aArgs[]);
#endif void ProcessMac(uint8_t aArgsLength, char *aArgs[]);
otError ProcessMacRetries(uint8_t aArgsLength, char *aArgs[]);
static void HandleIcmpReceive(void * aContext,
otMessage * aMessage,
const otMessageInfo *aMessageInfo,
const otIcmp6Header *aIcmpHeader);
static void HandlePingTimer(Timer &aTimer);
static void HandleActiveScanResult(otActiveScanResult *aResult, void *aContext);
static void HandleEnergyScanResult(otEnergyScanResult *aResult, void *aContext);
static void HandleLinkPcapReceive(const otRadioFrame *aFrame, bool aIsTx, void *aContext);
#if OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE
void HandleDiagnosticGetResponse(const otMessage &aMessage, const Ip6::MessageInfo &aMessageInfo);
static void HandleDiagnosticGetResponse(otMessage *aMessage, const otMessageInfo *aMessageInfo, void *aContext);
void OutputSpaces(uint16_t aCount);
void OutputMode(const otLinkModeConfig &aMode, uint16_t aColumn);
void OutputConnectivity(const otNetworkDiagConnectivity &aConnectivity, uint16_t aColumn);
void OutputRoute(const otNetworkDiagRoute &aRoute, uint16_t aColumn);
void OutputRouteData(const otNetworkDiagRouteData &aRouteData, uint16_t aColumn);
void OutputLeaderData(const otLeaderData &aLeaderData, uint16_t aColumn);
void OutputNetworkDiagMacCounters(const otNetworkDiagMacCounters &aMacCounters, uint16_t aColumn);
void OutputChildTableEntry(const otNetworkDiagChildEntry &aChildEntry, uint16_t aColumn);
#endif
#if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
static void HandleDnsResponse(void * aContext,
const char * aHostname,
const otIp6Address *aAddress,
uint32_t aTtl,
otError aResult);
#endif
#if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
static void HandleSntpResponse(void *aContext, uint64_t aTime, otError aResult);
#endif
void HandleIcmpReceive(otMessage *aMessage, const otMessageInfo *aMessageInfo, const otIcmp6Header *aIcmpHeader);
void SendPing(void);
void HandleActiveScanResult(otActiveScanResult *aResult);
void HandleEnergyScanResult(otEnergyScanResult *aResult);
void HandleLinkPcapReceive(const otRadioFrame *aFrame, bool aIsTx);
#if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
void HandleDnsResponse(const char *aHostname, const Ip6::Address *aAddress, uint32_t aTtl, otError aResult);
#endif
#if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
void HandleSntpResponse(uint64_t aTime, otError aResult);
#endif
static Interpreter &GetOwner(OwnerLocator &aOwnerLocator);
static const struct Command sCommands[];
const otCliCommand * mUserCommands;
uint8_t mUserCommandsLength;
Server * mServer;
uint16_t mPingLength;
uint16_t mPingCount;
uint32_t mPingInterval;
uint8_t mPingHopLimit;
bool mPingAllowZeroHopLimit;
uint16_t mPingIdentifier;
otIp6Address mPingDestAddress;
TimerMilli mPingTimer;
otIcmp6Handler mIcmpHandler;
#if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
bool mResolvingInProgress;
char mResolvingHostname[OT_DNS_MAX_HOSTNAME_LENGTH];
#endif
#if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
bool mSntpQueryingInProgress;
#endif
UdpExample mUdp;
Dataset mDataset;
#if OPENTHREAD_CONFIG_COAP_API_ENABLE
Coap mCoap;
#endif
#if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
CoapSecure mCoapSecure;
#endif
#if OPENTHREAD_CONFIG_COMMISSIONER_ENABLE && OPENTHREAD_FTD
Commissioner mCommissioner;
#endif
#if OPENTHREAD_CONFIG_JOINER_ENABLE
Joiner mJoiner;
#endif
Instance *mInstance;
};
} }
#endif