From a18491ea2700537e12da40b261354a2f3b0c836c Mon Sep 17 00:00:00 2001 From: kangping Date: Wed, 3 Feb 2021 22:00:57 +0800 Subject: [PATCH] [example] add Minimum Thread Commissioner example --- example/BUILDING.md | 32 +++++ example/CMakeLists.txt | 42 +++++++ example/README.md | 83 +++++++++++++ example/mini_commissioner.cpp | 218 ++++++++++++++++++++++++++++++++++ src/common/CMakeLists.txt | 5 - src/java/CMakeLists.txt | 1 - src/library/CMakeLists.txt | 3 +- 7 files changed, 376 insertions(+), 8 deletions(-) create mode 100644 example/BUILDING.md create mode 100644 example/CMakeLists.txt create mode 100644 example/README.md create mode 100644 example/mini_commissioner.cpp diff --git a/example/BUILDING.md b/example/BUILDING.md new file mode 100644 index 000000000..4a5b5623d --- /dev/null +++ b/example/BUILDING.md @@ -0,0 +1,32 @@ +# Build Minimum Thread Commissioner + +## CMake Build + +```shell +cd ~/ot-commissioner/example +mkdir -p build && cd build +cmake -GNinja -DBUILD_SHARED_LIBS=ON .. +ninja +``` + +A `mini_commissioner` binary will be generated in `build/`. + +## Standalone build + +Build and install the OT Commissioner library: + +```c++ +cd ~/ot-commissioner +mkdir -p build && cd build +cmake -GNinja -DBUILD_SHARED_LIBS=ON .. +sudo ninja install +``` + +Build the `mini_commissioner` app: + +```c++ +cd ~/ot-commissioner/example +clang++ -std=c++11 -Wall -g mini_commissioner.cpp -o mini_commissioner -lcommissioner +``` + +The `mini_commissioner` binary will be generated in current directory. diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt new file mode 100644 index 000000000..e120b5956 --- /dev/null +++ b/example/CMakeLists.txt @@ -0,0 +1,42 @@ +# +# Copyright (c) 2021, The OpenThread Commissioner 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. +# + +cmake_minimum_required(VERSION 3.10.1) +project(mini-commissioner VERSION 0.0.1) + +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/.. + ${CMAKE_CURRENT_BINARY_DIR}/commissioner +) + +add_executable(mini_commissioner mini_commissioner.cpp) + +target_link_libraries(mini_commissioner PRIVATE commissioner) + +install(TARGETS mini_commissioner + RUNTIME DESTINATION bin +) diff --git a/example/README.md b/example/README.md new file mode 100644 index 000000000..e2c3caaa8 --- /dev/null +++ b/example/README.md @@ -0,0 +1,83 @@ +# Minimum Thread Commissioner + +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. + +## Build + +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). + +## Run the Commissioner + +### Start the BR (ot-daemon) + +See the [codelab](https://openthread.io/codelabs/openthread-simulation-posix). + +### Start the Mini Commissioner + +After a successful build, we should get a `mini_commissioner` binary which can be started with four arguments: + +```shell +./mini_commissioner ::1 49191 00112233445566778899aabbccddeeff ABCDEF +``` + +You can get the usage by starting `mini_commissioner` with no arguments: + +```shell +./minim_commissioner +usage: + mini_commissioner +``` + +> Note: the WiFi/ethernet interface address of the BR should be used but not the Thread interface address. + +If everything go smooth, we will get outputs like below: + +```shell +./mini_commissioner ::1 49191 ca117352886a861cce8a91021e65dd1c ABCDEF +=================================================== +[Border Router address] : ::1 +[Border Router port] : 49191 +[PSKc] : ca117352886a861cce8a91021e65dd1c +[PSKd] : ABCDEF +=================================================== + +=================================================== +type CRTL + C to quit! +=================================================== + +petitioning to [::1]:49191 +the commissioner is active: true +enabling MeshCoP for all joiners +waiting for joiners +``` + +> Note: you are free to quit at any time with `CTRL+C`. + +### Start the joiner + +See the [codelab](https://openthread.io/codelabs/openthread-simulation-posix). + +if everything go smooth, we will get output like below for two times of joining: + +```shell +joiner "5ab1f2745b625c90" is requesting join the Thread network +joiner "5ab1f2745b625c90" is connected: OK +joiner "5ab1f2745b625c90" is commissioned +[Vendor Name] : OPENTHREAD +[Vendor Model] : NRF52840 +[Vendor SW Version] : 20191113-01632-g +[Vendor Stack Version] : f4ce36000010 +[Provisioning URL] : +[Vendor Data] : + +joiner "5ab1f2745b625c90" is requesting join the Thread network +joiner "5ab1f2745b625c90" is connected: OK +joiner "5ab1f2745b625c90" is commissioned +[Vendor Name] : OPENTHREAD +[Vendor Model] : NRF52840 +[Vendor SW Version] : 20191113-01632-g +[Vendor Stack Version] : f4ce36000010 +[Provisioning URL] : +[Vendor Data] : + +``` diff --git a/example/mini_commissioner.cpp b/example/mini_commissioner.cpp new file mode 100644 index 000000000..451f41c3e --- /dev/null +++ b/example/mini_commissioner.cpp @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2021, The OpenThread Commissioner 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 + * The file implements the minimum Thread Commissioner example app. + */ + +#include +#include + +#include +#include +#include + +#include + +#include + +using namespace ot::commissioner; + +static std::string ToHexString(const ByteArray &aBytes) +{ + std::string str; + + for (uint8_t byte : aBytes) + { + char buf[3]; + + sprintf(buf, "%02x", byte); + str.append(buf); + } + + return str; +} + +static ByteArray FromHexString(const std::string &aHex) +{ + assert(aHex.size() % 2 == 0); + + ByteArray bytes; + + for (size_t i = 0; i < aHex.size(); i += 2) + { + assert(isxdigit(aHex[i])); + assert(isxdigit(aHex[i + 1])); + + uint8_t x = isdigit(aHex[i]) ? (aHex[i] - '0') : (tolower(aHex[i]) - 'a' + 10); + uint8_t y = isdigit(aHex[i + 1]) ? (aHex[i + 1] - '0') : (tolower(aHex[i + 1]) - 'a' + 10); + + bytes.push_back((x << 4) | y); + } + return bytes; +} + +class MyCommissionerHandler : public CommissionerHandler +{ +public: + MyCommissionerHandler(const std::string &aPskd) + : mPskd(aPskd) + { + } + + std::string OnJoinerRequest(const ByteArray &aJoinerId) override + { + auto joinerId = ToHexString(aJoinerId); + + printf("\n"); + printf("joiner \"%s\" is requesting join the Thread network\n", joinerId.c_str()); + + return mPskd; + } + + void OnJoinerConnected(const ByteArray &aJoinerId, Error aError) override + { + auto joinerId = ToHexString(aJoinerId); + + printf("joiner \"%s\" is connected: %s\n", joinerId.c_str(), aError.ToString().c_str()); + } + + bool OnJoinerFinalize(const ByteArray & aJoinerId, + const std::string &aVendorName, + const std::string &aVendorModel, + const std::string &aVendorSwVersion, + const ByteArray & aVendorStackVersion, + const std::string &aProvisioningUrl, + const ByteArray & aVendorData) override + { + printf("joiner \"%s\" is commissioned\n", ToHexString(aJoinerId).c_str()); + printf("[Vendor Name] : %s\n", aVendorName.c_str()); + printf("[Vendor Model] : %s\n", aVendorModel.c_str()); + printf("[Vendor SW Version] : %s\n", aVendorSwVersion.c_str()); + printf("[Vendor Stack Version] : %s\n", ToHexString(aVendorStackVersion).c_str()); + printf("[Provisioning URL] : %s\n", aProvisioningUrl.c_str()); + printf("[Vendor Data] : %s\n", ToHexString(aVendorData).c_str()); + + return true; + } + +private: + std::string mPskd; +}; + +std::shared_ptr commissioner; + +void SignalHandler(int signal) +{ + if (commissioner != nullptr) + { + printf("\nResigning the commissioner\n"); + commissioner->Resign().IgnoreError(); + } + + exit(0); +} + +int main(int argc, const char *argv[]) +{ + if (argc != 5) + { + printf("usage:\n"); + printf(" mini_commissioner \n"); + return -1; + } + + std::string brAddr = argv[1]; + uint16_t brPort = std::stoul(argv[2]); + ByteArray pskc = FromHexString(argv[3]); + std::string pskd = argv[4]; + + printf("===================================================\n"); + printf("[Border Router address] : %s\n", brAddr.c_str()); + printf("[Border Router port] : %hu\n", brPort); + printf("[PSKc] : %s\n", ToHexString(pskc).c_str()); + printf("[PSKd] : %s\n", pskd.c_str()); + printf("===================================================\n\n"); + + MyCommissionerHandler myHandler{pskd}; + commissioner = Commissioner::Create(myHandler); + + signal(SIGINT, SignalHandler); + printf("===================================================\n"); + printf("type CRTL + C to quit!\n"); + printf("===================================================\n\n"); + + Config config; + config.mEnableCcm = false; + config.mPSKc = pskc; + + Error error; + + if ((error = commissioner->Init(config)) != ErrorCode::kNone) + { + printf("failed to initialize the commissioner: %s\n", error.ToString().c_str()); + return -1; + } + + std::string existingCommissionerId; + + printf("petitioning to [%s]:%hu\n", brAddr.c_str(), brPort); + error = commissioner->Petition(existingCommissionerId, brAddr, brPort); + if (error != ErrorCode::kNone) + { + printf("failed to petition to BR at [%s]:%hu: %s\n", brAddr.c_str(), brPort, error.ToString().c_str()); + return -1; + } + + // Check if we are active now. + printf("the commissioner is active: %s\n", commissioner->IsActive() ? "true" : "false"); + assert(commissioner->IsActive()); + + CommissionerDataset dataset; + + printf("enabling MeshCoP for all joiners\n"); + dataset.mPresentFlags |= CommissionerDataset::kSteeringDataBit; + dataset.mSteeringData = {0xFF}; // Set the steeering data to all-ones to allow all joiners. + error = commissioner->SetCommissionerDataset(dataset); + if (error != ErrorCode::kNone) + { + printf("failed to enable MeshCop for all joiners: %s\n", error.ToString().c_str()); + return -1; + } + + printf("waiting for joiners\n"); + while (true) + { + sleep(1); + } + + commissioner->Resign().IgnoreError(); + + return 0; +} diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 69b12e6fa..6a536cdf4 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -47,11 +47,6 @@ target_include_directories(commissioner-common ${PROJECT_SOURCE_DIR}/src ) -install(TARGETS commissioner-common - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib -) - if (OT_COMM_TEST) add_library(commissioner-common-test OBJECT address.hpp diff --git a/src/java/CMakeLists.txt b/src/java/CMakeLists.txt index 57c9edf39..96341087a 100644 --- a/src/java/CMakeLists.txt +++ b/src/java/CMakeLists.txt @@ -57,7 +57,6 @@ swig_add_library(commissioner-java swig_link_libraries(commissioner-java commissioner - commissioner-common ) ## GCC is too strict on this in optimization mode, see http://www.swig.org/Doc3.0/Java.html#Java_compiling_dynamic diff --git a/src/library/CMakeLists.txt b/src/library/CMakeLists.txt index b79e6e6d7..e6b734f16 100644 --- a/src/library/CMakeLists.txt +++ b/src/library/CMakeLists.txt @@ -84,7 +84,7 @@ target_link_libraries(commissioner event_core event_pthreads $<$>:pthread> - commissioner-common + $ ) target_compile_definitions(commissioner @@ -176,7 +176,6 @@ if (OT_COMM_TEST) event_pthreads commissioner $<$:commissioner-app> - commissioner-common ) target_compile_definitions(commissioner-test