[settings] define new Settings key for Border Router ID (#8971)

This commit adds new Border Agent functionality that generates and
saves 16 bytes ID in settings.  The ID can be published in the MeshCoP
mDNS service and used by the client to identify a Border Router
device.

A new `otBorderAgentGetId()` API is defined and the ID is generated
the first time this API is called.
This commit is contained in:
Kangping
2023-05-05 10:48:57 -07:00
committed by GitHub
parent 96ea73076e
commit eaa2779047
11 changed files with 192 additions and 4 deletions
+1
View File
@@ -85,6 +85,7 @@ ot_option(OT_BACKBONE_ROUTER OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE "backbone
ot_option(OT_BACKBONE_ROUTER_DUA_NDPROXYING OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE "BBR DUA ND Proxy")
ot_option(OT_BACKBONE_ROUTER_MULTICAST_ROUTING OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE "BBR MR")
ot_option(OT_BORDER_AGENT OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE "border agent")
ot_option(OT_BORDER_AGENT_ID OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE "create and save border agent ID")
ot_option(OT_BORDER_ROUTER OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE "border router")
ot_option(OT_BORDER_ROUTING OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE "border routing")
ot_option(OT_BORDER_ROUTING_COUNTERS OPENTHREAD_CONFIG_IP6_BR_COUNTERS_ENABLE "border routing counters")
+3
View File
@@ -84,6 +84,9 @@ if (openthread_enable_core_config_args) {
# Enable border agent support
openthread_config_border_agent_enable = false
# Enable border agent ID
openthread_config_border_agent_id_enable = false
# Enable border router support
openthread_config_border_router_enable = false
+24
View File
@@ -51,6 +51,12 @@ extern "C" {
*
*/
/**
* The length of Border Agent/Router ID in bytes.
*
*/
#define OT_BORDER_AGENT_ID_LENGTH (16)
/**
* This enumeration defines the Border Agent state.
*
@@ -82,6 +88,24 @@ otBorderAgentState otBorderAgentGetState(otInstance *aInstance);
*/
uint16_t otBorderAgentGetUdpPort(otInstance *aInstance);
/**
* Gets the randomly generated Border Agent ID.
*
* The ID is saved in persistent storage and survives reboots. The typical use case of the ID is to
* be published in the MeshCoP mDNS service as the `id` TXT value for the client to identify this
* Border Router/Agent device.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[out] aId A pointer to buffer to receive the ID.
* @param[inout] aLength Specifies the length of `aId` when used as input and receives the length
* actual ID data copied to `aId` when used as output.
*
* @retval OT_ERROR_INVALID_ARGS If value of `aLength` if smaller than `OT_BORDER_AGENT_ID_LENGTH`.
* @retval OT_ERROR_NONE If successfully retrieved the Border Agent ID.
*
*/
otError otBorderAgentGetId(otInstance *aInstance, uint8_t *aId, uint16_t *aLength);
/**
* @}
*
+1 -1
View File
@@ -53,7 +53,7 @@ extern "C" {
* @note This number versions both OpenThread platform and user APIs.
*
*/
#define OPENTHREAD_API_VERSION (317)
#define OPENTHREAD_API_VERSION (318)
/**
* @addtogroup api-instance
+1
View File
@@ -73,6 +73,7 @@ enum
OT_SETTINGS_KEY_SRP_SERVER_INFO = 0x000d, ///< The SRP server info (UDP port).
OT_SETTINGS_KEY_BR_ULA_PREFIX = 0x000f, ///< BR ULA prefix.
OT_SETTINGS_KEY_BR_ON_LINK_PREFIXES = 0x0010, ///< BR local on-link prefixes.
OT_SETTINGS_KEY_BORDER_AGENT_ID = 0x0011, ///< Unique Border Agent/Router ID.
// Deprecated and reserved key values:
//
+7
View File
@@ -42,6 +42,13 @@
using namespace ot;
#if OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
otError otBorderAgentGetId(otInstance *aInstance, uint8_t *aId, uint16_t *aLength)
{
return AsCoreType(aInstance).Get<MeshCoP::BorderAgent>().GetId(aId, *aLength);
}
#endif
otBorderAgentState otBorderAgentGetState(otInstance *aInstance)
{
return MapEnum(AsCoreType(aInstance).Get<MeshCoP::BorderAgent>().GetState());
+32 -2
View File
@@ -106,6 +106,28 @@ void SettingsBase::SrpServerInfo::Log(Action aAction) const
}
#endif
#if OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
Error SettingsBase::BorderAgentId::SetId(const uint8_t *aId, uint16_t aLength)
{
Error error = kErrorNone;
VerifyOrExit(aLength == sizeof(mId), error = kErrorInvalidArgs);
memcpy(mId, aId, aLength);
exit:
return error;
}
void SettingsBase::BorderAgentId::Log(Action aAction) const
{
char buffer[sizeof(BorderAgentId) * 2 + 1];
StringWriter sw(buffer, sizeof(buffer));
sw.AppendHexBytes(GetId(), sizeof(BorderAgentId));
LogInfo("%s BorderAgentId {id:%s}", ActionToString(aAction), buffer);
}
#endif // OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
#endif // OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
@@ -157,7 +179,8 @@ const char *SettingsBase::KeyToString(Key aKey)
"SrpServerInfo", // (13) kKeySrpServerInfo
"", // (14) Removed (previously NAT64 prefix)
"BrUlaPrefix", // (15) kKeyBrUlaPrefix
"BrOnLinkPrefixes" // (16) kKeyBrOnLinkPrefixes
"BrOnLinkPrefixes", // (16) kKeyBrOnLinkPrefixes
"BorderAgentId" // (17) kKeyBorderAgentId
};
static_assert(1 == kKeyActiveDataset, "kKeyActiveDataset value is incorrect");
@@ -172,8 +195,9 @@ const char *SettingsBase::KeyToString(Key aKey)
static_assert(13 == kKeySrpServerInfo, "kKeySrpServerInfo value is incorrect");
static_assert(15 == kKeyBrUlaPrefix, "kKeyBrUlaPrefix value is incorrect");
static_assert(16 == kKeyBrOnLinkPrefixes, "kKeyBrOnLinkPrefixes is incorrect");
static_assert(17 == kKeyBorderAgentId, "kKeyBorderAgentId is incorrect");
static_assert(kLastKey == kKeyBrOnLinkPrefixes, "kLastKey is not valid");
static_assert(kLastKey == kKeyBorderAgentId, "kLastKey is not valid");
OT_ASSERT(aKey <= kLastKey);
@@ -518,6 +542,12 @@ void Settings::Log(Action aAction, Error aError, Key aKey, const void *aValue)
break;
#endif
#if OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
case kKeyBorderAgentId:
reinterpret_cast<const BorderAgentId *>(aValue)->Log(aAction);
break;
#endif
default:
// For any other keys, we do not want to include the value
// in the log, so even if it is given we set `aValue` to
+55 -1
View File
@@ -47,6 +47,7 @@
#include "common/settings_driver.hpp"
#include "crypto/ecdsa.hpp"
#include "mac/mac_types.hpp"
#include "meshcop/border_agent.hpp"
#include "meshcop/dataset.hpp"
#include "net/ip6_address.hpp"
#include "thread/version.hpp"
@@ -120,9 +121,10 @@ public:
kKeySrpServerInfo = OT_SETTINGS_KEY_SRP_SERVER_INFO,
kKeyBrUlaPrefix = OT_SETTINGS_KEY_BR_ULA_PREFIX,
kKeyBrOnLinkPrefixes = OT_SETTINGS_KEY_BR_ON_LINK_PREFIXES,
kKeyBorderAgentId = OT_SETTINGS_KEY_BORDER_AGENT_ID,
};
static constexpr Key kLastKey = kKeyBrOnLinkPrefixes; ///< The last (numerically) enumerator value in `Key`.
static constexpr Key kLastKey = kKeyBorderAgentId; ///< The last (numerically) enumerator value in `Key`.
static_assert(static_cast<uint16_t>(kLastKey) < static_cast<uint16_t>(OT_SETTINGS_KEY_VENDOR_RESERVED_MIN),
"Core settings keys overlap with vendor reserved keys");
@@ -765,6 +767,58 @@ public:
} OT_TOOL_PACKED_END;
#endif // OPENTHREAD_CONFIG_SRP_SERVER_ENABLE && OPENTHREAD_CONFIG_SRP_SERVER_PORT_SWITCH_ENABLE
#if OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
/**
* This structure represents the Border Agent ID.
*
*/
OT_TOOL_PACKED_BEGIN
class BorderAgentId : private Clearable<BorderAgentId>
{
friend class Settings;
friend class Clearable<BorderAgentId>;
public:
static constexpr Key kKey = kKeyBorderAgentId; ///< The associated key.
/**
* This method initializes the `BorderAgentId` object.
*
*/
void Init(void) { Clear(); }
/**
* This method returns the Border Agent ID.
*
* @returns The Border Agent ID.
*
*/
const uint8_t *GetId(void) const { return mId; }
/**
* This method returns the Border Agent ID.
*
* @returns The Border Agent ID.
*
*/
uint8_t *GetId(void) { return mId; }
/**
* This method sets the Border Agent ID.
*
* @retval kErrorInvalidArgs If `aLength` doesn't equal to `OT_BORDER_AGENT_ID_LENGTH`.
* @retval kErrorNone If success.
*
*/
Error SetId(const uint8_t *aId, uint16_t aLength);
private:
void Log(Action aAction) const;
uint8_t mId[MeshCoP::BorderAgent::kIdLength];
} OT_TOOL_PACKED_END;
#endif // OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
protected:
explicit SettingsBase(Instance &aInstance)
: InstanceLocator(aInstance)
+10
View File
@@ -55,4 +55,14 @@
#define OPENTHREAD_CONFIG_BORDER_AGENT_UDP_PORT 0
#endif
/**
* @def OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
*
* Define ro 1 to enable Border Agent ID support.
*
*/
#ifndef OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
#define OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE 0
#endif
#endif // CONFIG_BORDER_AGENT_H_
+31
View File
@@ -225,10 +225,41 @@ BorderAgent::BorderAgent(Instance &aInstance)
, mTimer(aInstance)
, mState(kStateStopped)
, mUdpProxyPort(0)
#if OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
, mIdInitialized(false)
#endif
{
mCommissionerAloc.InitAsThreadOriginRealmLocalScope();
}
#if OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
Error BorderAgent::GetId(uint8_t *aId, uint16_t &aLength)
{
Error error = kErrorNone;
static_assert(sizeof(mId) == kIdLength, "Invalid Border Agent ID size");
VerifyOrExit(aLength >= sizeof(mId), error = kErrorInvalidArgs);
VerifyOrExit(!mIdInitialized, error = kErrorNone);
if (Get<Settings>().Read(mId) != kErrorNone)
{
Random::NonCrypto::FillBuffer(mId.GetId(), sizeof(mId));
SuccessOrExit(error = Get<Settings>().Save(mId));
}
mIdInitialized = true;
exit:
if (error == kErrorNone)
{
memcpy(aId, mId.GetId(), sizeof(mId));
aLength = static_cast<uint16_t>(sizeof(mId));
}
return error;
}
#endif // OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
void BorderAgent::HandleNotifierEvents(Events aEvents)
{
VerifyOrExit(aEvents.ContainsAny(kEventThreadRoleChanged | kEventCommissionerStateChanged));
+27
View File
@@ -59,6 +59,10 @@ class BorderAgent : public InstanceLocator, private NonCopyable
friend class Tmf::SecureAgent;
public:
#if OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
static constexpr uint8_t kIdLength = OT_BORDER_AGENT_ID_LENGTH;
#endif
/**
* This enumeration defines the Border Agent state.
*
@@ -78,6 +82,25 @@ public:
*/
explicit BorderAgent(Instance &aInstance);
#if OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
/**
* Gets the randomly generated Border Agent ID.
*
* The ID is saved in persistent storage and survives reboots. The typical use case of the ID is to
* be published in the MeshCoP mDNS service as the `id` TXT value for the client to identify this
* Border Router/Agent device.
*
* @param[out] aId A pointer to buffer to receive the ID.
* @param[inout] aLength Specifies the length of `aId` when used as input and receives the length
* actual ID data copied to `aId` when used as output.
*
* @retval OT_ERROR_INVALID_ARGS If value of `aLength` if smaller than `OT_BORDER_AGENT_ID_LENGTH`.
* @retval OT_ERROR_NONE If successfully retrieved the Border Agent ID.
*
*/
Error GetId(uint8_t *aId, uint16_t &aLength);
#endif
/**
* This method gets the UDP port of this service.
*
@@ -178,6 +201,10 @@ private:
TimeoutTimer mTimer;
State mState;
uint16_t mUdpProxyPort;
#if OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE
Settings::BorderAgentId mId;
bool mIdInitialized;
#endif
};
DeclareTmfHandler(BorderAgent, kUriRelayRx);