From 934efbdf694c34ee015dacf353bd37282c991389 Mon Sep 17 00:00:00 2001 From: Jonathan Hui Date: Wed, 17 Apr 2019 14:32:17 -0700 Subject: [PATCH] [dataset] add API to create new dataset for forming a network (#3825) --- examples/drivers/windows/otApi/otApi.cpp | 14 ++++++++ include/openthread/dataset_ftd.h | 12 +++++++ src/cli/cli_dataset.cpp | 7 ++++ src/core/api/dataset_ftd_api.cpp | 7 ++++ src/core/meshcop/dataset_manager.hpp | 11 +++++++ src/core/meshcop/dataset_manager_ftd.cpp | 41 ++++++++++++++++++++++++ 6 files changed, 92 insertions(+) diff --git a/examples/drivers/windows/otApi/otApi.cpp b/examples/drivers/windows/otApi/otApi.cpp index 15c3643b1..748f34502 100644 --- a/examples/drivers/windows/otApi/otApi.cpp +++ b/examples/drivers/windows/otApi/otApi.cpp @@ -1414,6 +1414,20 @@ otDatasetSetDelayTimerMinimal( return OT_ERROR_NOT_IMPLEMENTED; } +OTAPI +otError +OTCALL +otDatasetCreateNewNetwork( + _In_ otInstance *aInstance, + _Out_ otOperationalDataset *aDataset + ) +{ + if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS; + // TODO + UNREFERENCED_PARAMETER(aDataset); + return OT_ERROR_NOT_IMPLEMENTED; +} + OTAPI uint32_t OTCALL diff --git a/include/openthread/dataset_ftd.h b/include/openthread/dataset_ftd.h index 454d9b557..6cf9be900 100644 --- a/include/openthread/dataset_ftd.h +++ b/include/openthread/dataset_ftd.h @@ -49,6 +49,18 @@ extern "C" { * */ +/** + * This method creates a new Operational Dataset to use when forming a new network. + * + * @param[in] aInstance A pointer to an OpenThread instance. + * @param[out] aDataset The Operational Dataset. + * + * @retval OT_ERROR_NONE Successfully created a new Operational Dataset. + * @retval OT_ERROR_FAILED Failed to generate random values for new parameters. + * + */ +OTAPI otError OTCALL otDatasetCreateNewNetwork(otInstance *aInstance, otOperationalDataset *aDataset); + /** * Get minimal delay timer. * diff --git a/src/cli/cli_dataset.cpp b/src/cli/cli_dataset.cpp index 936edb660..1d51cb09e 100644 --- a/src/cli/cli_dataset.cpp +++ b/src/cli/cli_dataset.cpp @@ -38,6 +38,7 @@ #include "utils/wrap_string.h" #include +#include #include "cli/cli.hpp" #include "cli/cli_server.hpp" @@ -230,6 +231,12 @@ otError Dataset::ProcessInit(int argc, char *argv[]) { SuccessOrExit(error = otDatasetGetPending(mInterpreter.mInstance, &sDataset)); } +#if OPENTHREAD_FTD + else if (strcmp(argv[0], "new") == 0) + { + SuccessOrExit(error = otDatasetCreateNewNetwork(mInterpreter.mInstance, &sDataset)); + } +#endif else { ExitNow(error = OT_ERROR_INVALID_ARGS); diff --git a/src/core/api/dataset_ftd_api.cpp b/src/core/api/dataset_ftd_api.cpp index 929906193..5303d75a1 100644 --- a/src/core/api/dataset_ftd_api.cpp +++ b/src/core/api/dataset_ftd_api.cpp @@ -42,6 +42,13 @@ using namespace ot; +otError otDatasetCreateNewNetwork(otInstance *aInstance, otOperationalDataset *aDataset) +{ + Instance &instance = *static_cast(aInstance); + + return instance.Get().CreateNewNetwork(*aDataset); +} + uint32_t otDatasetGetDelayTimerMinimal(otInstance *aInstance) { Instance &instance = *static_cast(aInstance); diff --git a/src/core/meshcop/dataset_manager.hpp b/src/core/meshcop/dataset_manager.hpp index 67bd7c663..169d0f8f6 100644 --- a/src/core/meshcop/dataset_manager.hpp +++ b/src/core/meshcop/dataset_manager.hpp @@ -365,6 +365,17 @@ public: #if OPENTHREAD_FTD + /** + * This method creates a new Operational Dataset to use when forming a new network. + * + * @param[out] aDataset The Operational Dataset. + * + * @retval OT_ERROR_NONE Successfully created a new Operational Dataset. + * @retval OT_ERROR_FAILED Failed to generate random values for new parameters. + * + */ + otError CreateNewNetwork(otOperationalDataset &aDataset); + /** * This method starts the Leader functions for maintaining the Active Operational Dataset. * diff --git a/src/core/meshcop/dataset_manager_ftd.cpp b/src/core/meshcop/dataset_manager_ftd.cpp index 00efdeed2..fd0a6e31c 100644 --- a/src/core/meshcop/dataset_manager_ftd.cpp +++ b/src/core/meshcop/dataset_manager_ftd.cpp @@ -317,6 +317,47 @@ exit: } } +otError ActiveDataset::CreateNewNetwork(otOperationalDataset &aDataset) +{ + otError error = OT_ERROR_NONE; + + memset(&aDataset, 0, sizeof(aDataset)); + + aDataset.mActiveTimestamp = 1; + + SuccessOrExit(error = otPlatRandomGetTrue(aDataset.mMasterKey.m8, sizeof(aDataset.mMasterKey))); + SuccessOrExit(error = otPlatRandomGetTrue(aDataset.mPSKc.m8, sizeof(aDataset.mPSKc))); + SuccessOrExit(error = otPlatRandomGetTrue(aDataset.mExtendedPanId.m8, sizeof(aDataset.mExtendedPanId))); + + aDataset.mMeshLocalPrefix.m8[0] = 0xfd; + SuccessOrExit(error = otPlatRandomGetTrue(&aDataset.mMeshLocalPrefix.m8[1], OT_MESH_LOCAL_PREFIX_SIZE - 1)); + + aDataset.mSecurityPolicy.mFlags = Get().GetSecurityPolicyFlags(); + aDataset.mChannelMask = Get().GetSupportedChannelMask().GetMask(); + aDataset.mChannel = Get().GetSupportedChannelMask().ChooseRandomChannel(); + + do + { + aDataset.mPanId = Random::GetUint16(); + } while (aDataset.mPanId == Mac::kPanIdBroadcast); + + snprintf(aDataset.mNetworkName.m8, sizeof(aDataset.mNetworkName), "OpenThread-%04x", aDataset.mPanId); + + aDataset.mComponents.mIsActiveTimestampPresent = true; + aDataset.mComponents.mIsMasterKeyPresent = true; + aDataset.mComponents.mIsNetworkNamePresent = true; + aDataset.mComponents.mIsExtendedPanIdPresent = true; + aDataset.mComponents.mIsMeshLocalPrefixPresent = true; + aDataset.mComponents.mIsPanIdPresent = true; + aDataset.mComponents.mIsChannelPresent = true; + aDataset.mComponents.mIsPSKcPresent = true; + aDataset.mComponents.mIsSecurityPolicyPresent = true; + aDataset.mComponents.mIsChannelMaskPresent = true; + +exit: + return error; +} + otError ActiveDataset::GenerateLocal(void) { otError error = OT_ERROR_NONE;