[cli] move commissioner to separate source files (#3862)

This commit is contained in:
Jonathan Hui
2019-05-28 18:25:50 -07:00
committed by Jonathan Hui
parent 9cd11a2761
commit 68beda5b07
10 changed files with 530 additions and 288 deletions
+1
View File
@@ -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>
+2
View File
@@ -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
View File
@@ -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
View File
@@ -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
+387
View File
@@ -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
+117
View File
@@ -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_