mirror of
https://github.com/espressif/openthread.git
synced 2026-08-29 13:29:54 +00:00
[cli] move commissioner to separate source files (#3862)
This commit is contained in:
committed by
Jonathan Hui
parent
9cd11a2761
commit
68beda5b07
@@ -310,6 +310,7 @@ LOCAL_LDLIBS := \
|
||||
LOCAL_SRC_FILES := \
|
||||
src/cli/cli.cpp \
|
||||
src/cli/cli_coap.cpp \
|
||||
src/cli/cli_commissioner.cpp \
|
||||
src/cli/cli_console.cpp \
|
||||
src/cli/cli_dataset.cpp \
|
||||
src/cli/cli_joiner.cpp \
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\cli\cli.cpp" />
|
||||
<ClCompile Include="..\..\src\cli\cli_commissioner.cpp" />
|
||||
<ClCompile Include="..\..\src\cli\cli_dataset.cpp" />
|
||||
<ClCompile Include="..\..\src\cli\cli_instance.cpp" />
|
||||
<ClCompile Include="..\..\src\cli\cli_joiner.cpp" />
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
<ClCompile Include="..\..\src\cli\cli.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\cli\cli_commissioner.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\cli\cli_dataset.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\cli\cli.cpp" />
|
||||
<ClCompile Include="..\..\src\cli\cli_commissioner.cpp" />
|
||||
<ClCompile Include="..\..\src\cli\cli_dataset.cpp" />
|
||||
<ClCompile Include="..\..\src\cli\cli_joiner.cpp" />
|
||||
<ClCompile Include="..\..\src\cli\cli_server.cpp" />
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
<ClCompile Include="..\..\src\cli\cli.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\cli\cli_commissioner.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\cli\cli_dataset.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
||||
@@ -145,6 +145,7 @@ SOURCES_COMMON = \
|
||||
cli.cpp \
|
||||
cli_coap.cpp \
|
||||
cli_coap_secure.cpp \
|
||||
cli_commissioner.cpp \
|
||||
cli_console.cpp \
|
||||
cli_dataset.cpp \
|
||||
cli_joiner.cpp \
|
||||
@@ -165,6 +166,7 @@ noinst_HEADERS = \
|
||||
cli.hpp \
|
||||
cli_coap.hpp \
|
||||
cli_coap_secure.hpp \
|
||||
cli_commissioner.hpp \
|
||||
cli_console.hpp \
|
||||
cli_dataset.hpp \
|
||||
cli_joiner.hpp \
|
||||
|
||||
+6
-277
@@ -43,7 +43,6 @@
|
||||
#include "utils/parse_cmdline.hpp"
|
||||
#include "utils/wrap_string.h"
|
||||
|
||||
#include <openthread/commissioner.h>
|
||||
#include <openthread/icmp6.h>
|
||||
#include <openthread/link.h>
|
||||
#include <openthread/ncp.h>
|
||||
@@ -304,6 +303,9 @@ Interpreter::Interpreter(Instance *aInstance)
|
||||
#if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE
|
||||
, mCoapSecure(*this)
|
||||
#endif
|
||||
#if OPENTHREAD_ENABLE_COMMISSIONER && OPENTHREAD_FTD
|
||||
, mCommissioner(*this)
|
||||
#endif
|
||||
#if OPENTHREAD_ENABLE_JOINER
|
||||
, mJoiner(*this)
|
||||
#endif
|
||||
@@ -3178,285 +3180,12 @@ void Interpreter::ProcessVersion(int argc, char *argv[])
|
||||
|
||||
void Interpreter::ProcessCommissioner(int argc, char *argv[])
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
if (strcmp(argv[0], "start") == 0)
|
||||
{
|
||||
SuccessOrExit(error = otCommissionerStart(mInstance));
|
||||
}
|
||||
else if (strcmp(argv[0], "stop") == 0)
|
||||
{
|
||||
SuccessOrExit(error = otCommissionerStop(mInstance));
|
||||
}
|
||||
else if (strcmp(argv[0], "joiner") == 0)
|
||||
{
|
||||
otExtAddress addr;
|
||||
const otExtAddress *addrPtr;
|
||||
|
||||
VerifyOrExit(argc > 2, error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
if (strcmp(argv[2], "*") == 0)
|
||||
{
|
||||
addrPtr = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
VerifyOrExit(Hex2Bin(argv[2], addr.m8, sizeof(addr)) == sizeof(addr), error = OT_ERROR_PARSE);
|
||||
addrPtr = &addr;
|
||||
}
|
||||
|
||||
if (strcmp(argv[1], "add") == 0)
|
||||
{
|
||||
VerifyOrExit(argc > 3, error = OT_ERROR_INVALID_ARGS);
|
||||
// Timeout parameter is optional - if not specified, use default value.
|
||||
unsigned long timeout = kDefaultJoinerTimeout;
|
||||
|
||||
if (argc > 4)
|
||||
{
|
||||
SuccessOrExit(error = ParseUnsignedLong(argv[4], timeout));
|
||||
}
|
||||
|
||||
SuccessOrExit(error = otCommissionerAddJoiner(mInstance, addrPtr, argv[3], static_cast<uint32_t>(timeout)));
|
||||
}
|
||||
else if (strcmp(argv[1], "remove") == 0)
|
||||
{
|
||||
SuccessOrExit(error = otCommissionerRemoveJoiner(mInstance, addrPtr));
|
||||
}
|
||||
}
|
||||
else if (strcmp(argv[0], "provisioningurl") == 0)
|
||||
{
|
||||
SuccessOrExit(error = otCommissionerSetProvisioningUrl(mInstance, (argc > 1) ? argv[1] : NULL));
|
||||
}
|
||||
else if (strcmp(argv[0], "announce") == 0)
|
||||
{
|
||||
long mask;
|
||||
long count;
|
||||
long period;
|
||||
otIp6Address address;
|
||||
|
||||
VerifyOrExit(argc > 4, error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
// mask
|
||||
SuccessOrExit(error = ParseLong(argv[1], mask));
|
||||
|
||||
// count
|
||||
SuccessOrExit(error = ParseLong(argv[2], count));
|
||||
|
||||
// period
|
||||
SuccessOrExit(error = ParseLong(argv[3], period));
|
||||
|
||||
// destination
|
||||
SuccessOrExit(error = otIp6AddressFromString(argv[4], &address));
|
||||
|
||||
SuccessOrExit(error = otCommissionerAnnounceBegin(mInstance, static_cast<uint32_t>(mask),
|
||||
static_cast<uint8_t>(count), static_cast<uint16_t>(period),
|
||||
&address));
|
||||
}
|
||||
else if (strcmp(argv[0], "energy") == 0)
|
||||
{
|
||||
long mask;
|
||||
long count;
|
||||
long period;
|
||||
long scanDuration;
|
||||
otIp6Address address;
|
||||
|
||||
VerifyOrExit(argc > 5, error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
// mask
|
||||
SuccessOrExit(error = ParseLong(argv[1], mask));
|
||||
|
||||
// count
|
||||
SuccessOrExit(error = ParseLong(argv[2], count));
|
||||
|
||||
// period
|
||||
SuccessOrExit(error = ParseLong(argv[3], period));
|
||||
|
||||
// scan duration
|
||||
SuccessOrExit(error = ParseLong(argv[4], scanDuration));
|
||||
|
||||
// destination
|
||||
SuccessOrExit(error = otIp6AddressFromString(argv[5], &address));
|
||||
|
||||
SuccessOrExit(error =
|
||||
otCommissionerEnergyScan(mInstance, static_cast<uint32_t>(mask), static_cast<uint8_t>(count),
|
||||
static_cast<uint16_t>(period), static_cast<uint16_t>(scanDuration),
|
||||
&address, Interpreter::s_HandleEnergyReport, this));
|
||||
}
|
||||
else if (strcmp(argv[0], "panid") == 0)
|
||||
{
|
||||
long panid;
|
||||
long mask;
|
||||
otIp6Address address;
|
||||
|
||||
VerifyOrExit(argc > 3, error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
// panid
|
||||
SuccessOrExit(error = ParseLong(argv[1], panid));
|
||||
|
||||
// mask
|
||||
SuccessOrExit(error = ParseLong(argv[2], mask));
|
||||
|
||||
// destination
|
||||
SuccessOrExit(error = otIp6AddressFromString(argv[3], &address));
|
||||
|
||||
SuccessOrExit(error =
|
||||
otCommissionerPanIdQuery(mInstance, static_cast<uint16_t>(panid), static_cast<uint32_t>(mask),
|
||||
&address, Interpreter::s_HandlePanIdConflict, this));
|
||||
}
|
||||
else if (strcmp(argv[0], "mgmtget") == 0)
|
||||
{
|
||||
uint8_t tlvs[32];
|
||||
long value;
|
||||
int length = 0;
|
||||
|
||||
for (uint8_t index = 1; index < argc; index++)
|
||||
{
|
||||
VerifyOrExit(static_cast<size_t>(length) < sizeof(tlvs), error = OT_ERROR_NO_BUFS);
|
||||
|
||||
if (strcmp(argv[index], "locator") == 0)
|
||||
{
|
||||
tlvs[length++] = OT_MESHCOP_TLV_BORDER_AGENT_RLOC;
|
||||
}
|
||||
else if (strcmp(argv[index], "sessionid") == 0)
|
||||
{
|
||||
tlvs[length++] = OT_MESHCOP_TLV_COMM_SESSION_ID;
|
||||
}
|
||||
else if (strcmp(argv[index], "steeringdata") == 0)
|
||||
{
|
||||
tlvs[length++] = OT_MESHCOP_TLV_STEERING_DATA;
|
||||
}
|
||||
else if (strcmp(argv[index], "joinerudpport") == 0)
|
||||
{
|
||||
tlvs[length++] = OT_MESHCOP_TLV_JOINER_UDP_PORT;
|
||||
}
|
||||
else if (strcmp(argv[index], "binary") == 0)
|
||||
{
|
||||
VerifyOrExit(++index < argc, error = OT_ERROR_INVALID_ARGS);
|
||||
value = static_cast<long>(strlen(argv[index]) + 1) / 2;
|
||||
VerifyOrExit(static_cast<size_t>(value) <= (sizeof(tlvs) - static_cast<size_t>(length)),
|
||||
error = OT_ERROR_NO_BUFS);
|
||||
VerifyOrExit(Interpreter::Hex2Bin(argv[index], tlvs + length, static_cast<uint16_t>(value)) >= 0,
|
||||
error = OT_ERROR_PARSE);
|
||||
length += value;
|
||||
}
|
||||
else
|
||||
{
|
||||
ExitNow(error = OT_ERROR_INVALID_ARGS);
|
||||
}
|
||||
}
|
||||
|
||||
SuccessOrExit(error = otCommissionerSendMgmtGet(mInstance, tlvs, static_cast<uint8_t>(length)));
|
||||
}
|
||||
else if (strcmp(argv[0], "mgmtset") == 0)
|
||||
{
|
||||
otCommissioningDataset dataset;
|
||||
uint8_t tlvs[32];
|
||||
long value;
|
||||
int length = 0;
|
||||
|
||||
VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
memset(&dataset, 0, sizeof(dataset));
|
||||
|
||||
for (uint8_t index = 1; index < argc; index++)
|
||||
{
|
||||
VerifyOrExit(static_cast<size_t>(length) < sizeof(tlvs), error = OT_ERROR_NO_BUFS);
|
||||
|
||||
if (strcmp(argv[index], "locator") == 0)
|
||||
{
|
||||
VerifyOrExit(++index < argc, error = OT_ERROR_INVALID_ARGS);
|
||||
dataset.mIsLocatorSet = true;
|
||||
SuccessOrExit(error = Interpreter::ParseLong(argv[index], value));
|
||||
dataset.mLocator = static_cast<uint16_t>(value);
|
||||
}
|
||||
else if (strcmp(argv[index], "sessionid") == 0)
|
||||
{
|
||||
VerifyOrExit(++index < argc, error = OT_ERROR_INVALID_ARGS);
|
||||
dataset.mIsSessionIdSet = true;
|
||||
SuccessOrExit(error = Interpreter::ParseLong(argv[index], value));
|
||||
dataset.mSessionId = static_cast<uint16_t>(value);
|
||||
}
|
||||
else if (strcmp(argv[index], "steeringdata") == 0)
|
||||
{
|
||||
VerifyOrExit(++index < argc, error = OT_ERROR_INVALID_ARGS);
|
||||
dataset.mIsSteeringDataSet = true;
|
||||
length = static_cast<int>((strlen(argv[index]) + 1) / 2);
|
||||
VerifyOrExit(static_cast<size_t>(length) <= OT_STEERING_DATA_MAX_LENGTH, error = OT_ERROR_NO_BUFS);
|
||||
VerifyOrExit(
|
||||
Interpreter::Hex2Bin(argv[index], dataset.mSteeringData.m8, static_cast<uint16_t>(length)) >= 0,
|
||||
error = OT_ERROR_PARSE);
|
||||
dataset.mSteeringData.mLength = static_cast<uint8_t>(length);
|
||||
length = 0;
|
||||
}
|
||||
else if (strcmp(argv[index], "joinerudpport") == 0)
|
||||
{
|
||||
VerifyOrExit(++index < argc, error = OT_ERROR_INVALID_ARGS);
|
||||
dataset.mIsJoinerUdpPortSet = true;
|
||||
SuccessOrExit(error = Interpreter::ParseLong(argv[index], value));
|
||||
dataset.mJoinerUdpPort = static_cast<uint16_t>(value);
|
||||
}
|
||||
else if (strcmp(argv[index], "binary") == 0)
|
||||
{
|
||||
VerifyOrExit(++index < argc, error = OT_ERROR_INVALID_ARGS);
|
||||
length = static_cast<int>((strlen(argv[index]) + 1) / 2);
|
||||
VerifyOrExit(static_cast<size_t>(length) <= sizeof(tlvs), error = OT_ERROR_NO_BUFS);
|
||||
VerifyOrExit(Interpreter::Hex2Bin(argv[index], tlvs, static_cast<uint16_t>(length)) >= 0,
|
||||
error = OT_ERROR_PARSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
ExitNow(error = OT_ERROR_INVALID_ARGS);
|
||||
}
|
||||
}
|
||||
|
||||
SuccessOrExit(error = otCommissionerSendMgmtSet(mInstance, &dataset, tlvs, static_cast<uint8_t>(length)));
|
||||
}
|
||||
else if (strcmp(argv[0], "sessionid") == 0)
|
||||
{
|
||||
mServer->OutputFormat("%d\r\n", otCommissionerGetSessionId(mInstance));
|
||||
}
|
||||
else
|
||||
{
|
||||
ExitNow(error = OT_ERROR_INVALID_ARGS);
|
||||
}
|
||||
|
||||
exit:
|
||||
otError error;
|
||||
error = mCommissioner.Process(argc, argv);
|
||||
AppendResult(error);
|
||||
}
|
||||
|
||||
void OTCALL Interpreter::s_HandleEnergyReport(uint32_t aChannelMask,
|
||||
const uint8_t *aEnergyList,
|
||||
uint8_t aEnergyListLength,
|
||||
void * aContext)
|
||||
{
|
||||
static_cast<Interpreter *>(aContext)->HandleEnergyReport(aChannelMask, aEnergyList, aEnergyListLength);
|
||||
}
|
||||
|
||||
void Interpreter::HandleEnergyReport(uint32_t aChannelMask, const uint8_t *aEnergyList, uint8_t aEnergyListLength)
|
||||
{
|
||||
mServer->OutputFormat("Energy: %08x ", aChannelMask);
|
||||
|
||||
for (uint8_t i = 0; i < aEnergyListLength; i++)
|
||||
{
|
||||
mServer->OutputFormat("%d ", static_cast<int8_t>(aEnergyList[i]));
|
||||
}
|
||||
|
||||
mServer->OutputFormat("\r\n");
|
||||
}
|
||||
|
||||
void OTCALL Interpreter::s_HandlePanIdConflict(uint16_t aPanId, uint32_t aChannelMask, void *aContext)
|
||||
{
|
||||
static_cast<Interpreter *>(aContext)->HandlePanIdConflict(aPanId, aChannelMask);
|
||||
}
|
||||
|
||||
void Interpreter::HandlePanIdConflict(uint16_t aPanId, uint32_t aChannelMask)
|
||||
{
|
||||
mServer->OutputFormat("Conflict: %04x, %08x\r\n", aPanId, aChannelMask);
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_ENABLE_COMMISSIONER && OPENTHREAD_FTD
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_ENABLE_JOINER
|
||||
|
||||
|
||||
+9
-11
@@ -42,6 +42,7 @@
|
||||
#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"
|
||||
@@ -102,6 +103,7 @@ class Interpreter
|
||||
{
|
||||
friend class Coap;
|
||||
friend class CoapSecure;
|
||||
friend class Commissioner;
|
||||
friend class Dataset;
|
||||
friend class Joiner;
|
||||
friend class UdpExample;
|
||||
@@ -192,9 +194,8 @@ public:
|
||||
private:
|
||||
enum
|
||||
{
|
||||
kMaxArgs = 32,
|
||||
kMaxAutoAddresses = 8,
|
||||
kDefaultJoinerTimeout = 120, ///< Default timeout for Joiners, in seconds.
|
||||
kMaxArgs = 32,
|
||||
kMaxAutoAddresses = 8,
|
||||
};
|
||||
|
||||
otError ParsePingInterval(const char *aString, uint32_t &aInterval);
|
||||
@@ -216,7 +217,7 @@ private:
|
||||
#endif // OPENTHREAD_ENABLE_APPLICATION_COAP
|
||||
#if OPENTHREAD_ENABLE_COMMISSIONER && OPENTHREAD_FTD
|
||||
void ProcessCommissioner(int argc, char *argv[]);
|
||||
#endif // OPENTHREAD_ENABLE_COMMISSIONER && OPENTHREAD_FTD
|
||||
#endif
|
||||
#if OPENTHREAD_FTD
|
||||
void ProcessContextIdReuseDelay(int argc, char *argv[]);
|
||||
#endif
|
||||
@@ -360,11 +361,6 @@ private:
|
||||
#ifndef OTDLL
|
||||
static void s_HandleLinkPcapReceive(const otRadioFrame *aFrame, bool aIsTx, void *aContext);
|
||||
#endif
|
||||
static void OTCALL s_HandleEnergyReport(uint32_t aChannelMask,
|
||||
const uint8_t *aEnergyList,
|
||||
uint8_t aEnergyListLength,
|
||||
void * aContext);
|
||||
static void OTCALL s_HandlePanIdConflict(uint16_t aPanId, uint32_t aChannelMask, void *aContext);
|
||||
#ifndef OTDLL
|
||||
static void OTCALL s_HandleDiagnosticGetResponse(otMessage * aMessage,
|
||||
const otMessageInfo *aMessageInfo,
|
||||
@@ -392,8 +388,6 @@ private:
|
||||
#ifndef OTDLL
|
||||
void HandleLinkPcapReceive(const otRadioFrame *aFrame, bool aIsTx);
|
||||
#endif
|
||||
void HandleEnergyReport(uint32_t aChannelMask, const uint8_t *aEnergyList, uint8_t aEnergyListLength);
|
||||
void HandlePanIdConflict(uint16_t aPanId, uint32_t aChannelMask);
|
||||
#ifndef OTDLL
|
||||
void HandleDiagnosticGetResponse(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
#endif
|
||||
@@ -459,6 +453,10 @@ private:
|
||||
CoapSecure mCoapSecure;
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_ENABLE_COMMISSIONER && OPENTHREAD_FTD
|
||||
Commissioner mCommissioner;
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_ENABLE_JOINER
|
||||
Joiner mJoiner;
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,387 @@
|
||||
/*
|
||||
* Copyright (c) 2019, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file implements a simple CLI for the Commissioner role.
|
||||
*/
|
||||
|
||||
#include "cli_commissioner.hpp"
|
||||
|
||||
#include "cli/cli.hpp"
|
||||
#include "cli/cli_server.hpp"
|
||||
|
||||
#if OPENTHREAD_ENABLE_COMMISSIONER && OPENTHREAD_FTD
|
||||
|
||||
namespace ot {
|
||||
namespace Cli {
|
||||
|
||||
const struct Commissioner::Command Commissioner::sCommands[] = {
|
||||
{"help", &Commissioner::ProcessHelp}, {"announce", &Commissioner::ProcessAnnounce},
|
||||
{"energy", &Commissioner::ProcessEnergy}, {"joiner", &Commissioner::ProcessJoiner},
|
||||
{"mgmtget", &Commissioner::ProcessMgmtGet}, {"mgmtset", &Commissioner::ProcessMgmtSet},
|
||||
{"panid", &Commissioner::ProcessPanId}, {"provisioningurl", &Commissioner::ProcessProvisioningUrl},
|
||||
{"sessionid", &Commissioner::ProcessSessionId}, {"start", &Commissioner::ProcessStart},
|
||||
{"stop", &Commissioner::ProcessStop},
|
||||
};
|
||||
|
||||
otError Commissioner::ProcessHelp(int argc, char *argv[])
|
||||
{
|
||||
OT_UNUSED_VARIABLE(argc);
|
||||
OT_UNUSED_VARIABLE(argv);
|
||||
|
||||
for (size_t i = 0; i < OT_ARRAY_LENGTH(sCommands); i++)
|
||||
{
|
||||
mInterpreter.mServer->OutputFormat("%s\r\n", sCommands[i].mName);
|
||||
}
|
||||
|
||||
return OT_ERROR_NONE;
|
||||
}
|
||||
|
||||
otError Commissioner::ProcessAnnounce(int argc, char *argv[])
|
||||
{
|
||||
otError error;
|
||||
long mask;
|
||||
long count;
|
||||
long period;
|
||||
otIp6Address address;
|
||||
|
||||
VerifyOrExit(argc > 4, error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
SuccessOrExit(error = Interpreter::ParseLong(argv[1], mask));
|
||||
SuccessOrExit(error = Interpreter::ParseLong(argv[2], count));
|
||||
SuccessOrExit(error = Interpreter::ParseLong(argv[3], period));
|
||||
SuccessOrExit(error = otIp6AddressFromString(argv[4], &address));
|
||||
|
||||
SuccessOrExit(error = otCommissionerAnnounceBegin(mInterpreter.mInstance, static_cast<uint32_t>(mask),
|
||||
static_cast<uint8_t>(count), static_cast<uint16_t>(period),
|
||||
&address));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError Commissioner::ProcessEnergy(int argc, char *argv[])
|
||||
{
|
||||
otError error;
|
||||
long mask;
|
||||
long count;
|
||||
long period;
|
||||
long scanDuration;
|
||||
otIp6Address address;
|
||||
|
||||
VerifyOrExit(argc > 5, error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
SuccessOrExit(error = Interpreter::ParseLong(argv[1], mask));
|
||||
SuccessOrExit(error = Interpreter::ParseLong(argv[2], count));
|
||||
SuccessOrExit(error = Interpreter::ParseLong(argv[3], period));
|
||||
SuccessOrExit(error = Interpreter::ParseLong(argv[4], scanDuration));
|
||||
SuccessOrExit(error = otIp6AddressFromString(argv[5], &address));
|
||||
|
||||
SuccessOrExit(error = otCommissionerEnergyScan(mInterpreter.mInstance, static_cast<uint32_t>(mask),
|
||||
static_cast<uint8_t>(count), static_cast<uint16_t>(period),
|
||||
static_cast<uint16_t>(scanDuration), &address,
|
||||
&Commissioner::HandleEnergyReport, this));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError Commissioner::ProcessJoiner(int argc, char *argv[])
|
||||
{
|
||||
otError error;
|
||||
otExtAddress addr;
|
||||
const otExtAddress *addrPtr;
|
||||
|
||||
VerifyOrExit(argc > 2, error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
if (strcmp(argv[2], "*") == 0)
|
||||
{
|
||||
addrPtr = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
VerifyOrExit(Interpreter::Hex2Bin(argv[2], addr.m8, sizeof(addr)) == sizeof(addr), error = OT_ERROR_PARSE);
|
||||
addrPtr = &addr;
|
||||
}
|
||||
|
||||
if (strcmp(argv[1], "add") == 0)
|
||||
{
|
||||
VerifyOrExit(argc > 3, error = OT_ERROR_INVALID_ARGS);
|
||||
// Timeout parameter is optional - if not specified, use default value.
|
||||
unsigned long timeout = kDefaultJoinerTimeout;
|
||||
|
||||
if (argc > 4)
|
||||
{
|
||||
SuccessOrExit(error = Interpreter::ParseUnsignedLong(argv[4], timeout));
|
||||
}
|
||||
|
||||
SuccessOrExit(
|
||||
error = otCommissionerAddJoiner(mInterpreter.mInstance, addrPtr, argv[3], static_cast<uint32_t>(timeout)));
|
||||
}
|
||||
else if (strcmp(argv[1], "remove") == 0)
|
||||
{
|
||||
SuccessOrExit(error = otCommissionerRemoveJoiner(mInterpreter.mInstance, addrPtr));
|
||||
}
|
||||
else
|
||||
{
|
||||
ExitNow(error = OT_ERROR_INVALID_ARGS);
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError Commissioner::ProcessMgmtGet(int argc, char *argv[])
|
||||
{
|
||||
otError error;
|
||||
uint8_t tlvs[32];
|
||||
long value;
|
||||
int length = 0;
|
||||
|
||||
for (uint8_t index = 1; index < argc; index++)
|
||||
{
|
||||
VerifyOrExit(static_cast<size_t>(length) < sizeof(tlvs), error = OT_ERROR_NO_BUFS);
|
||||
|
||||
if (strcmp(argv[index], "locator") == 0)
|
||||
{
|
||||
tlvs[length++] = OT_MESHCOP_TLV_BORDER_AGENT_RLOC;
|
||||
}
|
||||
else if (strcmp(argv[index], "sessionid") == 0)
|
||||
{
|
||||
tlvs[length++] = OT_MESHCOP_TLV_COMM_SESSION_ID;
|
||||
}
|
||||
else if (strcmp(argv[index], "steeringdata") == 0)
|
||||
{
|
||||
tlvs[length++] = OT_MESHCOP_TLV_STEERING_DATA;
|
||||
}
|
||||
else if (strcmp(argv[index], "joinerudpport") == 0)
|
||||
{
|
||||
tlvs[length++] = OT_MESHCOP_TLV_JOINER_UDP_PORT;
|
||||
}
|
||||
else if (strcmp(argv[index], "binary") == 0)
|
||||
{
|
||||
VerifyOrExit(++index < argc, error = OT_ERROR_INVALID_ARGS);
|
||||
value = static_cast<long>(strlen(argv[index]) + 1) / 2;
|
||||
VerifyOrExit(static_cast<size_t>(value) <= (sizeof(tlvs) - static_cast<size_t>(length)),
|
||||
error = OT_ERROR_NO_BUFS);
|
||||
VerifyOrExit(Interpreter::Hex2Bin(argv[index], tlvs + length, static_cast<uint16_t>(value)) >= 0,
|
||||
error = OT_ERROR_PARSE);
|
||||
length += value;
|
||||
}
|
||||
else
|
||||
{
|
||||
ExitNow(error = OT_ERROR_INVALID_ARGS);
|
||||
}
|
||||
}
|
||||
|
||||
SuccessOrExit(error = otCommissionerSendMgmtGet(mInterpreter.mInstance, tlvs, static_cast<uint8_t>(length)));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError Commissioner::ProcessMgmtSet(int argc, char *argv[])
|
||||
{
|
||||
otError error;
|
||||
otCommissioningDataset dataset;
|
||||
uint8_t tlvs[32];
|
||||
long value;
|
||||
int length = 0;
|
||||
|
||||
VerifyOrExit(argc > 0, error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
memset(&dataset, 0, sizeof(dataset));
|
||||
|
||||
for (uint8_t index = 1; index < argc; index++)
|
||||
{
|
||||
VerifyOrExit(static_cast<size_t>(length) < sizeof(tlvs), error = OT_ERROR_NO_BUFS);
|
||||
|
||||
if (strcmp(argv[index], "locator") == 0)
|
||||
{
|
||||
VerifyOrExit(++index < argc, error = OT_ERROR_INVALID_ARGS);
|
||||
dataset.mIsLocatorSet = true;
|
||||
SuccessOrExit(error = Interpreter::Interpreter::ParseLong(argv[index], value));
|
||||
dataset.mLocator = static_cast<uint16_t>(value);
|
||||
}
|
||||
else if (strcmp(argv[index], "sessionid") == 0)
|
||||
{
|
||||
VerifyOrExit(++index < argc, error = OT_ERROR_INVALID_ARGS);
|
||||
dataset.mIsSessionIdSet = true;
|
||||
SuccessOrExit(error = Interpreter::Interpreter::ParseLong(argv[index], value));
|
||||
dataset.mSessionId = static_cast<uint16_t>(value);
|
||||
}
|
||||
else if (strcmp(argv[index], "steeringdata") == 0)
|
||||
{
|
||||
VerifyOrExit(++index < argc, error = OT_ERROR_INVALID_ARGS);
|
||||
dataset.mIsSteeringDataSet = true;
|
||||
length = static_cast<int>((strlen(argv[index]) + 1) / 2);
|
||||
VerifyOrExit(static_cast<size_t>(length) <= OT_STEERING_DATA_MAX_LENGTH, error = OT_ERROR_NO_BUFS);
|
||||
VerifyOrExit(Interpreter::Hex2Bin(argv[index], dataset.mSteeringData.m8, static_cast<uint16_t>(length)) >=
|
||||
0,
|
||||
error = OT_ERROR_PARSE);
|
||||
dataset.mSteeringData.mLength = static_cast<uint8_t>(length);
|
||||
length = 0;
|
||||
}
|
||||
else if (strcmp(argv[index], "joinerudpport") == 0)
|
||||
{
|
||||
VerifyOrExit(++index < argc, error = OT_ERROR_INVALID_ARGS);
|
||||
dataset.mIsJoinerUdpPortSet = true;
|
||||
SuccessOrExit(error = Interpreter::Interpreter::ParseLong(argv[index], value));
|
||||
dataset.mJoinerUdpPort = static_cast<uint16_t>(value);
|
||||
}
|
||||
else if (strcmp(argv[index], "binary") == 0)
|
||||
{
|
||||
VerifyOrExit(++index < argc, error = OT_ERROR_INVALID_ARGS);
|
||||
length = static_cast<int>((strlen(argv[index]) + 1) / 2);
|
||||
VerifyOrExit(static_cast<size_t>(length) <= sizeof(tlvs), error = OT_ERROR_NO_BUFS);
|
||||
VerifyOrExit(Interpreter::Hex2Bin(argv[index], tlvs, static_cast<uint16_t>(length)) >= 0,
|
||||
error = OT_ERROR_PARSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
ExitNow(error = OT_ERROR_INVALID_ARGS);
|
||||
}
|
||||
}
|
||||
|
||||
SuccessOrExit(error =
|
||||
otCommissionerSendMgmtSet(mInterpreter.mInstance, &dataset, tlvs, static_cast<uint8_t>(length)));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError Commissioner::ProcessPanId(int argc, char *argv[])
|
||||
{
|
||||
otError error;
|
||||
long panid;
|
||||
long mask;
|
||||
otIp6Address address;
|
||||
|
||||
VerifyOrExit(argc > 3, error = OT_ERROR_INVALID_ARGS);
|
||||
|
||||
SuccessOrExit(error = Interpreter::ParseLong(argv[1], panid));
|
||||
SuccessOrExit(error = Interpreter::ParseLong(argv[2], mask));
|
||||
SuccessOrExit(error = otIp6AddressFromString(argv[3], &address));
|
||||
|
||||
SuccessOrExit(error = otCommissionerPanIdQuery(mInterpreter.mInstance, static_cast<uint16_t>(panid),
|
||||
static_cast<uint32_t>(mask), &address,
|
||||
&Commissioner::HandlePanIdConflict, this));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError Commissioner::ProcessProvisioningUrl(int argc, char *argv[])
|
||||
{
|
||||
return otCommissionerSetProvisioningUrl(mInterpreter.mInstance, (argc > 1) ? argv[1] : NULL);
|
||||
}
|
||||
|
||||
otError Commissioner::ProcessSessionId(int argc, char *argv[])
|
||||
{
|
||||
OT_UNUSED_VARIABLE(argc);
|
||||
OT_UNUSED_VARIABLE(argv);
|
||||
|
||||
mInterpreter.mServer->OutputFormat("%d\r\n", otCommissionerGetSessionId(mInterpreter.mInstance));
|
||||
|
||||
return OT_ERROR_NONE;
|
||||
}
|
||||
|
||||
otError Commissioner::ProcessStart(int argc, char *argv[])
|
||||
{
|
||||
OT_UNUSED_VARIABLE(argc);
|
||||
OT_UNUSED_VARIABLE(argv);
|
||||
|
||||
return otCommissionerStart(mInterpreter.mInstance);
|
||||
}
|
||||
|
||||
otError Commissioner::ProcessStop(int argc, char *argv[])
|
||||
{
|
||||
OT_UNUSED_VARIABLE(argc);
|
||||
OT_UNUSED_VARIABLE(argv);
|
||||
|
||||
return otCommissionerStop(mInterpreter.mInstance);
|
||||
}
|
||||
|
||||
otError Commissioner::Process(int argc, char *argv[])
|
||||
{
|
||||
otError error = OT_ERROR_INVALID_ARGS;
|
||||
|
||||
if (argc < 1)
|
||||
{
|
||||
ProcessHelp(0, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t i = 0; i < OT_ARRAY_LENGTH(sCommands); i++)
|
||||
{
|
||||
if (strcmp(argv[0], sCommands[i].mName) == 0)
|
||||
{
|
||||
error = (this->*sCommands[i].mCommand)(argc, argv);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void OTCALL Commissioner::HandleEnergyReport(uint32_t aChannelMask,
|
||||
const uint8_t *aEnergyList,
|
||||
uint8_t aEnergyListLength,
|
||||
void * aContext)
|
||||
{
|
||||
static_cast<Commissioner *>(aContext)->HandleEnergyReport(aChannelMask, aEnergyList, aEnergyListLength);
|
||||
}
|
||||
|
||||
void Commissioner::HandleEnergyReport(uint32_t aChannelMask, const uint8_t *aEnergyList, uint8_t aEnergyListLength)
|
||||
{
|
||||
mInterpreter.mServer->OutputFormat("Energy: %08x ", aChannelMask);
|
||||
|
||||
for (uint8_t i = 0; i < aEnergyListLength; i++)
|
||||
{
|
||||
mInterpreter.mServer->OutputFormat("%d ", static_cast<int8_t>(aEnergyList[i]));
|
||||
}
|
||||
|
||||
mInterpreter.mServer->OutputFormat("\r\n");
|
||||
}
|
||||
|
||||
void OTCALL Commissioner::HandlePanIdConflict(uint16_t aPanId, uint32_t aChannelMask, void *aContext)
|
||||
{
|
||||
static_cast<Commissioner *>(aContext)->HandlePanIdConflict(aPanId, aChannelMask);
|
||||
}
|
||||
|
||||
void Commissioner::HandlePanIdConflict(uint16_t aPanId, uint32_t aChannelMask)
|
||||
{
|
||||
mInterpreter.mServer->OutputFormat("Conflict: %04x, %08x\r\n", aPanId, aChannelMask);
|
||||
}
|
||||
|
||||
} // namespace Cli
|
||||
} // namespace ot
|
||||
|
||||
#endif // OPENTHREAD_ENABLE_COMMISSIONER && OPENTHREAD_FTD
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (c) 2019, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file contains definitions for a simple CLI to control the Commissioner role.
|
||||
*/
|
||||
|
||||
#ifndef CLI_COMMISSIONER_HPP_
|
||||
#define CLI_COMMISSIONER_HPP_
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#include <openthread/commissioner.h>
|
||||
|
||||
#if OPENTHREAD_ENABLE_COMMISSIONER && OPENTHREAD_FTD
|
||||
|
||||
namespace ot {
|
||||
namespace Cli {
|
||||
|
||||
class Interpreter;
|
||||
|
||||
/**
|
||||
* This class implements the CLI CoAP Secure server and client.
|
||||
*
|
||||
*/
|
||||
class Commissioner
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param[in] aInterpreter The CLI interpreter.
|
||||
*
|
||||
*/
|
||||
explicit Commissioner(Interpreter &aInterpreter)
|
||||
: mInterpreter(aInterpreter)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This method interprets a list of CLI arguments.
|
||||
*
|
||||
* @param[in] argc The number of elements in argv.
|
||||
* @param[in] argv A pointer to an array of command line arguments.
|
||||
*
|
||||
*/
|
||||
otError Process(int argc, char *argv[]);
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
kDefaultJoinerTimeout = 120, ///< Default timeout for Joiners, in seconds.
|
||||
};
|
||||
|
||||
struct Command
|
||||
{
|
||||
const char *mName;
|
||||
otError (Commissioner::*mCommand)(int argc, char *argv[]);
|
||||
};
|
||||
|
||||
otError ProcessHelp(int argc, char *argv[]);
|
||||
otError ProcessAnnounce(int argc, char *argv[]);
|
||||
otError ProcessEnergy(int argc, char *argv[]);
|
||||
otError ProcessJoiner(int argc, char *argv[]);
|
||||
otError ProcessMgmtGet(int argc, char *argv[]);
|
||||
otError ProcessMgmtSet(int argc, char *argv[]);
|
||||
otError ProcessPanId(int argc, char *argv[]);
|
||||
otError ProcessProvisioningUrl(int argc, char *argv[]);
|
||||
otError ProcessSessionId(int argc, char *argv[]);
|
||||
otError ProcessStart(int argc, char *argv[]);
|
||||
otError ProcessStop(int argc, char *argv[]);
|
||||
|
||||
static void OTCALL HandleEnergyReport(uint32_t aChannelMask,
|
||||
const uint8_t *aEnergyList,
|
||||
uint8_t aEnergyListLength,
|
||||
void * aContext);
|
||||
void HandleEnergyReport(uint32_t aChannelMask, const uint8_t *aEnergyList, uint8_t aEnergyListLength);
|
||||
|
||||
static void OTCALL HandlePanIdConflict(uint16_t aPanId, uint32_t aChannelMask, void *aContext);
|
||||
void HandlePanIdConflict(uint16_t aPanId, uint32_t aChannelMask);
|
||||
|
||||
static const Command sCommands[];
|
||||
Interpreter & mInterpreter;
|
||||
};
|
||||
|
||||
} // namespace Cli
|
||||
} // namespace ot
|
||||
|
||||
#endif // OPENTHREAD_ENABLE_COMMISSIONER && OPENTHREAD_FTD
|
||||
|
||||
#endif // CLI_COMMISSIONER_HPP_
|
||||
Reference in New Issue
Block a user