mirror of
https://github.com/espressif/openthread.git
synced 2026-08-10 12:47:47 +00:00
[meshcop] introduce new public APIs for SteeringData (#12148)
This commit introduces a set of public APIs to allow manipulation of `otSteeringData`. The new APIs are provided when the configuration `OPENTHREAD_CONFIG_MESHCOP_STEERING_DATA_API_ENABLE` is enabled. The internal `SteeringData` is also improved to enhance robustness. Methods such as `Init()`, `UpdateBloomFilter()` now return an `Error` to signal failures on invalid arguments (e.g., invalid length) instead of asserting.
This commit is contained in:
@@ -129,6 +129,7 @@
|
||||
* @defgroup api-thread-router Router/Leader
|
||||
* @brief This module includes functions for Thread Routers and Leaders.
|
||||
* @defgroup api-server Server
|
||||
* @defgroup api-steering-data Steering Data
|
||||
*
|
||||
* @}
|
||||
*
|
||||
|
||||
@@ -260,6 +260,7 @@ ot_option(OT_SRP_ADV_PROXY OPENTHREAD_CONFIG_SRP_SERVER_ADVERTISING_PROXY_ENABLE
|
||||
ot_option(OT_SRP_CLIENT OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE "SRP client")
|
||||
ot_option(OT_SRP_SERVER OPENTHREAD_CONFIG_SRP_SERVER_ENABLE "SRP server")
|
||||
ot_option(OT_SRP_SERVER_FAST_START_MODE OPENTHREAD_CONFIG_SRP_SERVER_FAST_START_MODE_ENABLE "SRP server fast start")
|
||||
ot_option(OT_STEERING_DATA OPENTHREAD_CONFIG_MESHCOP_STEERING_DATA_API_ENABLE, "MeshCoP Steering Data APIs")
|
||||
ot_option(OT_TCP OPENTHREAD_CONFIG_TCP_ENABLE "TCP")
|
||||
ot_option(OT_TIME_SYNC OPENTHREAD_CONFIG_TIME_SYNC_ENABLE "time synchronization service")
|
||||
ot_option(OT_TREL OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE "TREL radio link for Thread over Infrastructure feature")
|
||||
|
||||
@@ -124,6 +124,7 @@ source_set("openthread") {
|
||||
"srp_client.h",
|
||||
"srp_client_buffers.h",
|
||||
"srp_server.h",
|
||||
"steering_data.h",
|
||||
"tasklet.h",
|
||||
"tcat.h",
|
||||
"tcp.h",
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include <openthread/instance.h>
|
||||
#include <openthread/ip6.h>
|
||||
#include <openthread/joiner.h>
|
||||
#include <openthread/steering_data.h>
|
||||
#include <openthread/platform/radio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -84,17 +85,6 @@ typedef enum otCommissionerJoinerEvent
|
||||
|
||||
#define OT_PROVISIONING_URL_MAX_SIZE 64 ///< Max size (number of chars) in Provisioning URL string (excludes null char).
|
||||
|
||||
#define OT_STEERING_DATA_MAX_LENGTH 16 ///< Max steering data length (bytes)
|
||||
|
||||
/**
|
||||
* Represents the steering data.
|
||||
*/
|
||||
typedef struct otSteeringData
|
||||
{
|
||||
uint8_t mLength; ///< Length of steering data (bytes)
|
||||
uint8_t m8[OT_STEERING_DATA_MAX_LENGTH]; ///< Byte values
|
||||
} otSteeringData;
|
||||
|
||||
/**
|
||||
* Represents a Commissioning Dataset.
|
||||
*/
|
||||
|
||||
@@ -52,7 +52,7 @@ extern "C" {
|
||||
*
|
||||
* @note This number versions both OpenThread platform and user APIs.
|
||||
*/
|
||||
#define OPENTHREAD_API_VERSION (554)
|
||||
#define OPENTHREAD_API_VERSION (555)
|
||||
|
||||
/**
|
||||
* @addtogroup api-instance
|
||||
|
||||
@@ -38,10 +38,10 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <openthread/commissioner.h>
|
||||
#include <openthread/dataset.h>
|
||||
#include <openthread/error.h>
|
||||
#include <openthread/instance.h>
|
||||
#include <openthread/steering_data.h>
|
||||
#include <openthread/platform/radio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright (c) 2025, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief This file defines the OpenThread MeshCoP Steering Data APIs.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef OPENTHREAD_STEERING_DATA_H_
|
||||
#define OPENTHREAD_STEERING_DATA_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <openthread/error.h>
|
||||
#include <openthread/joiner.h>
|
||||
#include <openthread/platform/radio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @addtogroup api-steering-data
|
||||
*
|
||||
* @brief
|
||||
* This module includes helper functions for the MeshCoP Steering Data.
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* All the functions in this header require `OPENTHREAD_CONFIG_MESHCOP_STEERING_DATA_API_ENABLE` to be enabled.
|
||||
*/
|
||||
|
||||
#define OT_STEERING_DATA_MIN_LENGTH 1 ///< Min Steering Data length (bytes)
|
||||
|
||||
#define OT_STEERING_DATA_MAX_LENGTH 16 ///< Max Steering Data length (bytes)
|
||||
|
||||
/**
|
||||
* Represents the steering data.
|
||||
*/
|
||||
typedef struct otSteeringData
|
||||
{
|
||||
uint8_t mLength; ///< Length of Steering Data (bytes).
|
||||
uint8_t m8[OT_STEERING_DATA_MAX_LENGTH]; ///< Byte values.
|
||||
} otSteeringData;
|
||||
|
||||
/**
|
||||
* Initializes the Steering Data.
|
||||
*
|
||||
* @param[out] aSteeringData The Steering Data to initialize.
|
||||
* @param[in] aLength The length of the Steering Data in bytes.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully initialized the Steering Data.
|
||||
* @retval OT_ERROR_INVALID_ARGS The @p aLength is invalid.
|
||||
*/
|
||||
otError otSteeringDataInit(otSteeringData *aSteeringData, uint8_t aLength);
|
||||
|
||||
/**
|
||||
* Checks whether the Steering Data has a valid length.
|
||||
*
|
||||
* @param[in] aSteeringData The Steering Data to check.
|
||||
*
|
||||
* @retval TRUE If the Steering Data's length is valid.
|
||||
* @retval FALSE If the Steering Data's length is not valid.
|
||||
*/
|
||||
bool otSteeringDataIsValid(const otSteeringData *aSteeringData);
|
||||
|
||||
/**
|
||||
* Sets the Steering Data to permit all joiners.
|
||||
*
|
||||
* @param[out] aSteeringData The Steering Data to update.
|
||||
*/
|
||||
void otSteeringDataSetToPermitAllJoiners(otSteeringData *aSteeringData);
|
||||
|
||||
/**
|
||||
* Updates the Steering Data's bloom filter with a Joiner ID.
|
||||
*
|
||||
* @param[out] aSteeringData The Steering Data to update.
|
||||
* @param[in] aJoinerId The Joiner ID to add.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully updated the Steering Data.
|
||||
* @retval OT_ERROR_INVALID_ARGS The Steering Data is not valid (incorrect length).
|
||||
*/
|
||||
otError otSteeringDataUpdateWithJoinerId(otSteeringData *aSteeringData, const otExtAddress *aJoinerId);
|
||||
|
||||
/**
|
||||
* Updates the Steering Data's bloom filter with a Joiner Discerner.
|
||||
*
|
||||
* @param[out] aSteeringData The Steering Data to update
|
||||
* @param[in] aDiscerner The Joiner Discerner to add.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully updated the Steering Data.
|
||||
* @retval OT_ERROR_INVALID_ARGS The Steering Data is not valid (incorrect length).
|
||||
*/
|
||||
otError otSteeringDataUpdateWithDiscerner(otSteeringData *aSteeringData, const otJoinerDiscerner *aDiscerner);
|
||||
|
||||
/**
|
||||
* Merges two Steering Data bloom filters.
|
||||
*
|
||||
* The @p aOtherSteeringData must have a length that is a divisor of the @p aSteeringData length.
|
||||
*
|
||||
* @param[out] aSteeringData The Steering Data to merge into.
|
||||
* @param[in] aOtherSteeringData The other Steering Data to merge from.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully merged the Steering Data.
|
||||
* @retval OT_ERROR_INVALID_ARGS The Steering Data lengths are not valid or they cannot be merged.
|
||||
*/
|
||||
otError otSteeringDataMerge(otSteeringData *aSteeringData, const otSteeringData *aOtherSteeringData);
|
||||
|
||||
/**
|
||||
* Checks if the Steering Data permits all joiners.
|
||||
*
|
||||
* @param[in] aSteeringData The Steering Data to check.
|
||||
*
|
||||
* @retval TRUE If the Steering Data permits all joiners.
|
||||
* @retval FALSE If the Steering Data does not permit all joiners.
|
||||
*/
|
||||
bool otSteeringDataPermitsAllJoiners(const otSteeringData *aSteeringData);
|
||||
|
||||
/**
|
||||
* Checks if the Steering Data is empty.
|
||||
*
|
||||
* @param[in] aSteeringData The Steering Data to check.
|
||||
*
|
||||
* @retval TRUE If the Steering Data is empty.
|
||||
* @retval FALSE If the Steering Data is not empty.
|
||||
*/
|
||||
bool otSteeringDataIsEmpty(const otSteeringData *aSteeringData);
|
||||
|
||||
/**
|
||||
* Checks if the Steering Data contains a Joiner ID.
|
||||
*
|
||||
* @param[in] aSteeringData The Steering Data to check.
|
||||
* @param[in] aJoinerId The Joiner ID.
|
||||
*
|
||||
* @retval TRUE If the Steering Data contains the Joiner ID.
|
||||
* @retval FALSE If the Steering Data does not contain the Joiner ID.
|
||||
*/
|
||||
bool otSteeringDataContainsJoinerId(const otSteeringData *aSteeringData, const otExtAddress *aJoinerId);
|
||||
|
||||
/**
|
||||
* Checks if the Steering Data contains a Joiner Discerner.
|
||||
*
|
||||
* @param[in] aSteeringData The Steering Data to check.
|
||||
* @param[in] aDiscerner The Joiner Discerner.
|
||||
*
|
||||
* @retval TRUE If the Steering Data contains the Joiner Discerner.
|
||||
* @retval FALSE If the Steering Data does not contain the Joiner Discerner.
|
||||
*/
|
||||
bool otSteeringDataContainsDiscerner(const otSteeringData *aSteeringData, const otJoinerDiscerner *aDiscerner);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // OPENTHREAD_STEERING_DATA_H_
|
||||
@@ -214,6 +214,7 @@ openthread_core_files = [
|
||||
"api/srp_client_api.cpp",
|
||||
"api/srp_client_buffers_api.cpp",
|
||||
"api/srp_server_api.cpp",
|
||||
"api/steering_data_api.cpp",
|
||||
"api/tasklet_api.cpp",
|
||||
"api/tcp_api.cpp",
|
||||
"api/tcp_ext_api.cpp",
|
||||
|
||||
@@ -84,6 +84,7 @@ set(COMMON_SOURCES
|
||||
api/srp_client_api.cpp
|
||||
api/srp_client_buffers_api.cpp
|
||||
api/srp_server_api.cpp
|
||||
api/steering_data_api.cpp
|
||||
api/tasklet_api.cpp
|
||||
api/tcp_api.cpp
|
||||
api/tcp_ext_api.cpp
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2025, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief This file implements the OpenThread MeshCoP helper API.
|
||||
*/
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#include <openthread/steering_data.h>
|
||||
|
||||
#include "meshcop/meshcop.hpp"
|
||||
|
||||
using namespace ot;
|
||||
|
||||
#if OPENTHREAD_CONFIG_MESHCOP_STEERING_DATA_API_ENABLE
|
||||
|
||||
otError otSteeringDataInit(otSteeringData *aSteeringData, uint8_t aLength)
|
||||
{
|
||||
return AsCoreType(aSteeringData).Init(aLength);
|
||||
}
|
||||
|
||||
bool otSteeringDataIsValid(const otSteeringData *aSteeringData) { return AsCoreType(aSteeringData).IsValid(); }
|
||||
|
||||
void otSteeringDataSetToPermitAllJoiners(otSteeringData *aSteeringData)
|
||||
{
|
||||
AsCoreType(aSteeringData).SetToPermitAllJoiners();
|
||||
}
|
||||
|
||||
otError otSteeringDataUpdateWithJoinerId(otSteeringData *aSteeringData, const otExtAddress *aJoinerId)
|
||||
{
|
||||
return AsCoreType(aSteeringData).UpdateBloomFilter(AsCoreType(aJoinerId));
|
||||
}
|
||||
|
||||
otError otSteeringDataUpdateWithDiscerner(otSteeringData *aSteeringData, const otJoinerDiscerner *aDiscerner)
|
||||
{
|
||||
return AsCoreType(aSteeringData).UpdateBloomFilter(AsCoreType(aDiscerner));
|
||||
}
|
||||
|
||||
otError otSteeringDataMerge(otSteeringData *aSteeringData, const otSteeringData *aOtherSteeringData)
|
||||
{
|
||||
return AsCoreType(aSteeringData).MergeBloomFilterWith(AsCoreType(aOtherSteeringData));
|
||||
}
|
||||
|
||||
bool otSteeringDataPermitsAllJoiners(const otSteeringData *aSteeringData)
|
||||
{
|
||||
return AsCoreType(aSteeringData).PermitsAllJoiners();
|
||||
}
|
||||
|
||||
bool otSteeringDataIsEmpty(const otSteeringData *aSteeringData) { return AsCoreType(aSteeringData).IsEmpty(); }
|
||||
|
||||
bool otSteeringDataContainsJoinerId(const otSteeringData *aSteeringData, const otExtAddress *aJoinerId)
|
||||
{
|
||||
return AsCoreType(aSteeringData).Contains(AsCoreType(aJoinerId));
|
||||
}
|
||||
|
||||
bool otSteeringDataContainsDiscerner(const otSteeringData *aSteeringData, const otJoinerDiscerner *aDiscerner)
|
||||
{
|
||||
return AsCoreType(aSteeringData).Contains(AsCoreType(aDiscerner));
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_MESHCOP_STEERING_DATA_API_ENABLE
|
||||
@@ -310,6 +310,15 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_MESHCOP_STEERING_DATA_API_ENABLE
|
||||
*
|
||||
* Define as 1 to enable the MeshCoP Steering Data public APIs (in `openthread/steering_data.h`).
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_MESHCOP_STEERING_DATA_API_ENABLE
|
||||
#define OPENTHREAD_CONFIG_MESHCOP_STEERING_DATA_API_ENABLE 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE
|
||||
*
|
||||
|
||||
@@ -346,7 +346,7 @@ void Commissioner::ComputeBloomFilter(SteeringData &aSteeringData) const
|
||||
{
|
||||
Mac::ExtAddress joinerId;
|
||||
|
||||
aSteeringData.Init();
|
||||
IgnoreError(aSteeringData.Init(SteeringData::kMaxLength));
|
||||
|
||||
for (const Joiner &joiner : mJoiners)
|
||||
{
|
||||
@@ -357,11 +357,11 @@ void Commissioner::ComputeBloomFilter(SteeringData &aSteeringData) const
|
||||
|
||||
case Joiner::kTypeEui64:
|
||||
ComputeJoinerId(joiner.mSharedId.mEui64, joinerId);
|
||||
aSteeringData.UpdateBloomFilter(joinerId);
|
||||
IgnoreError(aSteeringData.UpdateBloomFilter(joinerId));
|
||||
break;
|
||||
|
||||
case Joiner::kTypeDiscerner:
|
||||
aSteeringData.UpdateBloomFilter(joiner.mSharedId.mDiscerner);
|
||||
IgnoreError(aSteeringData.UpdateBloomFilter(joiner.mSharedId.mDiscerner));
|
||||
break;
|
||||
|
||||
case Joiner::kTypeAny:
|
||||
|
||||
@@ -191,49 +191,73 @@ JoinerDiscerner::InfoString JoinerDiscerner::ToString(void) const
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// SteeringData
|
||||
|
||||
void SteeringData::Init(uint8_t aLength)
|
||||
Error SteeringData::Init(uint8_t aLength)
|
||||
{
|
||||
OT_ASSERT(aLength <= kMaxLength);
|
||||
Error error = kErrorNone;
|
||||
|
||||
VerifyOrExit(IsValueInRange(aLength, kMinLength, kMaxLength), error = kErrorInvalidArgs);
|
||||
|
||||
mLength = aLength;
|
||||
ClearAllBytes(m8);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
Error SteeringData::Init(uint8_t aLength, const uint8_t *aData)
|
||||
{
|
||||
Error error;
|
||||
|
||||
SuccessOrExit(error = Init(aLength));
|
||||
memcpy(m8, aData, mLength);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void SteeringData::SetToPermitAllJoiners(void)
|
||||
{
|
||||
Init(1);
|
||||
IgnoreError(Init(1));
|
||||
m8[0] = kPermitAll;
|
||||
}
|
||||
|
||||
void SteeringData::UpdateBloomFilter(const Mac::ExtAddress &aJoinerId)
|
||||
Error SteeringData::UpdateBloomFilter(const Mac::ExtAddress &aJoinerId)
|
||||
{
|
||||
HashBitIndexes indexes;
|
||||
|
||||
CalculateHashBitIndexes(aJoinerId, indexes);
|
||||
UpdateBloomFilter(indexes);
|
||||
|
||||
return UpdateBloomFilter(indexes);
|
||||
}
|
||||
|
||||
void SteeringData::UpdateBloomFilter(const JoinerDiscerner &aDiscerner)
|
||||
Error SteeringData::UpdateBloomFilter(const JoinerDiscerner &aDiscerner)
|
||||
{
|
||||
HashBitIndexes indexes;
|
||||
|
||||
CalculateHashBitIndexes(aDiscerner, indexes);
|
||||
UpdateBloomFilter(indexes);
|
||||
|
||||
return UpdateBloomFilter(indexes);
|
||||
}
|
||||
|
||||
void SteeringData::UpdateBloomFilter(const HashBitIndexes &aIndexes)
|
||||
Error SteeringData::UpdateBloomFilter(const HashBitIndexes &aIndexes)
|
||||
{
|
||||
OT_ASSERT(IsLengthValid());
|
||||
Error error = kErrorNone;
|
||||
|
||||
VerifyOrExit(IsValid(), error = kErrorInvalidArgs);
|
||||
|
||||
SetBit(aIndexes.mIndex[0] % GetNumBits());
|
||||
SetBit(aIndexes.mIndex[1] % GetNumBits());
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
Error SteeringData::MergeBloomFilterWith(const SteeringData &aOther)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
|
||||
VerifyOrExit(IsLengthValid(), error = kErrorInvalidArgs);
|
||||
VerifyOrExit(aOther.IsLengthValid(), error = kErrorInvalidArgs);
|
||||
VerifyOrExit(IsValid(), error = kErrorInvalidArgs);
|
||||
VerifyOrExit(aOther.IsValid(), error = kErrorInvalidArgs);
|
||||
|
||||
VerifyOrExit(GetLength() % aOther.GetLength() == 0, error = kErrorInvalidArgs);
|
||||
|
||||
@@ -266,7 +290,13 @@ bool SteeringData::Contains(const JoinerDiscerner &aDiscerner) const
|
||||
|
||||
bool SteeringData::Contains(const HashBitIndexes &aIndexes) const
|
||||
{
|
||||
return (mLength > 0) && GetBit(aIndexes.mIndex[0] % GetNumBits()) && GetBit(aIndexes.mIndex[1] % GetNumBits());
|
||||
bool contains = false;
|
||||
|
||||
VerifyOrExit(IsValid());
|
||||
contains = GetBit(aIndexes.mIndex[0] % GetNumBits()) && GetBit(aIndexes.mIndex[1] % GetNumBits());
|
||||
|
||||
exit:
|
||||
return contains;
|
||||
}
|
||||
|
||||
void SteeringData::CalculateHashBitIndexes(const Mac::ExtAddress &aJoinerId, HashBitIndexes &aIndexes)
|
||||
@@ -287,17 +317,21 @@ void SteeringData::CalculateHashBitIndexes(const JoinerDiscerner &aDiscerner, Ha
|
||||
|
||||
bool SteeringData::DoesAllMatch(uint8_t aMatch) const
|
||||
{
|
||||
bool matches = true;
|
||||
bool matches = false;
|
||||
|
||||
VerifyOrExit(IsValid());
|
||||
|
||||
for (uint8_t i = 0; i < mLength; i++)
|
||||
{
|
||||
if (m8[i] != aMatch)
|
||||
{
|
||||
matches = false;
|
||||
break;
|
||||
ExitNow();
|
||||
}
|
||||
}
|
||||
|
||||
matches = true;
|
||||
|
||||
exit:
|
||||
return matches;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,10 +39,12 @@
|
||||
#include <openthread/commissioner.h>
|
||||
#include <openthread/instance.h>
|
||||
#include <openthread/joiner.h>
|
||||
#include <openthread/steering_data.h>
|
||||
|
||||
#include "coap/coap.hpp"
|
||||
#include "common/as_core_type.hpp"
|
||||
#include "common/clearable.hpp"
|
||||
#include "common/code_utils.hpp"
|
||||
#include "common/equatable.hpp"
|
||||
#include "common/log.hpp"
|
||||
#include "common/message.hpp"
|
||||
@@ -230,7 +232,7 @@ private:
|
||||
class SteeringData : public otSteeringData
|
||||
{
|
||||
public:
|
||||
static constexpr uint8_t kMinLength = 1; ///< Minimum Steering Data length (in bytes).
|
||||
static constexpr uint8_t kMinLength = OT_STEERING_DATA_MIN_LENGTH; ///< Minimum Steering Data length (in bytes).
|
||||
static constexpr uint8_t kMaxLength = OT_STEERING_DATA_MAX_LENGTH; ///< Maximum Steering Data length (in bytes).
|
||||
|
||||
static constexpr uint16_t kInfoStringSize = 45; ///< Size of `InfoString` to use with `ToString()`.
|
||||
@@ -255,16 +257,37 @@ public:
|
||||
/**
|
||||
* Initializes the Steering Data and clears the bloom filter.
|
||||
*
|
||||
* @param[in] aLength The Steering Data length (in bytes) - MUST be smaller than or equal to `kMaxLength`.
|
||||
* @param[in] aLength The Steering Data length (in bytes).
|
||||
*
|
||||
* @retval kErrorSuccess Successfully initialized the Steering Data.
|
||||
* @retval kErrorInvalidArgs @p aLength is not valid.
|
||||
*/
|
||||
void Init(uint8_t aLength = kMaxLength);
|
||||
Error Init(uint8_t aLength);
|
||||
|
||||
/**
|
||||
* Initializes the Steering Data.
|
||||
*
|
||||
* @param[in] aLength The Steering Data length (in bytes).
|
||||
* @param[in] aData A pointer to a buffer containing the data bytes.
|
||||
*
|
||||
* @retval kErrorSuccess Successfully initialized the Steering Data.
|
||||
* @retval kErrorInvalidArgs @p aLength is not valid.
|
||||
*/
|
||||
Error Init(uint8_t aLength, const uint8_t *aData);
|
||||
|
||||
/**
|
||||
* Checks whether the Steering Data has a valid length.
|
||||
*
|
||||
* @returns TRUE if the Steering Data's length is valid (within min to max range), FALSE otherwise.
|
||||
*/
|
||||
bool IsValid(void) const { return IsValueInRange(mLength, kMinLength, kMaxLength); }
|
||||
|
||||
/**
|
||||
* Clears the bloom filter (all bits are cleared and no Joiner Id is accepted)..
|
||||
*
|
||||
* The Steering Data length (bloom filter length) is set to one byte with all bits cleared.
|
||||
*/
|
||||
void Clear(void) { Init(1); }
|
||||
void Clear(void) { IgnoreError(Init(1)); }
|
||||
|
||||
/**
|
||||
* Sets the bloom filter to permit all Joiner IDs.
|
||||
@@ -298,15 +321,21 @@ public:
|
||||
* Updates the bloom filter adding the given Joiner ID.
|
||||
*
|
||||
* @param[in] aJoinerId The Joiner ID to add to bloom filter.
|
||||
*
|
||||
* @retval kErrorNone Successfully updated the bloom filter.
|
||||
* @retval kErrorInvalidArgs The Steering Data's length is invalid.
|
||||
*/
|
||||
void UpdateBloomFilter(const Mac::ExtAddress &aJoinerId);
|
||||
Error UpdateBloomFilter(const Mac::ExtAddress &aJoinerId);
|
||||
|
||||
/**
|
||||
* Updates the bloom filter adding a given Joiner Discerner.
|
||||
*
|
||||
* @param[in] aDiscerner The Joiner Discerner to add to bloom filter.
|
||||
*
|
||||
* @retval kErrorNone Successfully updated the bloom filter.
|
||||
* @retval kErrorInvalidArgs The Steering Data's length is invalid.
|
||||
*/
|
||||
void UpdateBloomFilter(const JoinerDiscerner &aDiscerner);
|
||||
Error UpdateBloomFilter(const JoinerDiscerner &aDiscerner);
|
||||
|
||||
/**
|
||||
* Merges the bloom filter by combining it with another steering data filter.
|
||||
@@ -393,7 +422,6 @@ public:
|
||||
private:
|
||||
static constexpr uint8_t kPermitAll = 0xff;
|
||||
|
||||
bool IsLengthValid(void) const { return IsValueInRange(mLength, kMinLength, kMaxLength); }
|
||||
uint8_t GetNumBits(void) const { return (mLength * kBitsPerByte); }
|
||||
|
||||
uint8_t BitIndex(uint8_t aBit) const { return (mLength - 1 - (aBit / kBitsPerByte)); }
|
||||
@@ -403,8 +431,8 @@ private:
|
||||
void SetBit(uint8_t aBit) { m8[BitIndex(aBit)] |= BitFlag(aBit); }
|
||||
void ClearBit(uint8_t aBit) { m8[BitIndex(aBit)] &= ~BitFlag(aBit); }
|
||||
|
||||
bool DoesAllMatch(uint8_t aMatch) const;
|
||||
void UpdateBloomFilter(const HashBitIndexes &aIndexes);
|
||||
bool DoesAllMatch(uint8_t aMatch) const;
|
||||
Error UpdateBloomFilter(const HashBitIndexes &aIndexes);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -60,10 +60,9 @@ void NetworkNameTlv::SetNetworkName(const NameData &aNameData)
|
||||
|
||||
bool NetworkNameTlv::IsValid(void) const { return IsValidUtf8String(mNetworkName, GetLength()); }
|
||||
|
||||
void SteeringDataTlv::CopyTo(SteeringData &aSteeringData) const
|
||||
Error SteeringDataTlv::CopyTo(SteeringData &aSteeringData) const
|
||||
{
|
||||
aSteeringData.Init(GetSteeringDataLength());
|
||||
memcpy(aSteeringData.GetData(), mSteeringData, GetSteeringDataLength());
|
||||
return aSteeringData.Init(GetSteeringDataLength(), mSteeringData);
|
||||
}
|
||||
|
||||
bool SecurityPolicyTlv::IsValid(void) const
|
||||
|
||||
@@ -364,8 +364,11 @@ public:
|
||||
* Copies the Steering Data from the TLV into a given `SteeringData` variable.
|
||||
*
|
||||
* @param[out] aSteeringData A reference to a `SteeringData` to copy into.
|
||||
*
|
||||
* @retval kErrorNone Successfully copied the steering data into @p aSteeringData.
|
||||
* @retval kErrorInvalidArgs The Steering Data TLV length is invalid.
|
||||
*/
|
||||
void CopyTo(SteeringData &aSteeringData) const;
|
||||
Error CopyTo(SteeringData &aSteeringData) const;
|
||||
|
||||
private:
|
||||
uint8_t mSteeringData[OT_STEERING_DATA_MAX_LENGTH];
|
||||
|
||||
@@ -371,7 +371,7 @@ void DiscoverScanner::HandleDiscoveryResponse(Mle::RxInfo &aRxInfo) const
|
||||
OffsetRange valueOffsetRange = tlvInfo.mValueOffsetRange;
|
||||
|
||||
valueOffsetRange.ShrinkLength(MeshCoP::SteeringData::kMaxLength);
|
||||
steeringData.Init(static_cast<uint8_t>(valueOffsetRange.GetLength()));
|
||||
IgnoreError(steeringData.Init(static_cast<uint8_t>(valueOffsetRange.GetLength())));
|
||||
aRxInfo.mMessage.ReadBytes(valueOffsetRange, steeringData.GetData());
|
||||
|
||||
if (mEnableFiltering)
|
||||
|
||||
@@ -2696,9 +2696,9 @@ void Mle::SetSteeringData(const Mac::ExtAddress *aExtAddress)
|
||||
{
|
||||
Mac::ExtAddress joinerId;
|
||||
|
||||
mSteeringData.Init();
|
||||
IgnoreError(mSteeringData.Init(MeshCoP::SteeringData::kMaxLength));
|
||||
MeshCoP::ComputeJoinerId(*aExtAddress, joinerId);
|
||||
mSteeringData.UpdateBloomFilter(joinerId);
|
||||
IgnoreError(mSteeringData.UpdateBloomFilter(joinerId));
|
||||
}
|
||||
}
|
||||
#endif // OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE
|
||||
|
||||
@@ -635,7 +635,7 @@ Error Leader::FindSteeringData(MeshCoP::SteeringData &aSteeringData) const
|
||||
const MeshCoP::SteeringDataTlv *steeringDataTlv = FindInCommissioningData<MeshCoP::SteeringDataTlv>();
|
||||
|
||||
VerifyOrExit(steeringDataTlv != nullptr, error = kErrorNotFound);
|
||||
steeringDataTlv->CopyTo(aSteeringData);
|
||||
error = steeringDataTlv->CopyTo(aSteeringData);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
|
||||
@@ -76,6 +76,8 @@
|
||||
|
||||
#define OPENTHREAD_CONFIG_COMMISSIONER_MAX_JOINER_ENTRIES 4
|
||||
|
||||
#define OPENTHREAD_CONFIG_MESHCOP_STEERING_DATA_API_ENABLE 1
|
||||
|
||||
#define OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE 1
|
||||
|
||||
#define OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE 1
|
||||
|
||||
+12
-13
@@ -31,6 +31,7 @@
|
||||
#include <openthread/config.h>
|
||||
|
||||
#include "test_util.hpp"
|
||||
#include "common/clearable.hpp"
|
||||
#include "meshcop/meshcop.hpp"
|
||||
#include "meshcop/timestamp.hpp"
|
||||
|
||||
@@ -75,7 +76,7 @@ void TestSteeringData(void)
|
||||
{
|
||||
printf("\n--------------------------------------------");
|
||||
|
||||
steeringData.Init(len);
|
||||
SuccessOrQuit(steeringData.Init(len));
|
||||
|
||||
VerifyOrQuit(steeringData.GetLength() == len);
|
||||
VerifyOrQuit(steeringData.IsEmpty());
|
||||
@@ -84,14 +85,14 @@ void TestSteeringData(void)
|
||||
VerifyOrQuit(!steeringData.Contains(joinerId2));
|
||||
VerifyOrQuit(!steeringData.Contains(indexes));
|
||||
|
||||
steeringData.UpdateBloomFilter(joinerId1);
|
||||
SuccessOrQuit(steeringData.UpdateBloomFilter(joinerId1));
|
||||
printf("\nAfter UpdateBloomFilter(joinerId1): %s", steeringData.ToString().AsCString());
|
||||
VerifyOrQuit(steeringData.GetLength() == len);
|
||||
VerifyOrQuit(!steeringData.IsEmpty());
|
||||
VerifyOrQuit(!steeringData.PermitsAllJoiners());
|
||||
VerifyOrQuit(steeringData.Contains(joinerId1));
|
||||
|
||||
steeringData.UpdateBloomFilter(joinerId2);
|
||||
SuccessOrQuit(steeringData.UpdateBloomFilter(joinerId2));
|
||||
printf("\nAfter UpdateBloomFilter(joinerId2): %s", steeringData.ToString().AsCString());
|
||||
VerifyOrQuit(steeringData.GetLength() == len);
|
||||
VerifyOrQuit(!steeringData.IsEmpty());
|
||||
@@ -101,14 +102,12 @@ void TestSteeringData(void)
|
||||
VerifyOrQuit(steeringData.Contains(indexes));
|
||||
}
|
||||
|
||||
steeringData.Init(0);
|
||||
VerifyOrQuit(steeringData.Init(0) == kErrorInvalidArgs);
|
||||
VerifyOrQuit(steeringData.Init(MeshCoP::SteeringData::kMaxLength + 1) == kErrorInvalidArgs);
|
||||
|
||||
ClearAllBytes(steeringData);
|
||||
VerifyOrQuit(steeringData.GetLength() == 0);
|
||||
VerifyOrQuit(steeringData.IsEmpty());
|
||||
VerifyOrQuit(!steeringData.PermitsAllJoiners());
|
||||
VerifyOrQuit(!steeringData.Contains(joinerId1));
|
||||
VerifyOrQuit(!steeringData.Contains(joinerId2));
|
||||
VerifyOrQuit(!steeringData.Contains(indexes));
|
||||
VerifyOrQuit(steeringData.UpdateBloomFilter(joinerId1) == kErrorInvalidArgs);
|
||||
|
||||
printf("TestSteeringData() passed\n");
|
||||
}
|
||||
@@ -161,8 +160,8 @@ void TestSteeringDataBloomFilterMerge(void)
|
||||
printf("\n--------------------------------------------");
|
||||
printf("\nLen:%u OtherLen:%u", length, otherLength);
|
||||
|
||||
steeringData.Init(length);
|
||||
otherSteeringData.Init(otherLength);
|
||||
SuccessOrQuit(steeringData.Init(length));
|
||||
SuccessOrQuit(otherSteeringData.Init(otherLength));
|
||||
|
||||
VerifyOrQuit(steeringData.GetLength() == length);
|
||||
VerifyOrQuit(otherSteeringData.GetLength() == otherLength);
|
||||
@@ -184,13 +183,13 @@ void TestSteeringDataBloomFilterMerge(void)
|
||||
|
||||
for (Mac::ExtAddress &id : joinerIds)
|
||||
{
|
||||
steeringData.UpdateBloomFilter(id);
|
||||
SuccessOrQuit(steeringData.UpdateBloomFilter(id));
|
||||
VerifyOrQuit(steeringData.Contains(id));
|
||||
}
|
||||
|
||||
for (Mac::ExtAddress &id : otherJoinerIds)
|
||||
{
|
||||
otherSteeringData.UpdateBloomFilter(id);
|
||||
SuccessOrQuit(otherSteeringData.UpdateBloomFilter(id));
|
||||
VerifyOrQuit(otherSteeringData.Contains(id));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user