From 0d33f8c80fccd00d36d9afd278bb6c2c68bf237c Mon Sep 17 00:00:00 2001 From: Yakun Xu Date: Tue, 28 Jul 2020 21:51:53 +0800 Subject: [PATCH] [nrf5-lock] enable Thread joining (#1879) * [nrf5] enable Thread joining * add method stub on linux * only add joiner handler when thread is enabled * fix lgtm comments --- config/nrf5/nrf5-chip.mk | 7 +- examples/Makefile.am | 1 - examples/lock-app/nrf5/Makefile | 3 + examples/lock-app/nrf5/main/AppTask.cpp | 32 ++++++++- examples/lock-app/nrf5/main/include/AppTask.h | 1 + .../lock-app/nrf5/main/include/app_config.h | 3 +- src/include/platform/ThreadStackManager.h | 7 ++ .../GenericConfigurationManagerImpl.ipp | 16 ++--- src/platform/Linux/ThreadStackManagerImpl.cpp | 5 ++ src/platform/Linux/ThreadStackManagerImpl.h | 2 + ...GenericThreadStackManagerImpl_OpenThread.h | 5 ++ ...nericThreadStackManagerImpl_OpenThread.ipp | 67 +++++++++++++++++++ ...ThreadStackManagerImpl_OpenThread_LwIP.ipp | 3 + src/platform/nRF5/CHIPDevicePlatformConfig.h | 4 +- third_party/openthread/repo | 2 +- 15 files changed, 141 insertions(+), 17 deletions(-) diff --git a/config/nrf5/nrf5-chip.mk b/config/nrf5/nrf5-chip.mk index 1d6ff88e793e74..a0da62fafc6e97 100644 --- a/config/nrf5/nrf5-chip.mk +++ b/config/nrf5/nrf5-chip.mk @@ -152,7 +152,8 @@ STD_LIBS += \ -lCHIPDataModel \ -lInetLayer \ -lSystemLayer \ - -llwip + -llwip \ + -lSetupPayload # Add the appropriate CHIP target as a prerequisite to all application # compilation targets to ensure that CHIP gets built and its header @@ -165,7 +166,9 @@ STD_LINK_PREREQUISITES += \ $(CHIP_OUTPUT_DIR)/lib/libCHIP.a \ $(CHIP_OUTPUT_DIR)/lib/libInetLayer.a \ $(CHIP_OUTPUT_DIR)/lib/libSystemLayer.a \ - $(CHIP_OUTPUT_DIR)/lib/liblwip.a + $(CHIP_OUTPUT_DIR)/lib/liblwip.a \ + $(CHIP_OUTPUT_DIR)/lib/libSetupPayload.a \ + # ================================================== diff --git a/examples/Makefile.am b/examples/Makefile.am index b8b84ebf49af0d..1c970ce817b88b 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -73,7 +73,6 @@ PRETTY_FILES = \ lock-app/nrf5/main/support/AltPrintf.c \ lock-app/nrf5/main/support/FreeRTOSNewlibLockSupport.c \ lock-app/nrf5/main/support/nRF5Sbrk.c \ - lock-app/nrf5/main/support/CXXExceptionStubs.cpp \ $(NULL) include $(abs_top_nlbuild_autotools_dir)/automake/post.am diff --git a/examples/lock-app/nrf5/Makefile b/examples/lock-app/nrf5/Makefile index ec385e33d1afdc..31ee18c7fee98d 100644 --- a/examples/lock-app/nrf5/Makefile +++ b/examples/lock-app/nrf5/Makefile @@ -113,10 +113,12 @@ INC_DIRS = \ $(PROJECT_ROOT)/main/traits/include \ $(PROJECT_ROOT)/main/schema/include \ $(PROJECT_ROOT)/third_party/printf \ + $(CHIP_OUTPUT_DIR)/third_party/openthread/include \ $(CHIP_ROOT)/src/include/ \ $(CHIP_ROOT)/src/lib \ $(CHIP_ROOT)/src/ \ $(CHIP_ROOT)/src/system \ + $(CHIP_ROOT)/third_party/openthread/repo/include \ $(NRF5_PLATFORM_DIR)/app/include \ $(NRF5_PLATFORM_DIR)/app/project_include \ $(NRF5_PLATFORM_DIR)/util/include \ @@ -210,6 +212,7 @@ LIBS = \ -lopenthread-nrf52840-transport \ -lopenthread-nrf52840-softdevice-sdk \ -lnordicsemi-nrf52840-radio-driver-softdevice \ + -lSetupPayload \ $(NRF5_SDK_ROOT)/external/openthread/nrf_security/lib/libmbedcrypto_glue.a \ $(NRF5_SDK_ROOT)/external/openthread/nrf_security/lib/libmbedcrypto_glue_cc310.a \ $(NRF5_SDK_ROOT)/external/openthread/nrf_security/lib/libmbedcrypto_glue_vanilla.a \ diff --git a/examples/lock-app/nrf5/main/AppTask.cpp b/examples/lock-app/nrf5/main/AppTask.cpp index 27e5d6361986fc..dc4b46181b46b5 100644 --- a/examples/lock-app/nrf5/main/AppTask.cpp +++ b/examples/lock-app/nrf5/main/AppTask.cpp @@ -33,6 +33,10 @@ #include "FreeRTOS.h" #include +#if CHIP_ENABLE_OPENTHREAD +#include +#endif +#include #define FACTORY_RESET_TRIGGER_TIMEOUT 3000 #define FACTORY_RESET_CANCEL_WINDOW_TIMEOUT 3000 @@ -102,6 +106,9 @@ int AppTask::Init() static app_button_cfg_t sButtons[] = { { LOCK_BUTTON, APP_BUTTON_ACTIVE_LOW, BUTTON_PULL, ButtonEventHandler }, { FUNCTION_BUTTON, APP_BUTTON_ACTIVE_LOW, BUTTON_PULL, ButtonEventHandler }, +#if CHIP_ENABLE_OPENTHREAD + { JOIN_BUTTON, APP_BUTTON_ACTIVE_LOW, BUTTON_PULL, ButtonEventHandler }, +#endif }; ret = app_button_init(sButtons, ARRAY_SIZE(sButtons), pdMS_TO_TICKS(FUNCTION_BUTTON_DEBOUNCE_PERIOD_MS)); @@ -160,7 +167,7 @@ void AppTask::AppTaskMain(void * pvParameter) ret = sAppTask.Init(); if (ret != NRF_SUCCESS) { - NRF_LOG_INFO("AppTask.Init() failed"); + NRF_LOG_INFO("AppTask.Init() failed: %s", chip::ErrorStr(ret)); APP_ERROR_HANDLER(ret); } @@ -270,9 +277,24 @@ void AppTask::LockActionEventHandler(AppEvent * aEvent) } } +#if CHIP_ENABLE_OPENTHREAD +void AppTask::JoinHandler(AppEvent * aEvent) +{ + if (aEvent->ButtonEvent.PinNo != JOIN_BUTTON) + return; + + CHIP_ERROR error = ThreadStackMgr().JoinerStart(); + NRF_LOG_INFO("Thread joiner triggered: %s", chip::ErrorStr(error)); +} +#endif + void AppTask::ButtonEventHandler(uint8_t pin_no, uint8_t button_action) { - if (pin_no != LOCK_BUTTON && pin_no != FUNCTION_BUTTON) + if (pin_no != LOCK_BUTTON +#if CHIP_ENABLE_OPENTHREAD + && pin_no != JOIN_BUTTON +#endif + && pin_no != FUNCTION_BUTTON) { return; } @@ -290,6 +312,12 @@ void AppTask::ButtonEventHandler(uint8_t pin_no, uint8_t button_action) { button_event.Handler = FunctionHandler; } +#if CHIP_ENABLE_OPENTHREAD + else if (pin_no == JOIN_BUTTON && button_action == APP_BUTTON_RELEASE) + { + button_event.Handler = JoinHandler; + } +#endif sAppTask.PostEvent(&button_event); } diff --git a/examples/lock-app/nrf5/main/include/AppTask.h b/examples/lock-app/nrf5/main/include/AppTask.h index ae0e4b16688a25..27c8e0b1562466 100644 --- a/examples/lock-app/nrf5/main/include/AppTask.h +++ b/examples/lock-app/nrf5/main/include/AppTask.h @@ -52,6 +52,7 @@ class AppTask static void FunctionTimerEventHandler(AppEvent * aEvent); static void FunctionHandler(AppEvent * aEvent); + static void JoinHandler(AppEvent * aEvent); static void LockActionEventHandler(AppEvent * aEvent); static void ButtonEventHandler(uint8_t pin_no, uint8_t button_action); diff --git a/examples/lock-app/nrf5/main/include/app_config.h b/examples/lock-app/nrf5/main/include/app_config.h index 2f7403a579ff90..bd4a555ccb879e 100644 --- a/examples/lock-app/nrf5/main/include/app_config.h +++ b/examples/lock-app/nrf5/main/include/app_config.h @@ -113,7 +113,7 @@ #define BUTTON_ENABLED 1 #define GPIOTE_ENABLED 1 -#define GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS 2 +#define GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS 3 #define APP_TIMER_CONFIG_OP_QUEUE_SIZE 10 @@ -121,6 +121,7 @@ #define LOCK_BUTTON BUTTON_2 #define FUNCTION_BUTTON BUTTON_1 +#define JOIN_BUTTON BUTTON_4 #define FUNCTION_BUTTON_DEBOUNCE_PERIOD_MS 50 #define SYSTEM_STATE_LED BSP_LED_0 diff --git a/src/include/platform/ThreadStackManager.h b/src/include/platform/ThreadStackManager.h index 2bdbb3e1a9410a..8bf58c72d15b89 100644 --- a/src/include/platform/ThreadStackManager.h +++ b/src/include/platform/ThreadStackManager.h @@ -73,6 +73,8 @@ class ThreadStackManager CHIP_ERROR GetAndLogThreadTopologyFull(void); CHIP_ERROR GetPrimary802154MACAddress(uint8_t * buf); + CHIP_ERROR JoinerStart(void); + private: // ===== Members for internal use by the following friends. @@ -295,6 +297,11 @@ inline CHIP_ERROR ThreadStackManager::GetPrimary802154MACAddress(uint8_t * buf) return static_cast(this)->_GetPrimary802154MACAddress(buf); } +inline CHIP_ERROR ThreadStackManager::JoinerStart(void) +{ + return static_cast(this)->_JoinerStart(); +} + } // namespace DeviceLayer } // namespace chip diff --git a/src/include/platform/internal/GenericConfigurationManagerImpl.ipp b/src/include/platform/internal/GenericConfigurationManagerImpl.ipp index 749018b7595d82..02d1746dc2ff91 100644 --- a/src/include/platform/internal/GenericConfigurationManagerImpl.ipp +++ b/src/include/platform/internal/GenericConfigurationManagerImpl.ipp @@ -551,14 +551,14 @@ CHIP_ERROR GenericConfigurationManagerImpl::_GetSetupPinCode(uint32_t CHIP_ERROR err; err = Impl()->ReadConfigValue(ImplClass::kConfigKey_SetupPinCode, setupPinCode); -#ifdef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE - if (CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE != 0 && err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) +#if defined(CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE) && CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE + if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) { setupPinCode = CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE; - ChipLogProgress(DeviceLayer, "Pairing code not found; using default: %08u", CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE); + ChipLogProgress(DeviceLayer, "Setup PIN code not found; using default: %08u", CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE); err = CHIP_NO_ERROR; } -#endif // CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE +#endif // defined(CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE) && CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE SuccessOrExit(err); exit: @@ -577,15 +577,15 @@ CHIP_ERROR GenericConfigurationManagerImpl::_GetSetupDiscriminator(ui CHIP_ERROR err; err = Impl()->ReadConfigValue(ImplClass::kConfigKey_SetupDiscriminator, setupDiscriminator); -#ifdef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR - if (CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR != 0 && err == CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR) +#if defined(CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR) && CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR + if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) { setupDiscriminator = CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR; - ChipLogProgress(DeviceLayer, "Pairing code not found; using default: %03x", + ChipLogProgress(DeviceLayer, "Setup PIN discriminator not found; using default: %03x", CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR); err = CHIP_NO_ERROR; } -#endif // CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR +#endif // defined(CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR) && CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR SuccessOrExit(err); exit: diff --git a/src/platform/Linux/ThreadStackManagerImpl.cpp b/src/platform/Linux/ThreadStackManagerImpl.cpp index ae7023357fe2a7..791244f89ea0ca 100644 --- a/src/platform/Linux/ThreadStackManagerImpl.cpp +++ b/src/platform/Linux/ThreadStackManagerImpl.cpp @@ -411,6 +411,11 @@ CHIP_ERROR ThreadStackManagerImpl::_GetPrimary802154MACAddress(uint8_t * buf) return OTBR_TO_CHIP_ERROR(error); } +CHIP_ERROR ThreadStackManagerImpl::_JoinerStart(void) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + // TODO: Implement after we decide on the dbus message loop extern ThreadStackManager & ThreadStackMgr(void); diff --git a/src/platform/Linux/ThreadStackManagerImpl.h b/src/platform/Linux/ThreadStackManagerImpl.h index ce147c21ca0772..4a16a5bf64ed07 100644 --- a/src/platform/Linux/ThreadStackManagerImpl.h +++ b/src/platform/Linux/ThreadStackManagerImpl.h @@ -84,6 +84,8 @@ class ThreadStackManagerImpl : public ThreadStackManager CHIP_ERROR _GetPrimary802154MACAddress(uint8_t * buf); + CHIP_ERROR _JoinerStart(void); + ~ThreadStackManagerImpl() = default; private: diff --git a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.h b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.h index a8c55d726446a3..c05af98ca0f89d 100644 --- a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.h +++ b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.h @@ -90,12 +90,17 @@ class GenericThreadStackManagerImpl_OpenThread bool IsThreadAttachedNoLock(void); CHIP_ERROR AdjustPollingInterval(void); + CHIP_ERROR _JoinerStart(void); + private: // ===== Private members for use by this class only. otInstance * mOTInst; ConnectivityManager::ThreadPollingConfig mPollingConfig; + static void OnJoinerComplete(otError aError, void * aContext); + void OnJoinerComplete(otError aError); + inline ImplClass * Impl() { return static_cast(this); } }; diff --git a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.ipp b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.ipp index eaad08c5bb726e..eaf207364ec635 100644 --- a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.ipp +++ b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.ipp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -875,6 +876,72 @@ void GenericThreadStackManagerImpl_OpenThread::_ErasePersistentInfo(v Impl()->UnlockThreadStack(); } +template +void GenericThreadStackManagerImpl_OpenThread::OnJoinerComplete(otError aError, void * aContext) +{ + static_cast(aContext)->OnJoinerComplete(aError); +} + +template +void GenericThreadStackManagerImpl_OpenThread::OnJoinerComplete(otError aError) +{ + ChipLogProgress(DeviceLayer, "Join Thread network: %s", otThreadErrorToString(aError)); + + if (aError == OT_ERROR_NONE) + { + otError error = otThreadSetEnabled(mOTInst, true); + + ChipLogProgress(DeviceLayer, "Start Thread network: %s", otThreadErrorToString(error)); + } +} + +template +CHIP_ERROR GenericThreadStackManagerImpl_OpenThread::_JoinerStart(void) +{ + CHIP_ERROR error = CHIP_NO_ERROR; + + Impl()->LockThreadStack(); + VerifyOrExit(!otDatasetIsCommissioned(mOTInst) && otThreadGetDeviceRole(mOTInst) == OT_DEVICE_ROLE_DISABLED, + error = MapOpenThreadError(OT_ERROR_INVALID_STATE)); + VerifyOrExit(otJoinerGetState(mOTInst) == OT_JOINER_STATE_IDLE, error = MapOpenThreadError(OT_ERROR_BUSY)); + + if (!otIp6IsEnabled(mOTInst)) + { + SuccessOrExit(error = MapOpenThreadError(otIp6SetEnabled(mOTInst, true))); + } + + { + otJoinerDiscerner discerner; + uint32_t discriminator; + + SuccessOrExit(error = ConfigurationMgr().GetSetupDiscriminator(discriminator)); + discerner.mLength = 12; + discerner.mValue = discriminator; + + ChipLogProgress(DeviceLayer, "Joiner Discerner: %u", discriminator); + otJoinerSetDiscerner(mOTInst, &discerner); + } + + { + otJoinerPskd pskd; + uint32_t pincode; + + SuccessOrExit(error = ConfigurationMgr().GetSetupPinCode(pincode)); + snprintf(pskd.m8, sizeof(pskd.m8) - 1, "%u", pincode); + + ChipLogProgress(DeviceLayer, "Joiner PSKd: %u", pincode); + error = MapOpenThreadError(otJoinerStart(mOTInst, pskd.m8, NULL, NULL, NULL, NULL, NULL, + &GenericThreadStackManagerImpl_OpenThread::OnJoinerComplete, this)); + } + +exit: + Impl()->UnlockThreadStack(); + + ChipLogProgress(DeviceLayer, "Joiner start: %s", chip::ErrorStr(error)); + + return error; +} + } // namespace Internal } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread_LwIP.ipp b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread_LwIP.ipp index 60aeee10b141ab..17199c63d819ca 100644 --- a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread_LwIP.ipp +++ b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread_LwIP.ipp @@ -70,6 +70,9 @@ CHIP_ERROR GenericThreadStackManagerImpl_OpenThread_LwIP::DoInit(otIn // Initialize member data. memset(mAddrAssigned, 0, sizeof(mAddrAssigned)); + sThreadNetIf.name[0] = 'o'; + sThreadNetIf.name[1] = 't'; + // Initialize the base class. err = GenericThreadStackManagerImpl_OpenThread::DoInit(otInst); SuccessOrExit(err); diff --git a/src/platform/nRF5/CHIPDevicePlatformConfig.h b/src/platform/nRF5/CHIPDevicePlatformConfig.h index 72121484ad5526..2bcd9ff4d7db53 100644 --- a/src/platform/nRF5/CHIPDevicePlatformConfig.h +++ b/src/platform/nRF5/CHIPDevicePlatformConfig.h @@ -78,11 +78,11 @@ // ========== Platform-specific Configuration Overrides ========= #ifndef CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE -#define CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE 8192 +#define CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE 4096 #endif // CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE #ifndef CHIP_DEVICE_CONFIG_THREAD_TASK_STACK_SIZE -#define CHIP_DEVICE_CONFIG_THREAD_TASK_STACK_SIZE 8192 +#define CHIP_DEVICE_CONFIG_THREAD_TASK_STACK_SIZE 4096 #endif // CHIP_DEVICE_CONFIG_THREAD_TASK_STACK_SIZE #define CHIP_DEVICE_CONFIG_ENABLE_WIFI_TELEMETRY 0 diff --git a/third_party/openthread/repo b/third_party/openthread/repo index 5e9b2818eb9811..ac86fe52e62e60 160000 --- a/third_party/openthread/repo +++ b/third_party/openthread/repo @@ -1 +1 @@ -Subproject commit 5e9b2818eb9811b957f74ba8ad64f00fb62e8ea0 +Subproject commit ac86fe52e62e60a66aeeb1c905cb1294709147e9