Skip to content

Commit 523346c

Browse files
committed
[example] add Minimum Thread Commissioner example
1 parent e021a5f commit 523346c

File tree

4 files changed

+374
-0
lines changed

4 files changed

+374
-0
lines changed

example/BUILDING.md

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Build Minimum Thread Commissioner
2+
3+
## CMake Build
4+
5+
```shell
6+
cd ~/ot-commissioner/example
7+
mkdir -p build && cd build
8+
cmake -GNinja ..
9+
ninja
10+
```
11+
12+
A `mini_commissioner` binary will be generated in `build/`.
13+
14+
## Standalone build
15+
16+
Build and install the OT Commissioner library:
17+
18+
```c++
19+
cd ~/ot-commissioner
20+
mkdir -p build && cd build
21+
cmake -GNinja ..
22+
sudo ninja install
23+
```
24+
25+
Build the `mini_commissioner` app:
26+
27+
```c++
28+
cd ~/ot-commissioner/example
29+
clang++ -std=c++11 -Wall -g mini_commissioner.cpp -o mini_commissioner -lcommissioner
30+
```
31+
32+
The `mini_commissioner` binary will be generated in current directory.

example/CMakeLists.txt

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#
2+
# Copyright (c) 2021, The OpenThread Commissioner 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+
project(mini-commissioner VERSION 0.0.1)
30+
31+
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/..
32+
${CMAKE_CURRENT_BINARY_DIR}/commissioner
33+
)
34+
35+
add_executable(mini_commissioner mini_commissioner.cpp)
36+
37+
target_link_libraries(mini_commissioner PRIVATE commissioner)
38+
39+
install(TARGETS mini_commissioner
40+
RUNTIME DESTINATION bin
41+
)

example/README.md

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Minimum Thread Commissioner
2+
3+
This directory includes an example of building a minimum Thread Commissioner with the OT Commissioner library. The minimum Thread Commissioner petitions to given Border Router, enables MeshCoP for all joiners and commissions joiners.
4+
5+
## Build
6+
7+
See [BUILDING.md](./BUILDING.md) for building this mini Commissioner program. You can find details about the Border Router (`ot-daemon`) and simulation devices in this [codelab](https://openthread.io/codelabs/openthread-simulation-posix).
8+
9+
## Run the Commissioner
10+
11+
### Start the BR (ot-daemon)
12+
13+
See the [codelab](https://openthread.io/codelabs/openthread-simulation-posix).
14+
15+
### Start the Mini Commissioner
16+
17+
After a successful build, we should get a `mini_commissioner` binary which can be started with four arguments:
18+
19+
```shell
20+
./mini_commissioner ::1 49191 00112233445566778899aabbccddeeff ABCDEF
21+
```
22+
23+
You can get the usage by starting `mini_commissioner` with no arguments:
24+
25+
```shell
26+
./minim_commissioner
27+
usage:
28+
mini_commissioner <br-addr> <br-port> <pskc-hex> <pskd>
29+
```
30+
31+
> Note: the WiFi/ethernet interface address of the BR should be used but not the Thread interface address.
32+
33+
If everything go smooth, we will get outputs like below:
34+
35+
```shell
36+
./mini_commissioner ::1 49191 ca117352886a861cce8a91021e65dd1c ABCDEF
37+
===================================================
38+
[Border Router address] : ::1
39+
[Border Router port] : 49191
40+
[PSKc] : ca117352886a861cce8a91021e65dd1c
41+
[PSKd] : ABCDEF
42+
===================================================
43+
44+
===================================================
45+
type CRTL + C to quit!
46+
===================================================
47+
48+
petitioning to [::1]:49191
49+
the commissioner is active: true
50+
enabling MeshCoP for all joiners
51+
waiting for joiners
52+
```
53+
54+
> Note: you are free to quit at any time with `CTRL+C`.
55+
56+
### Start the joiner
57+
58+
See the [codelab](https://openthread.io/codelabs/openthread-simulation-posix).
59+
60+
if everything go smooth, we will get output like below for two times of joining:
61+
62+
```shell
63+
joiner "5ab1f2745b625c90" is requesting join the Thread network
64+
joiner "5ab1f2745b625c90" is connected: OK
65+
joiner "5ab1f2745b625c90" is commissioned
66+
[Vendor Name] : OPENTHREAD
67+
[Vendor Model] : NRF52840
68+
[Vendor SW Version] : 20191113-01632-g
69+
[Vendor Stack Version] : f4ce36000010
70+
[Provisioning URL] :
71+
[Vendor Data] :
72+
73+
joiner "5ab1f2745b625c90" is requesting join the Thread network
74+
joiner "5ab1f2745b625c90" is connected: OK
75+
joiner "5ab1f2745b625c90" is commissioned
76+
[Vendor Name] : OPENTHREAD
77+
[Vendor Model] : NRF52840
78+
[Vendor SW Version] : 20191113-01632-g
79+
[Vendor Stack Version] : f4ce36000010
80+
[Provisioning URL] :
81+
[Vendor Data] :
82+
83+
```

example/mini_commissioner.cpp

+218
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
/*
2+
* Copyright (c) 2021, The OpenThread Commissioner 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+
* The file implements the minimum Thread Commissioner example app.
32+
*/
33+
34+
#include <iomanip>
35+
#include <sstream>
36+
37+
#include <assert.h>
38+
#include <signal.h>
39+
#include <stdio.h>
40+
41+
#include <unistd.h>
42+
43+
#include <commissioner/commissioner.hpp>
44+
45+
using namespace ot::commissioner;
46+
47+
static std::string ToHexString(const ByteArray &aBytes)
48+
{
49+
std::string str;
50+
51+
for (uint8_t byte : aBytes)
52+
{
53+
char buf[3];
54+
55+
sprintf(buf, "%02x", byte);
56+
str.append(buf);
57+
}
58+
59+
return str;
60+
}
61+
62+
static ByteArray FromHexString(const std::string &aHex)
63+
{
64+
assert(aHex.size() % 2 == 0);
65+
66+
ByteArray bytes;
67+
68+
for (size_t i = 0; i < aHex.size(); i += 2)
69+
{
70+
assert(isxdigit(aHex[i]));
71+
assert(isxdigit(aHex[i + 1]));
72+
73+
uint8_t x = isdigit(aHex[i]) ? (aHex[i] - '0') : (tolower(aHex[i]) - 'a' + 10);
74+
uint8_t y = isdigit(aHex[i + 1]) ? (aHex[i + 1] - '0') : (tolower(aHex[i + 1]) - 'a' + 10);
75+
76+
bytes.push_back((x << 4) | y);
77+
}
78+
return bytes;
79+
}
80+
81+
class MyCommissionerHandler : public CommissionerHandler
82+
{
83+
public:
84+
MyCommissionerHandler(const std::string &aPskd)
85+
: mPskd(aPskd)
86+
{
87+
}
88+
89+
std::string OnJoinerRequest(const ByteArray &aJoinerId) override
90+
{
91+
auto joinerId = ToHexString(aJoinerId);
92+
93+
printf("\n");
94+
printf("joiner \"%s\" is requesting join the Thread network\n", joinerId.c_str());
95+
96+
return mPskd;
97+
}
98+
99+
void OnJoinerConnected(const ByteArray &aJoinerId, Error aError) override
100+
{
101+
auto joinerId = ToHexString(aJoinerId);
102+
103+
printf("joiner \"%s\" is connected: %s\n", joinerId.c_str(), aError.ToString().c_str());
104+
}
105+
106+
bool OnJoinerFinalize(const ByteArray & aJoinerId,
107+
const std::string &aVendorName,
108+
const std::string &aVendorModel,
109+
const std::string &aVendorSwVersion,
110+
const ByteArray & aVendorStackVersion,
111+
const std::string &aProvisioningUrl,
112+
const ByteArray & aVendorData) override
113+
{
114+
printf("joiner \"%s\" is commissioned\n", ToHexString(aJoinerId).c_str());
115+
printf("[Vendor Name] : %s\n", aVendorName.c_str());
116+
printf("[Vendor Model] : %s\n", aVendorModel.c_str());
117+
printf("[Vendor SW Version] : %s\n", aVendorSwVersion.c_str());
118+
printf("[Vendor Stack Version] : %s\n", ToHexString(aVendorStackVersion).c_str());
119+
printf("[Provisioning URL] : %s\n", aProvisioningUrl.c_str());
120+
printf("[Vendor Data] : %s\n", ToHexString(aVendorData).c_str());
121+
122+
return true;
123+
}
124+
125+
private:
126+
std::string mPskd;
127+
};
128+
129+
std::shared_ptr<Commissioner> commissioner;
130+
131+
void SignalHandler(int signal)
132+
{
133+
if (commissioner != nullptr)
134+
{
135+
printf("\nResigning the commissioner\n");
136+
commissioner->Resign();
137+
}
138+
139+
exit(0);
140+
}
141+
142+
int main(int argc, const char *argv[])
143+
{
144+
if (argc != 5)
145+
{
146+
printf("usage:\n");
147+
printf(" mini_commissioner <br-addr> <br-port> <pskc-hex> <pskd>\n");
148+
return -1;
149+
}
150+
151+
std::string brAddr = argv[1];
152+
uint16_t brPort = std::stoul(argv[2]);
153+
ByteArray pskc = FromHexString(argv[3]);
154+
std::string pskd = argv[4];
155+
156+
printf("===================================================\n");
157+
printf("[Border Router address] : %s\n", brAddr.c_str());
158+
printf("[Border Router port] : %hu\n", brPort);
159+
printf("[PSKc] : %s\n", ToHexString(pskc).c_str());
160+
printf("[PSKd] : %s\n", pskd.c_str());
161+
printf("===================================================\n\n");
162+
163+
MyCommissionerHandler myHandler{pskd};
164+
commissioner = Commissioner::Create(myHandler);
165+
166+
signal(SIGINT, SignalHandler);
167+
printf("===================================================\n");
168+
printf("type CRTL + C to quit!\n");
169+
printf("===================================================\n\n");
170+
171+
Config config;
172+
config.mEnableCcm = false;
173+
config.mPSKc = pskc;
174+
175+
Error error;
176+
177+
if ((error = commissioner->Init(config)) != ErrorCode::kNone)
178+
{
179+
printf("failed to initialize the commissioner: %s\n", error.ToString().c_str());
180+
return -1;
181+
}
182+
183+
std::string existingCommissionerId;
184+
185+
printf("petitioning to [%s]:%hu\n", brAddr.c_str(), brPort);
186+
error = commissioner->Petition(existingCommissionerId, brAddr, brPort);
187+
if (error != ErrorCode::kNone)
188+
{
189+
printf("failed to petition to BR at [%s]:%hu: %s\n", brAddr.c_str(), brPort, error.ToString().c_str());
190+
return -1;
191+
}
192+
193+
// Check if we are active now.
194+
printf("the commissioner is active: %s\n", commissioner->IsActive() ? "true" : "false");
195+
assert(commissioner->IsActive());
196+
197+
CommissionerDataset dataset;
198+
199+
printf("enabling MeshCoP for all joiners\n");
200+
dataset.mPresentFlags |= CommissionerDataset::kSteeringDataBit;
201+
dataset.mSteeringData = {0xFF}; // Set the steeering data to all-ones to allow all joiners.
202+
error = commissioner->SetCommissionerDataset(dataset);
203+
if (error != ErrorCode::kNone)
204+
{
205+
printf("failed to enable MeshCop for all joiners: %s\n", error.ToString().c_str());
206+
return -1;
207+
}
208+
209+
printf("waiting for joiners\n");
210+
while (true)
211+
{
212+
sleep(1);
213+
}
214+
215+
commissioner->Resign().IgnoreError();
216+
217+
return 0;
218+
}

0 commit comments

Comments
 (0)