[cli] support joiner discerner (#5298)

This commit adds support joiner discerner in CLI. The format of joiner
discerner is `number/length`. For example `0xabc/12` means the discerner
value is `0xabc` and the length is `12`.
This commit is contained in:
Yakun Xu
2020-07-27 20:27:21 -07:00
committed by GitHub
parent 2117dae5f8
commit cbf1a19483
10 changed files with 239 additions and 30 deletions
+7 -1
View File
@@ -81,11 +81,12 @@ Energy: 00050000 0 0 0 0
### joiner add
Usage: `commissioner joiner add <eui64> <pskd>`
Usage: `commissioner joiner add <eui64>|<discerner> <pskd>`
Add a Joiner entry.
- eui64: The IEEE EUI-64 of the Joiner or '\*' to match any Joiner.
- discerner: The Joiner discerner in format `number/length`.
- pskd: Pre-Shared Key for the Joiner.
```bash
@@ -93,6 +94,11 @@ Add a Joiner entry.
Done
```
```bash
> commissioner joiner add 0xabc/12 J01NME
Done
```
### joiner remove
Usage: `commissioner joiner remove <eui64>`
+19
View File
@@ -7,6 +7,7 @@ See [README_COMMISSIONING.md](README_COMMISSIONING.md).
## Command List
- [help](#help)
- [discerner](#discerner)
- [id](#id)
- [start](#start)
- [stop](#stop)
@@ -28,6 +29,24 @@ stop
Done
```
### discerner
Usage: `joiner discerner [discerner]`
Print or set the Joiner Discerner. Note this value takes the place of the place of EUI-64 during the joiner session of Thread commissioning.
- discerner: `clear` to clear discerner, `number/length` to set discerner
```bash
> joiner discerner 0xabc/12
Done
> joiner discerner
0xabc/12
Done
> joiner discerner clear
Done
```
### id
Usage: `joiner id`
+24
View File
@@ -399,6 +399,30 @@ otError Interpreter::ParseUnsignedLong(char *aString, unsigned long &aUnsignedLo
return (*endptr == '\0') ? OT_ERROR_NONE : OT_ERROR_INVALID_ARGS;
}
otError Interpreter::ParseJoinerDiscerner(char *aString, otJoinerDiscerner &aDiscerner)
{
otError error = OT_ERROR_NONE;
char * separator = strstr(aString, "/");
unsigned long length;
VerifyOrExit(separator != nullptr, error = OT_ERROR_NOT_FOUND);
SuccessOrExit(error = ParseUnsignedLong(separator + 1, length));
VerifyOrExit(length > 0 && length <= 64, error = OT_ERROR_INVALID_ARGS);
{
char * end;
unsigned long long value = strtoull(aString, &end, 0);
aDiscerner.mValue = value;
VerifyOrExit(end == separator, error = OT_ERROR_INVALID_ARGS);
}
aDiscerner.mLength = static_cast<uint8_t>(length);
exit:
return error;
}
otError Interpreter::ParsePingInterval(const char *aString, uint32_t &aInterval)
{
otError error = OT_ERROR_NONE;
+5 -4
View File
@@ -204,10 +204,11 @@ private:
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[]);
otError ParsePingInterval(const char *aString, uint32_t &aInterval);
static otError ParseJoinerDiscerner(char *aString, otJoinerDiscerner &aJoinerDiscerner);
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[]);
+20 -5
View File
@@ -116,20 +116,27 @@ otError Commissioner::ProcessJoiner(uint8_t aArgsLength, char *aArgs[])
{
otError error;
otExtAddress addr;
const otExtAddress *addrPtr;
const otExtAddress *addrPtr = nullptr;
otJoinerDiscerner discerner;
VerifyOrExit(aArgsLength > 2, error = OT_ERROR_INVALID_ARGS);
memset(&discerner, 0, sizeof(discerner));
if (strcmp(aArgs[2], "*") == 0)
{
addrPtr = nullptr;
// Intentionally empty
}
else
else if ((error = Interpreter::ParseJoinerDiscerner(aArgs[2], discerner)) == OT_ERROR_NOT_FOUND)
{
VerifyOrExit(Interpreter::Hex2Bin(aArgs[2], addr.m8, sizeof(addr)) == sizeof(addr),
error = OT_ERROR_INVALID_ARGS);
addrPtr = &addr;
}
else if (error != OT_ERROR_NONE)
{
ExitNow();
}
if (strcmp(aArgs[1], "add") == 0)
{
@@ -142,8 +149,16 @@ otError Commissioner::ProcessJoiner(uint8_t aArgsLength, char *aArgs[])
SuccessOrExit(error = Interpreter::ParseUnsignedLong(aArgs[4], timeout));
}
SuccessOrExit(
error = otCommissionerAddJoiner(mInterpreter.mInstance, addrPtr, aArgs[3], static_cast<uint32_t>(timeout)));
if (discerner.mLength)
{
SuccessOrExit(error = otCommissionerAddJoinerWithDiscerner(mInterpreter.mInstance, &discerner, aArgs[3],
static_cast<uint32_t>(timeout)));
}
else
{
SuccessOrExit(error = otCommissionerAddJoiner(mInterpreter.mInstance, addrPtr, aArgs[3],
static_cast<uint32_t>(timeout)));
}
}
else if (strcmp(aArgs[1], "remove") == 0)
{
+41 -4
View File
@@ -33,6 +33,8 @@
#include "cli_joiner.hpp"
#include <inttypes.h>
#include "cli/cli.hpp"
#include "cli/cli_server.hpp"
@@ -42,12 +44,47 @@ namespace ot {
namespace Cli {
const struct Joiner::Command Joiner::sCommands[] = {
{"help", &Joiner::ProcessHelp},
{"id", &Joiner::ProcessId},
{"start", &Joiner::ProcessStart},
{"stop", &Joiner::ProcessStop},
{"discerner", &Joiner::ProcessDiscerner}, {"help", &Joiner::ProcessHelp}, {"id", &Joiner::ProcessId},
{"start", &Joiner::ProcessStart}, {"stop", &Joiner::ProcessStop},
};
otError Joiner::ProcessDiscerner(uint8_t aArgsLength, char *aArgs[])
{
otError error = OT_ERROR_NONE;
if (aArgsLength == 2)
{
otJoinerDiscerner discerner;
memset(&discerner, 0, sizeof(discerner));
if (strcmp(aArgs[1], "clear") == 0)
{
SuccessOrExit(error = otJoinerSetDiscerner(mInterpreter.mInstance, nullptr));
}
else
{
VerifyOrExit(OT_ERROR_NONE == Interpreter::ParseJoinerDiscerner(aArgs[1], discerner),
error = OT_ERROR_INVALID_ARGS);
SuccessOrExit(error = otJoinerSetDiscerner(mInterpreter.mInstance, &discerner));
}
}
else if (aArgsLength == 1)
{
const otJoinerDiscerner *discerner = otJoinerGetDiscerner(mInterpreter.mInstance);
VerifyOrExit(discerner != nullptr, error = OT_ERROR_NOT_FOUND);
mInterpreter.mServer->OutputFormat("0x%" PRIx64 "/%u\r\n", discerner->mValue, discerner->mLength);
}
else
{
error = OT_ERROR_INVALID_ARGS;
}
exit:
return error;
}
otError Joiner::ProcessHelp(uint8_t aArgsLength, char *aArgs[])
{
OT_UNUSED_VARIABLE(aArgsLength);
+1
View File
@@ -79,6 +79,7 @@ private:
otError (Joiner::*mCommand)(uint8_t aArgsLength, char *aArgs[]);
};
otError ProcessDiscerner(uint8_t aArgsLength, char *aArgs[]);
otError ProcessHelp(uint8_t aArgsLength, char *aArgs[]);
otError ProcessId(uint8_t aArgsLength, char *aArgs[]);
otError ProcessStart(uint8_t aArgsLength, char *aArgs[]);
+34 -2
View File
@@ -27,7 +27,7 @@
# POSSIBILITY OF SUCH DAMAGE.
#
proc wait_for {command expected} {
proc wait_for {command success {failure {[\r\n]FAILURE_NOT_EXPECTED[\r\n]}}} {
set result 0
set timeout 1
for {set i 0} {$i < 20} {incr i} {
@@ -36,9 +36,12 @@ proc wait_for {command expected} {
}
expect {
-re $expected {
-re $success {
set result 1
}
-re $failure {
exit 1
}
timeout {
# Do nothing
}
@@ -64,9 +67,38 @@ proc spawn_node {id} {
return $spawn_id
}
proc setup_leader {} {
# Sets up a Thread network spawn_1 as the leader.
global spawn_1
global spawn_id
global env
set spawn_1 [spawn_node 1]
set spawn_id $spawn_1
send "dataset init new\n"
expect "Done"
send "dataset commit active\n"
expect "Done"
send "ifconfig up\n"
expect "Done"
send "thread start\n"
expect "Done"
wait_for "state" "leader"
expect "Done"
}
proc dispose {} {
send "\x04"
expect eof
}
proc dispose_leader {} {
global spawn_1
global spawn_id
set spawn_id $spawn_1
dispose
}
set timeout 10
+3 -14
View File
@@ -38,7 +38,6 @@ proc setup_nodes {} {
global spawn_id
global env
set spawn_1 [spawn_node 1]
set spawn_2 [spawn_node 2]
set psk "J01NME"
@@ -48,17 +47,9 @@ proc setup_nodes {} {
set eui64 $expect_out(1,string)
expect "Done"
setup_leader
set spawn_id $spawn_1
send "dataset init new\n"
expect "Done"
send "dataset commit active\n"
expect "Done"
send "ifconfig up\n"
expect "Done"
send "thread start\n"
expect "Done"
wait_for "state" "leader"
expect "Done"
send "commissioner start\n"
expect "Done"
expect "Commissioner: active"
@@ -84,12 +75,10 @@ proc setup_nodes {} {
}
proc dispose_nodes {} {
global spawn_1
global spawn_2
global spawn_id
set spawn_id $spawn_1
dispose
dispose_leader
set spawn_id $spawn_2
dispose
}
+85
View File
@@ -0,0 +1,85 @@
#!/usr/bin/expect -f
#
# Copyright (c) 2020, 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.
#
source "tests/scripts/expect/_common.exp"
setup_leader
set pskd "J01NME"
set discerner "0xabc/12"
send "commissioner start\n"
expect "Done"
expect "Commissioner: active"
send "commissioner joiner add 1/0 $pskd\n"
expect "InvalidArgs"
send "commissioner joiner add $discerner $pskd\n"
expect "Done"
set spawn_2 [spawn_node 2]
set spawn_id $spawn_2
send "mode rs\n"
expect "Done"
send "ifconfig up\n"
expect "Done"
send "joiner discerner\n"
expect "NotFound"
send "joiner discerner 1/1 2\n"
expect "InvalidArgs"
send "joiner discerner 1\n"
expect "InvalidArgs"
send "joiner discerner 1/\n"
expect "InvalidArgs"
send "joiner discerner 1/128\n"
expect "InvalidArgs"
send "joiner discerner 1/-1\n"
expect "InvalidArgs"
send "joiner discerner 1/0\n"
expect "InvalidArgs"
send "joiner discerner invalid/20\n"
expect "InvalidArgs"
send "joiner discerner clear\n"
expect "Done"
send "joiner discerner $discerner\n"
expect "Done"
send "joiner discerner\n"
expect "$discerner"
expect "Done"
send "joiner start $pskd\n"
expect "Done"
wait_for "" "Join success" "Join failed"
send "thread start\n"
expect "Done"
wait_for "state" "child"
expect "Done"
dispose
dispose_leader