mirror of
https://github.com/espressif/openthread.git
synced 2026-08-17 07:59:51 +00:00
[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:
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
//
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user