[border-agent] introduce Border Agent TXT Data Parser (#12009)

This commit introduces a new feature to parse the MeshCoP service TXT
data from a Border Agent.

The new API `otBorderAgentTxtDataParse()` allows parsing the raw TXT
data into a structured `otBorderAgentTxtDataInfo` object. This can be
used by applications to inspect the capabilities and status of a
discovered Border Agent.

Config `OPENTHREAD_CONFIG_BORDER_AGENT_TXT_DATA_PARSER_ENABLE` controls
this new feature.

The existing test for the Border Agent is updated to validate the new
parser and its output.
This commit is contained in:
Abtin Keshavarzian
2025-10-22 09:40:18 +08:00
committed by GitHub
parent ecd29ced66
commit ad1cfb749e
14 changed files with 729 additions and 146 deletions
+89 -88
View File
@@ -33,142 +33,143 @@
*/
/**
* @defgroup api API
* @defgroup api API
* @brief
* This module includes the application programming interface to the OpenThread stack.
*
* @{
*
* @defgroup api-error Error
* @defgroup api-error Error
*
* @defgroup api-execution Execution
* @defgroup api-execution Execution
*
* @{
*
* @defgroup api-instance Instance
* @defgroup api-tasklets Tasklets
* @defgroup api-instance Instance
* @defgroup api-tasklets Tasklets
*
* @}
*
* @defgroup api-net IPv6 Networking
* @defgroup api-net IPv6 Networking
* @{
*
* @defgroup api-ble-secure BLE Secure
* @defgroup api-dns DNS
* @defgroup api-dnssd-server DNS-SD Server
* @defgroup api-icmp6 ICMPv6
* @defgroup api-ip6 IPv6
* @defgroup api-mdns Multicast DNS
* @defgroup api-nat64 NAT64
* @defgroup api-srp SRP
* @defgroup api-ping-sender Ping Sender
* @defgroup api-ble-secure BLE Secure
* @defgroup api-dns DNS
* @defgroup api-dnssd-server DNS-SD Server
* @defgroup api-icmp6 ICMPv6
* @defgroup api-ip6 IPv6
* @defgroup api-mdns Multicast DNS
* @defgroup api-nat64 NAT64
* @defgroup api-srp SRP
* @defgroup api-ping-sender Ping Sender
*
* @defgroup api-tcp-group TCP
* @defgroup api-tcp-group TCP
*
* @{
*
* @defgroup api-tcp TCP
* @defgroup api-tcp-ext TCP Abstractions
* @defgroup api-tcp TCP
* @defgroup api-tcp-ext TCP Abstractions
*
* @}
*
* @defgroup api-udp-group UDP
* @defgroup api-udp-group UDP
*
* @{
*
* @defgroup api-udp UDP
* @defgroup api-udp-forward UDP Forward
* @defgroup api-udp UDP
* @defgroup api-udp-forward UDP Forward
*
* @}
*
* @}
*
* @defgroup api-link Link
* @defgroup api-link Link
*
* @{
*
* @defgroup api-link-link Link
* @defgroup api-link-metrics Link Metrics
* @defgroup api-link-raw Raw Link
* @defgroup api-link-link Link
* @defgroup api-link-metrics Link Metrics
* @defgroup api-link-raw Raw Link
*
* @}
*
* @defgroup api-message Message
* @defgroup api-message Message
*
* @defgroup api-multi-radio Multi Radio Link
* @defgroup api-trel TREL - Thread Stack
* @defgroup api-multi-radio Multi Radio Link
* @defgroup api-trel TREL - Thread Stack
*
* @defgroup api-thread Thread
* @defgroup api-thread Thread
*
* @{
*
* @defgroup api-backbone-router Backbone Router
* @defgroup api-border-agent Border Agent
* @defgroup api-border-agent-tracker Border Agent Tracker
* @defgroup api-border-router Border Router
* @defgroup api-border-routing Border Routing Manager
* @defgroup api-commissioner Commissioner
* @defgroup api-thread-general General
* @defgroup api-backbone-router Backbone Router
* @defgroup api-border-agent Border Agent
* @defgroup api-border-agent-tracker Border Agent Tracker
* @defgroup api-border-agent-txt-data Border Agent TXT Data Parser
* @defgroup api-border-router Border Router
* @defgroup api-border-routing Border Routing Manager
* @defgroup api-commissioner Commissioner
* @defgroup api-thread-general General
* @brief This module includes functions for all Thread roles.
* @defgroup api-joiner Joiner
* @defgroup api-operational-dataset Operational Dataset
* @defgroup api-joiner Joiner
* @defgroup api-operational-dataset Operational Dataset
* @brief Includes functions for the Operational Dataset API.
* @defgroup api-thread-router Router/Leader
* @defgroup api-thread-router Router/Leader
* @brief This module includes functions for Thread Routers and Leaders.
* @defgroup api-server Server
* @defgroup api-server Server
*
* @}
*
* @defgroup api-addons Add-Ons
* @defgroup api-addons Add-Ons
*
* @{
*
* @defgroup api-channel-manager Channel Manager
* @defgroup api-channel-monitor Channel Monitoring
* @defgroup api-child-supervision Child Supervision
* @defgroup api-coap-group CoAP
* @defgroup api-channel-manager Channel Manager
* @defgroup api-channel-monitor Channel Monitoring
* @defgroup api-child-supervision Child Supervision
* @defgroup api-coap-group CoAP
*
* @{
*
* @defgroup api-coap CoAP
* @defgroup api-coap-secure CoAP Secure
* @defgroup api-coap CoAP
* @defgroup api-coap-secure CoAP Secure
*
* @}
*
* @defgroup api-cli Command Line Interface
* @defgroup api-crypto Crypto - Thread Stack
* @defgroup api-factory-diagnostics Factory Diagnostics - Thread Stack
* @defgroup api-heap Heap
* @defgroup api-history-tracker History Tracker
* @defgroup api-jam-detection Jam Detection
* @defgroup api-logging Logging - Thread Stack
* @defgroup api-mesh-diag Mesh Diagnostics
* @defgroup api-ncp Network Co-Processor
* @defgroup api-network-time Network Time Synchronization
* @defgroup api-radio Radio Statistics
* @defgroup api-random-group Random Number Generator
* @defgroup api-cli Command Line Interface
* @defgroup api-crypto Crypto - Thread Stack
* @defgroup api-factory-diagnostics Factory Diagnostics - Thread Stack
* @defgroup api-heap Heap
* @defgroup api-history-tracker History Tracker
* @defgroup api-jam-detection Jam Detection
* @defgroup api-logging Logging - Thread Stack
* @defgroup api-mesh-diag Mesh Diagnostics
* @defgroup api-ncp Network Co-Processor
* @defgroup api-network-time Network Time Synchronization
* @defgroup api-radio Radio Statistics
* @defgroup api-random-group Random Number Generator
*
* @{
*
* @defgroup api-random-crypto RNG Cryptographic
* @defgroup api-random-non-crypto RNG Non-cryptographic
* @defgroup api-random-crypto RNG Cryptographic
* @defgroup api-random-non-crypto RNG Non-cryptographic
*
* @}
*
* @defgroup api-sntp SNTP
* @defgroup api-verhoeff-checksum Verhoeff Checksum
* @defgroup api-sntp SNTP
* @defgroup api-verhoeff-checksum Verhoeff Checksum
*
* @}
*
* @defgroup api-provisional Provisional
* @defgroup api-provisional Provisional
* @brief
* This module includes the OpenThread provisional APIs. These APIs are not stable and users should use them with
* caution.
*
* @{
*
* @defgroup api-provisional-link Link
* @defgroup api-provisional-p2p Peer-to-Peer
* @defgroup api-provisional-link Link
* @defgroup api-provisional-p2p Peer-to-Peer
*
* @}
*
@@ -176,33 +177,33 @@
*/
/**
* @defgroup platform Platform Abstraction
* @defgroup platform Platform Abstraction
* @brief
* This module includes the platform abstraction used by the OpenThread stack.
*
* @{
*
* @defgroup plat-alarm Alarm
* @defgroup plat-ble BLE
* @defgroup plat-crypto Crypto - Platform
* @defgroup plat-dns DNS - Platform
* @defgroup plat-dns-sd DNS-SD (mDNS)
* @defgroup plat-entropy Entropy
* @defgroup plat-factory-diagnostics Factory Diagnostics - Platform
* @defgroup plat-infra-if Infrastructure Interface
* @defgroup plat-logging Logging - Platform
* @defgroup plat-memory Memory
* @defgroup plat-messagepool Message Pool
* @defgroup plat-misc Miscellaneous
* @defgroup plat-mdns Multicast DNS
* @defgroup plat-multipan Multipan
* @defgroup plat-otns Network Simulator
* @defgroup plat-radio Radio
* @defgroup plat-settings Settings
* @defgroup plat-spi-slave SPI Slave
* @defgroup plat-time Time Service
* @defgroup plat-toolchain Toolchain
* @defgroup plat-trel TREL - Platform
* @defgroup plat-alarm Alarm
* @defgroup plat-ble BLE
* @defgroup plat-crypto Crypto - Platform
* @defgroup plat-dns DNS - Platform
* @defgroup plat-dns-sd DNS-SD (mDNS)
* @defgroup plat-entropy Entropy
* @defgroup plat-factory-diagnostics Factory Diagnostics - Platform
* @defgroup plat-infra-if Infrastructure Interface
* @defgroup plat-logging Logging - Platform
* @defgroup plat-memory Memory
* @defgroup plat-messagepool Message Pool
* @defgroup plat-misc Miscellaneous
* @defgroup plat-mdns Multicast DNS
* @defgroup plat-multipan Multipan
* @defgroup plat-otns Network Simulator
* @defgroup plat-radio Radio
* @defgroup plat-settings Settings
* @defgroup plat-spi-slave SPI Slave
* @defgroup plat-time Time Service
* @defgroup plat-toolchain Toolchain
* @defgroup plat-trel TREL - Platform
*
* @}
*/
+1
View File
@@ -178,6 +178,7 @@ ot_option(OT_BORDER_AGENT_EPSKC OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENA
ot_option(OT_BORDER_AGENT_ID OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE "create and save border agent ID")
ot_option(OT_BORDER_AGENT_MESHCOP_SERVICE OPENTHREAD_CONFIG_BORDER_AGENT_MESHCOP_SERVICE_ENABLE "border agent meshcop service")
ot_option(OT_BORDER_AGENT_TRACKER OPENTHREAD_CONFIG_BORDER_AGENT_TRACKER_ENABLE "border agent tracker")
ot_option(OT_BORDER_AGENT_TXT_DATA_PARSER OPENTHREAD_CONFIG_BORDER_AGENT_TXT_DATA_PARSER_ENABLE "border agent TXT data parser")
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_DHCP6_PD OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE "dhcpv6 pd support in border routing")
+1
View File
@@ -44,6 +44,7 @@ source_set("openthread") {
"ble_secure.h",
"border_agent.h",
"border_agent_tracker.h",
"border_agent_txt_data.h",
"border_router.h",
"border_routing.h",
"channel_manager.h",
+183
View File
@@ -0,0 +1,183 @@
/*
* 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 Border Agent TXT data parsing APIs.
*/
#ifndef OPENTHREAD_BORDER_AGENT_TXT_DATA_H_
#define OPENTHREAD_BORDER_AGENT_TXT_DATA_H_
#include <stdbool.h>
#include <stdint.h>
#include <openthread/border_agent.h>
#include <openthread/dataset.h>
#include <openthread/error.h>
#include <openthread/ip6.h>
#include <openthread/platform/radio.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @addtogroup api-border-agent-txt-data
*
* @brief
* This module includes APIs for parsing the MeshCoP service TXT data of a Border Agent.
*
* @{
*/
#define OT_BORDER_AGENT_RECORD_VERSION_SIZE (8) ///< Max size of Record Version string in `otBorderAgentTxtDataInfo`.
#define OT_BORDER_AGENT_THREAD_VERSION_SIZE (16) ///< Max size of Thread Version string in `otBorderAgentTxtDataInfo`.
#define OT_BORDER_AGENT_VENDOR_NAME_SIZE (32) ///< Max size of Vendor Name string in `otBorderAgentTxtDataInfo`.
#define OT_BORDER_AGENT_MODEL_NAME_SIZE (32) ///< Max size of Model Name string in `otBorderAgentTxtDataInfo`.
/**
* Represents the Connection Mode in a Border Agent State Bitmap.
*/
typedef enum otBorderAgentConnMode
{
OT_BORDER_AGENT_CONN_MODE_DISABLED = 0, ///< DTLS connection not allowed.
OT_BORDER_AGENT_CONN_MODE_PSKC = 1, ///< DTLS connection with PSKc.
OT_BORDER_AGENT_CONN_MODE_PSKD = 2, ///< DTLS connection with PSKd.
OT_BORDER_AGENT_CONN_MODE_VENDOR = 3, ///< DTLS with vendor defined credential.
OT_BORDER_AGENT_CONN_MODE_X509 = 4, ///< DTLS with X.509 certificate.
} otBorderAgentConnMode;
/**
* Represents the Thread Interface Status in a Border Agent State Bitmap.
*/
typedef enum otBorderAgentThreadIfState
{
OT_BORDER_AGENT_THREAD_IF_NOT_INITIALIZED = 0, ///< Thread interface is not initialized.
OT_BORDER_AGENT_THREAD_IF_INITIALIZED = 1, ///< Thread interface is initialized but is not yet active.
OT_BORDER_AGENT_THREAD_IF_ACTIVE = 2, ///< Thread interface is initialized and active.
} otBorderAgentThreadIfState;
/**
* Represents the Availability Status in a Border Agent State Bitmap.
*/
typedef enum otBorderAgentAvailability
{
OT_BORDER_AGENT_AVAILABILITY_INFREQUENT = 0, ///< Infrequent availability.
OT_BORDER_AGENT_AVAILABILITY_HIGH = 1, ///< High availability.
} otBorderAgentAvailability;
/**
* Represents the Thread Role in a Border Agent State Bitmap.
*/
typedef enum otBorderAgentThreadRole
{
OT_BORDER_AGENT_THREAD_ROLE_DISABLED_OR_DETACHED = 0, ///< Detached or disabled.
OT_BORDER_AGENT_THREAD_ROLE_CHILD = 1, ///< End device (child).
OT_BORDER_AGENT_THREAD_ROLE_ROUTER = 2, ///< Router.
OT_BORDER_AGENT_THREAD_ROLE_LEADER = 3, ///< Leader.
} otBorderAgentThreadRole;
/**
* Represents Border Agent State Bitmap information.
*/
typedef struct otBorderAgentStateBitmap
{
otBorderAgentConnMode mConnMode; ///< Connection Mode.
otBorderAgentThreadIfState mThreadIfState; ///< Thread Interface Status.
otBorderAgentAvailability mAvailability; ///< Availability
otBorderAgentThreadRole mThreadRole; ///< Thread Role.
bool mBbrIsActive; ///< Backbone Router function is active.
bool mBbrIsPrimary; ///< Device is the Primary Backbone Router.
bool mEpskcSupported; ///< ePSKc Mode is supported.
} otBorderAgentStateBitmap;
/**
* Represents parsed Border Agent TXT data.
*
* The boolean flags indicate whether a specific field is present in the parsed TXT data.
*/
typedef struct otBorderAgentTxtDataInfo
{
bool mHasRecordVersion : 1; ///< Indicates whether Record Version is present.
bool mHasAgentId : 1; ///< Indicates whether Agent ID is present.
bool mHasThreadVersion : 1; ///< Indicates whether Thread Version is present.
bool mHasStateBitmap : 1; ///< Indicates whether State Bitmap is present.
bool mHasNetworkName : 1; ///< Indicates whether Network Name is present.
bool mHasExtendedPanId : 1; ///< Indicates whether Extended PAN ID is present.
bool mHasActiveTimestamp : 1; ///< Indicates whether Active Timestamp is present.
bool mHasPartitionId : 1; ///< Indicates whether Partition ID is present.
bool mHasDomainName : 1; ///< Indicates whether Domain Name is present.
bool mHasBbrSeqNum : 1; ///< Indicates whether BBR Sequence Number is present.
bool mHasBbrPort : 1; ///< Indicates whether BBR Port is present.
bool mHasOmrPrefix : 1; ///< Indicates whether OMR Prefix is present.
bool mHasExtAddress : 1; ///< Indicates whether Extended Address is present.
bool mHasVendorName : 1; ///< Indicates whether Vendor Name is present.
bool mHasModelName : 1; ///< Indicates whether Model Name is present.
char mRecordVersion[OT_BORDER_AGENT_RECORD_VERSION_SIZE]; ///< Record Version string.
otBorderAgentId mAgentId; ///< Agent ID.
char mThreadVersion[OT_BORDER_AGENT_THREAD_VERSION_SIZE]; ///< Thread Version string.
otBorderAgentStateBitmap mStateBitmap; ///< State Bitmap.
otNetworkName mNetworkName; ///< Network Name.
otExtendedPanId mExtendedPanId; ///< Extended PAN ID.
otTimestamp mActiveTimestamp; ///< Active Timestamp.
uint32_t mPartitionId; ///< Partition ID.
otNetworkName mDomainName; ///< Domain Name.
uint8_t mBbrSeqNum; ///< BBR Sequence Number.
uint16_t mBbrPort; ///< BBR Port.
otIp6Prefix mOmrPrefix; ///< OMR Prefix.
otExtAddress mExtAddress; ///< Extended Address.
char mVendorName[OT_BORDER_AGENT_VENDOR_NAME_SIZE]; ///< Vendor Name string.
char mModelName[OT_BORDER_AGENT_MODEL_NAME_SIZE]; ///< Model Name string.
} otBorderAgentTxtDataInfo;
/**
* Parses a Border Agent's MeshCoP service TXT data.
*
* Requires `OPENTHREAD_CONFIG_BORDER_AGENT_TXT_DATA_PARSER_ENABLE`.
*
* @param[in] aTxtData A pointer to the buffer containing the TXT data.
* @param[in] aTxtDataLength The length of the TXT data in bytes.
* @param[out] aInfo A pointer to a structure to output the parsed information.
*
* @retval OT_ERROR_NONE Successfully parsed the TXT data.
* @retval OT_ERROR_PARSE Failed to parse the TXT data.
*/
otError otBorderAgentTxtDataParse(const uint8_t *aTxtData, uint16_t aTxtDataLength, otBorderAgentTxtDataInfo *aInfo);
/**
* @}
*
*/
#ifdef __cplusplus
} // extern "C"
#endif
#endif // OPENTHREAD_BORDER_AGENT_TXT_DATA_H_
+1 -1
View File
@@ -52,7 +52,7 @@ extern "C" {
*
* @note This number versions both OpenThread platform and user APIs.
*/
#define OPENTHREAD_API_VERSION (542)
#define OPENTHREAD_API_VERSION (543)
/**
* @addtogroup api-instance
+1
View File
@@ -310,6 +310,7 @@ openthread_core_files = [
"api/ble_secure_api.cpp",
"api/border_agent_api.cpp",
"api/border_agent_tracker_api.cpp",
"api/border_agent_txt_data_api.cpp",
"api/border_router_api.cpp",
"api/border_routing_api.cpp",
"api/channel_manager_api.cpp",
+1
View File
@@ -36,6 +36,7 @@ set(COMMON_SOURCES
api/ble_secure_api.cpp
api/border_agent_api.cpp
api/border_agent_tracker_api.cpp
api/border_agent_txt_data_api.cpp
api/border_router_api.cpp
api/border_routing_api.cpp
api/channel_manager_api.cpp
@@ -0,0 +1,51 @@
/*
* 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
* This file implements the OpenThread Border Agent TXT data parsing APIs.
*/
#include "openthread-core-config.h"
#if OPENTHREAD_CONFIG_BORDER_AGENT_TXT_DATA_PARSER_ENABLE
#include <openthread/border_agent_txt_data.h>
#include "instance/instance.hpp"
using namespace ot;
otError otBorderAgentTxtDataParse(const uint8_t *aTxtData, uint16_t aTxtDataLength, otBorderAgentTxtDataInfo *aInfo)
{
AssertPointerIsNotNull(aTxtData);
return AsCoreType(aInfo).ParseFrom(aTxtData, aTxtDataLength);
}
#endif // OPENTHREAD_CONFIG_BORDER_AGENT_TXT_DATA_PARSER_ENABLE
+9
View File
@@ -134,6 +134,15 @@
#define OPENTHREAD_CONFIG_BORDER_AGENT_TRACKER_ENABLE 0
#endif
/**
* @def OPENTHREAD_CONFIG_BORDER_AGENT_TXT_DATA_PARSER_ENABLE
*
* Define to 1 to enable the Border Agent TXT Data Parser feature.
*/
#ifndef OPENTHREAD_CONFIG_BORDER_AGENT_TXT_DATA_PARSER_ENABLE
#define OPENTHREAD_CONFIG_BORDER_AGENT_TXT_DATA_PARSER_ENABLE 0
#endif
/**
* @}
*/
+184 -8
View File
@@ -33,13 +33,14 @@
#include "border_agent_txt_data.hpp"
#include "common/string.hpp"
#include "instance/instance.hpp"
namespace ot {
namespace MeshCoP {
namespace BorderAgent {
#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE
#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE || OPENTHREAD_CONFIG_BORDER_AGENT_TXT_DATA_PARSER_ENABLE
const char TxtData::kRecordVersion[] = "1";
@@ -56,12 +57,18 @@ const char TxtData::Key::kBbrSeqNum[] = "sq";
const char TxtData::Key::kBbrPort[] = "bb";
const char TxtData::Key::kOmrPrefix[] = "omr";
const char TxtData::Key::kExtAddress[] = "xa";
#if OPENTHREAD_CONFIG_BORDER_AGENT_TXT_DATA_PARSER_ENABLE
const char TxtData::Key::kVendorName[] = "vn";
const char TxtData::Key::kModelName[] = "mn";
#endif
TxtData::TxtData(Instance &aInstance)
: InstanceLocator(aInstance)
{
}
#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE
Error TxtData::Prepare(uint8_t *aBuffer, uint16_t aBufferSize, uint16_t &aLength)
{
Error error = kErrorNone;
@@ -157,25 +164,25 @@ uint32_t TxtData::StateBitmap::Determine(Instance &aInstance)
{
uint32_t bitmap = 0;
bitmap |= (aInstance.Get<Manager>().IsRunning() ? kConnectionModePskc : kConnectionModeDisabled);
bitmap |= kAvailabilityHigh;
bitmap |= ((aInstance.Get<Manager>().IsRunning() ? kConnModePskc : kConnModeDisabled) << kOffsetConnMode);
bitmap |= (kAvailabilityHigh << kOffsetAvailability);
switch (aInstance.Get<Mle::Mle>().GetRole())
{
case Mle::DeviceRole::kRoleDisabled:
bitmap |= (kThreadIfStatusNotInitialized | kThreadRoleDisabledOrDetached);
bitmap |= (kThreadIfNotInit << kOffsetIfState) | (kRoleDisabledDetached << kOffsetRole);
break;
case Mle::DeviceRole::kRoleDetached:
bitmap |= (kThreadIfStatusInitialized | kThreadRoleDisabledOrDetached);
bitmap |= (kThreadIfInit << kOffsetIfState) | (kRoleDisabledDetached << kOffsetRole);
break;
case Mle::DeviceRole::kRoleChild:
bitmap |= (kThreadIfStatusActive | kThreadRoleChild);
bitmap |= (kThreadIfActive << kOffsetIfState) | (kRoleChild << kOffsetRole);
break;
case Mle::DeviceRole::kRoleRouter:
bitmap |= (kThreadIfStatusActive | kThreadRoleRouter);
bitmap |= (kThreadIfActive << kOffsetIfState) | (kRoleRouter << kOffsetRole);
break;
case Mle::DeviceRole::kRoleLeader:
bitmap |= (kThreadIfStatusActive | kThreadRoleLeader);
bitmap |= (kThreadIfActive << kOffsetIfState) | (kRoleLeader << kOffsetRole);
break;
}
@@ -199,6 +206,175 @@ uint32_t TxtData::StateBitmap::Determine(Instance &aInstance)
#endif // OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE
#if OPENTHREAD_CONFIG_BORDER_AGENT_TXT_DATA_PARSER_ENABLE
Error TxtData::Info::ParseFrom(const uint8_t *aTxtData, uint16_t aTxtDataLength)
{
Error error;
Dns::TxtEntry entry;
Dns::TxtEntry::Iterator iterator;
Clear();
iterator.Init(aTxtData, aTxtDataLength);
while ((error = iterator.GetNextEntry(entry)) == kErrorNone)
{
ProcessTxtEntry(entry);
}
if (error == kErrorNotFound)
{
error = kErrorNone;
}
return error;
}
void TxtData::Info::ProcessTxtEntry(const Dns::TxtEntry &aEntry)
{
if (aEntry.mKey == nullptr)
{
// If the TXT data happens to have entries with key longer
// than `kMaxIterKeyLength`, `mKey` would be `nullptr` and full
// entry would be placed in `mValue`. We skip over such
// entries.
}
else if (StringMatch(aEntry.mKey, Key::kRecordVersion))
{
ReadStringValue(aEntry, mRecordVersion);
mHasRecordVersion = true;
}
else if (StringMatch(aEntry.mKey, Key::kAgentId))
{
mHasAgentId = ReadValue(aEntry, mAgentId);
}
else if (StringMatch(aEntry.mKey, Key::kThreadVersion))
{
ReadStringValue(aEntry, mThreadVersion);
mHasThreadVersion = true;
}
else if (StringMatch(aEntry.mKey, Key::kStateBitmap))
{
uint32_t bitmap;
if (ReadBigEndianUintValue(aEntry, bitmap))
{
StateBitmap::Parse(bitmap, mStateBitmap);
mHasStateBitmap = true;
}
}
else if (StringMatch(aEntry.mKey, Key::kNetworkName))
{
ReadStringValue(aEntry, mNetworkName.m8);
mHasNetworkName = true;
}
else if (StringMatch(aEntry.mKey, Key::kExtendedPanId))
{
mHasExtendedPanId = ReadValue(aEntry, mExtendedPanId);
}
else if (StringMatch(aEntry.mKey, Key::kActiveTimestamp))
{
Timestamp timestamp;
if (ReadValue(aEntry, timestamp))
{
timestamp.ConvertTo(mActiveTimestamp);
mHasActiveTimestamp = true;
}
}
else if (StringMatch(aEntry.mKey, Key::kPartitionId))
{
mHasPartitionId = ReadBigEndianUintValue(aEntry, mPartitionId);
}
else if (StringMatch(aEntry.mKey, Key::kDomainName))
{
ReadStringValue(aEntry, mDomainName.m8);
mHasDomainName = true;
}
else if (StringMatch(aEntry.mKey, Key::kBbrSeqNum))
{
mHasBbrSeqNum = ReadBigEndianUintValue(aEntry, mBbrSeqNum);
}
else if (StringMatch(aEntry.mKey, Key::kBbrPort))
{
mHasBbrPort = ReadBigEndianUintValue(aEntry, mBbrPort);
}
else if (StringMatch(aEntry.mKey, Key::kOmrPrefix))
{
mHasOmrPrefix = ReadOmrPrefix(aEntry, AsCoreType(&mOmrPrefix));
}
else if (StringMatch(aEntry.mKey, Key::kExtAddress))
{
mHasExtAddress = ReadValue(aEntry, mExtAddress);
}
else if (StringMatch(aEntry.mKey, Key::kVendorName))
{
ReadStringValue(aEntry, mVendorName);
mHasVendorName = true;
}
else if (StringMatch(aEntry.mKey, Key::kModelName))
{
ReadStringValue(aEntry, mModelName);
mHasModelName = true;
}
}
bool TxtData::Info::ReadValue(const Dns::TxtEntry &aEntry, void *aBuffer, uint16_t aSize)
{
bool didRead = false;
VerifyOrExit(aEntry.mValueLength >= aSize);
memcpy(aBuffer, aEntry.mValue, aSize);
didRead = true;
exit:
return didRead;
}
void TxtData::Info::ReadStringValue(const Dns::TxtEntry &aEntry, char *aString, uint16_t aStringSize)
{
uint16_t copyLength = Min<uint16_t>(aStringSize - 1, aEntry.mValueLength);
memcpy(aString, aEntry.mValue, copyLength);
aString[copyLength] = kNullChar;
}
bool TxtData::Info::ReadOmrPrefix(const Dns::TxtEntry &aEntry, Ip6::Prefix &aPrefix)
{
bool didRead = false;
uint8_t length;
VerifyOrExit(aEntry.mValueLength >= sizeof(uint8_t));
length = aEntry.mValue[0];
VerifyOrExit(length <= Ip6::Prefix::kMaxLength);
VerifyOrExit(aEntry.mValueLength >= sizeof(uint8_t) + Ip6::Prefix::SizeForLength(length));
aPrefix.Set(&aEntry.mValue[1], length);
didRead = true;
exit:
return didRead;
}
void TxtData::StateBitmap::Parse(uint32_t aBitmap, Info &aInfo)
{
ClearAllBytes(aInfo);
aInfo.mConnMode = static_cast<ConnMode>((aBitmap & kMaskConnMode) >> kOffsetConnMode);
aInfo.mThreadIfState = static_cast<IfState>((aBitmap & kMaskIfState) >> kOffsetIfState);
aInfo.mAvailability = static_cast<Availability>((aBitmap & kMaskAvailability) >> kOffsetAvailability);
aInfo.mThreadRole = static_cast<Role>((aBitmap & kMaskRole) >> kOffsetRole);
aInfo.mBbrIsActive = aBitmap & kFlagBbrIsActive;
aInfo.mBbrIsPrimary = aBitmap & kFlagBbrIsPrimary;
aInfo.mEpskcSupported = aBitmap & kFlagEpskcSupported;
}
#endif // OPENTHREAD_CONFIG_BORDER_AGENT_TXT_DATA_PARSER_ENABLE
#endif // OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE || OPENTHREAD_CONFIG_BORDER_AGENT_TXT_DATA_PARSER_ENABLE
} // namespace BorderAgent
} // namespace MeshCoP
} // namespace ot
+143 -42
View File
@@ -37,20 +37,48 @@
#include "openthread-core-config.h"
#include <openthread/border_agent.h>
#include <openthread/border_agent_txt_data.h>
#include "common/as_core_type.hpp"
#include "common/clearable.hpp"
#include "common/encoding.hpp"
#include "common/error.hpp"
#include "common/locator.hpp"
#include "common/type_traits.hpp"
#include "net/dns_types.hpp"
#include "net/ip6_address.hpp"
namespace ot {
namespace MeshCoP {
namespace BorderAgent {
#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE
#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE || OPENTHREAD_CONFIG_BORDER_AGENT_TXT_DATA_PARSER_ENABLE
class TxtData : public InstanceLocator
{
public:
typedef otBorderAgentMeshCoPServiceTxtData ServiceTxtData; ///< Service TXT Data.
typedef otBorderAgentConnMode ConnMode; ///< Connection Mode in a Border Agent State Bitmap.
typedef otBorderAgentThreadIfState IfState; ///< Thread Interface State in a Border Agent State Bitmap.
typedef otBorderAgentAvailability Availability; ///< Availability Status in a Border Agent State Bitmap.
typedef otBorderAgentThreadRole Role; ///< Thread Role in a Border Agent State Bitmap.
static constexpr ConnMode kConnModeDisabled = OT_BORDER_AGENT_CONN_MODE_DISABLED; ///< Not allowed.
static constexpr ConnMode kConnModePskc = OT_BORDER_AGENT_CONN_MODE_PSKC; ///< DTLS with PSKc.
static constexpr ConnMode kConnModePskd = OT_BORDER_AGENT_CONN_MODE_PSKD; ///< DTLS with PSKd.
static constexpr ConnMode kConnModeVendor = OT_BORDER_AGENT_CONN_MODE_VENDOR; ///< Vendor defined.
static constexpr ConnMode kConnModeX509 = OT_BORDER_AGENT_CONN_MODE_X509; ///< DTLS X.509 cert.
static constexpr IfState kThreadIfNotInit = OT_BORDER_AGENT_THREAD_IF_NOT_INITIALIZED; ///< Not init.
static constexpr IfState kThreadIfInit = OT_BORDER_AGENT_THREAD_IF_INITIALIZED; ///< Init but not active.
static constexpr IfState kThreadIfActive = OT_BORDER_AGENT_THREAD_IF_ACTIVE; ///< Init and active.
static constexpr Availability kAvailabilityInfreq = OT_BORDER_AGENT_AVAILABILITY_INFREQUENT; ///< Infrequent.
static constexpr Availability kAvailabilityHigh = OT_BORDER_AGENT_AVAILABILITY_HIGH; ///< High.
static constexpr Role kRoleDisabledDetached = OT_BORDER_AGENT_THREAD_ROLE_DISABLED_OR_DETACHED; ///< Detach.
static constexpr Role kRoleChild = OT_BORDER_AGENT_THREAD_ROLE_CHILD; ///< Child.
static constexpr Role kRoleRouter = OT_BORDER_AGENT_THREAD_ROLE_ROUTER; ///< Router.
static constexpr Role kRoleLeader = OT_BORDER_AGENT_THREAD_ROLE_LEADER; ///< Leader.
/**
* Initializes the `TxtData` object.
@@ -59,6 +87,68 @@ public:
*/
TxtData(Instance &aInstance);
#if OPENTHREAD_CONFIG_BORDER_AGENT_TXT_DATA_PARSER_ENABLE
/**
* Represents information parsed from a Border Agent TXT Data.
*/
class Info : public otBorderAgentTxtDataInfo, public Clearable<Info>
{
public:
/**
* Parses a Border Agent's MeshCoP service TXT data.
*
* @param[in] aTxtData A pointer to the buffer containing the TXT data.
* @param[in] aTxtDataLength The length of the TXT data in bytes.
*
* @retval kErrorNone Successfully parsed the TXT data.
* @retval kErrorParse Failed to parse the TXT data.
*/
Error ParseFrom(const uint8_t *aTxtData, uint16_t aTxtDataLength);
private:
void ProcessTxtEntry(const Dns::TxtEntry &aEntry);
static bool ReadValue(const Dns::TxtEntry &aEntry, void *aBuffer, uint16_t aSize);
static void ReadStringValue(const Dns::TxtEntry &aEntry, char *aString, uint16_t aStringSize);
static bool ReadOmrPrefix(const Dns::TxtEntry &aEntry, Ip6::Prefix &aPrefix);
template <typename ObjectType> bool ReadValue(const Dns::TxtEntry &aEntry, ObjectType &aObject)
{
static_assert(!TypeTraits::IsPointer<ObjectType>::kValue, "ObjectType must not be a pointer");
return ReadValue(aEntry, &aObject, sizeof(aObject));
}
template <uint16_t kStringSize>
static void ReadStringValue(const Dns::TxtEntry &aEntry, char (&aString)[kStringSize])
{
ReadStringValue(aEntry, aString, kStringSize);
}
template <typename UintType>
static bool ReadBigEndianUintValue(const Dns::TxtEntry &aEntry, UintType &aUintValue)
{
static_assert(TypeTraits::IsUint<UintType>::kValue, "UintType must be a 8, 16, 32, or 64 bit uint");
bool didRead = false;
if (aEntry.mValueLength >= sizeof(UintType))
{
aUintValue = BigEndian::Read<UintType>(aEntry.mValue);
didRead = true;
}
return didRead;
}
};
#endif // OPENTHREAD_CONFIG_BORDER_AGENT_TXT_DATA_PARSER_ENABLE
#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE
typedef otBorderAgentMeshCoPServiceTxtData ServiceTxtData; ///< Service TXT Data.
/**
* Prepares the MeshCoP service TXT data.
*
@@ -81,6 +171,8 @@ public:
*/
Error Prepare(ServiceTxtData &aTxtData);
#endif // OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE
private:
static const char kRecordVersion[];
@@ -99,60 +191,69 @@ private:
static const char kBbrPort[];
static const char kOmrPrefix[];
static const char kExtAddress[];
#if OPENTHREAD_CONFIG_BORDER_AGENT_TXT_DATA_PARSER_ENABLE
static const char kVendorName[];
static const char kModelName[];
#endif
};
struct StateBitmap
{
static uint32_t Determine(Instance &aInstance);
static constexpr uint8_t kOffsetConnMode = 0;
static constexpr uint8_t kOffsetIfState = 3;
static constexpr uint8_t kOffsetAvailability = 5;
static constexpr uint8_t kOffsetBbrIsActive = 7;
static constexpr uint8_t kOffsetBbrIsPrimary = 8;
static constexpr uint8_t kOffsetRole = 9;
static constexpr uint8_t kOffsetEpskcSupported = 11;
// --- State Bitmap ConnectionMode ---
static constexpr uint8_t kOffsetConnectionMode = 0;
static constexpr uint32_t kMaskConnectionMode = 7 << kOffsetConnectionMode;
static constexpr uint32_t kConnectionModeDisabled = 0 << kOffsetConnectionMode;
static constexpr uint32_t kConnectionModePskc = 1 << kOffsetConnectionMode;
static constexpr uint32_t kConnectionModePskd = 2 << kOffsetConnectionMode;
static constexpr uint32_t kConnectionModeVendor = 3 << kOffsetConnectionMode;
static constexpr uint32_t kConnectionModeX509 = 4 << kOffsetConnectionMode;
// --- State Bitmap ThreadIfStatus ---
static constexpr uint8_t kOffsetThreadIfStatus = 3;
static constexpr uint32_t kMaskThreadIfStatus = 3 << kOffsetThreadIfStatus;
static constexpr uint32_t kThreadIfStatusNotInitialized = 0 << kOffsetThreadIfStatus;
static constexpr uint32_t kThreadIfStatusInitialized = 1 << kOffsetThreadIfStatus;
static constexpr uint32_t kThreadIfStatusActive = 2 << kOffsetThreadIfStatus;
// --- State Bitmap Availability ---
static constexpr uint8_t kOffsetAvailability = 5;
static constexpr uint32_t kMaskAvailability = 3 << kOffsetAvailability;
static constexpr uint32_t kAvailabilityInfrequent = 0 << kOffsetAvailability;
static constexpr uint32_t kAvailabilityHigh = 1 << kOffsetAvailability;
// --- State Bitmap BbrIsActive ---
static constexpr uint8_t kOffsetBbrIsActive = 7;
static constexpr uint32_t kFlagBbrIsActive = 1 << kOffsetBbrIsActive;
// --- State Bitmap BbrIsPrimary ---
static constexpr uint8_t kOffsetBbrIsPrimary = 8;
static constexpr uint32_t kMaskConnMode = 7 << kOffsetConnMode;
static constexpr uint32_t kMaskIfState = 3 << kOffsetIfState;
static constexpr uint32_t kMaskAvailability = 3 << kOffsetAvailability;
static constexpr uint32_t kFlagBbrIsActive = 1 << kOffsetBbrIsActive;
static constexpr uint32_t kFlagBbrIsPrimary = 1 << kOffsetBbrIsPrimary;
static constexpr uint32_t kMaskRole = 3 << kOffsetRole;
static constexpr uint32_t kFlagEpskcSupported = 1 << kOffsetEpskcSupported;
// --- State Bitmap ThreadRole ---
static constexpr uint8_t kOffsetThreadRole = 9;
static constexpr uint32_t kMaskThreadRole = 3 << kOffsetThreadRole;
static constexpr uint32_t kThreadRoleDisabledOrDetached = 0 << kOffsetThreadRole;
static constexpr uint32_t kThreadRoleChild = 1 << kOffsetThreadRole;
static constexpr uint32_t kThreadRoleRouter = 2 << kOffsetThreadRole;
static constexpr uint32_t kThreadRoleLeader = 3 << kOffsetThreadRole;
static_assert(kConnModeDisabled == 0, "kConnModeDisabled is incorrect");
static_assert(kConnModePskc == 1, "kConnModePskc is incorrect");
static_assert(kConnModePskd == 2, "kConnModePskd is incorrect");
static_assert(kConnModeVendor == 3, "kConnModeVendor is incorrect");
static_assert(kConnModeX509 == 4, "kConnModeX509 is incorrect");
// --- State Bitmap EpskcSupported ---
static constexpr uint8_t kOffsetEpskcSupported = 11;
static constexpr uint32_t kFlagEpskcSupported = 1 << kOffsetEpskcSupported;
static_assert(kThreadIfNotInit == 0, "kThreadIfNotInit is incorrect");
static_assert(kThreadIfInit == 1, "kThreadIfInit is incorrect");
static_assert(kThreadIfActive == 2, "kThreadIfActive is incorrect");
static_assert(kAvailabilityInfreq == 0, "kAvailabilityInfreq is incorrect");
static_assert(kAvailabilityHigh == 1, "kAvailabilityHigh is incorrect");
static_assert(kRoleDisabledDetached == 0, "kRoleDisabledDetached is incorrect");
static_assert(kRoleChild == 1, "kRoleChild is incorrect");
static_assert(kRoleRouter == 2, "kRoleRouter is incorrect");
static_assert(kRoleLeader == 3, "kRoleLeader is incorrect");
#if OPENTHREAD_CONFIG_BORDER_AGENT_TXT_DATA_PARSER_ENABLE
typedef otBorderAgentStateBitmap Info;
static void Parse(uint32_t aBitmap, Info &aInfo);
#endif
#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE
static uint32_t Determine(Instance &aInstance);
#endif
};
};
#endif // OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE
#endif // OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE || OPENTHREAD_CONFIG_BORDER_AGENT_TXT_DATA_PARSER_ENABLE
} // namespace BorderAgent
} // namespace MeshCoP
#if OPENTHREAD_CONFIG_BORDER_AGENT_TXT_DATA_PARSER_ENABLE
DefineCoreType(otBorderAgentTxtDataInfo, MeshCoP::BorderAgent::TxtData::Info);
#endif
} // namespace ot
#endif // BORDER_AGENT_TXT_DATA_HPP_
@@ -47,6 +47,7 @@
#define OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE 1
#define OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE 1
#define OPENTHREAD_CONFIG_BORDER_AGENT_TRACKER_ENABLE 1
#define OPENTHREAD_CONFIG_BORDER_AGENT_TXT_DATA_PARSER_ENABLE 1
#define OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE 1
#define OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE 1
#define OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_CLIENT_ENABLE 0
+62 -7
View File
@@ -1242,61 +1242,114 @@ void ValidateMeshCoPTxtData(TxtData &aTxtData, Node &aNode)
static constexpr uint32_t kFlagEpskcSupported = 1 << 11;
MeshCoP::BorderAgent::Id id;
BaTxtData::Info info;
const Mac::ExtAddress &extAddress = aNode.Get<Mac::Mac>().GetExtAddress();
uint32_t stateBitmap;
uint32_t threadIfStatus;
uint32_t threadRole;
bool baIsRunning;
aTxtData.ValidateFormat();
aTxtData.LogAllTxtEntries();
SuccessOrQuit(info.ParseFrom(aTxtData.mData, aTxtData.mLength));
aNode.Get<Manager>().GetId(id);
aTxtData.ValidateKey("id", id);
VerifyOrQuit(info.mHasAgentId);
VerifyOrQuit(id == AsCoreType(&info.mAgentId));
aTxtData.ValidateKey("rv", "1");
VerifyOrQuit(info.mHasRecordVersion);
VerifyOrQuit(StringMatch(info.mRecordVersion, "1"));
aTxtData.ValidateKey("tv", kThreadVersionString);
aTxtData.ValidateKey("xa", aNode.Get<Mac::Mac>().GetExtAddress());
VerifyOrQuit(info.mHasThreadVersion);
VerifyOrQuit(StringMatch(info.mThreadVersion, kThreadVersionString));
aTxtData.ValidateKey("xa", extAddress);
VerifyOrQuit(info.mHasExtAddress);
VerifyOrQuit(AsCoreType(&info.mExtAddress) == extAddress);
if (aNode.Get<MeshCoP::ActiveDatasetManager>().IsComplete())
{
aTxtData.ValidateKey("nn", aNode.Get<NetworkNameManager>().GetNetworkName().GetAsCString());
aTxtData.ValidateKey("xp", aNode.Get<ExtendedPanIdManager>().GetExtPanId());
const char *networkName = aNode.Get<NetworkNameManager>().GetNetworkName().GetAsCString();
const MeshCoP::ExtendedPanId &extPanId = aNode.Get<ExtendedPanIdManager>().GetExtPanId();
aTxtData.ValidateKey("nn", networkName);
VerifyOrQuit(info.mHasNetworkName);
VerifyOrQuit(StringMatch(info.mNetworkName.m8, networkName));
aTxtData.ValidateKey("xp", extPanId);
VerifyOrQuit(info.mHasExtendedPanId);
VerifyOrQuit(AsCoreType(&info.mExtendedPanId) == extPanId);
}
if (aNode.Get<Mle::Mle>().IsAttached())
{
aTxtData.ValidateKey("pt", BigEndian::HostSwap32(aNode.Get<Mle::Mle>().GetLeaderData().GetPartitionId()));
aTxtData.ValidateKey("at", aNode.Get<ActiveDatasetManager>().GetTimestamp());
uint32_t partitionId = aNode.Get<Mle::Mle>().GetLeaderData().GetPartitionId();
const MeshCoP::Timestamp &timestamp = aNode.Get<ActiveDatasetManager>().GetTimestamp();
MeshCoP::Timestamp::Info timestampInfo;
aTxtData.ValidateKey("pt", BigEndian::HostSwap32(partitionId));
VerifyOrQuit(info.mHasPartitionId);
VerifyOrQuit(info.mPartitionId == partitionId);
aTxtData.ValidateKey("at", timestamp);
timestamp.ConvertTo(timestampInfo);
VerifyOrQuit(info.mHasActiveTimestamp);
VerifyOrQuit(info.mActiveTimestamp.mSeconds == timestampInfo.mSeconds);
VerifyOrQuit(info.mActiveTimestamp.mTicks == timestampInfo.mTicks);
VerifyOrQuit(info.mActiveTimestamp.mAuthoritative == timestampInfo.mAuthoritative);
}
else
{
VerifyOrQuit(!aTxtData.ContainsKey("pt"));
VerifyOrQuit(!info.mHasPartitionId);
VerifyOrQuit(!aTxtData.ContainsKey("at"));
VerifyOrQuit(!info.mHasActiveTimestamp);
}
stateBitmap = aTxtData.ReadUint32Key("sb");
VerifyOrQuit(info.mHasStateBitmap);
baIsRunning = aNode.Get<Manager>().IsRunning();
VerifyOrQuit((stateBitmap & kMaskConnectionMode) == (baIsRunning ? kConnectionModePskc : kConnectionModeDisabled));
VerifyOrQuit(info.mStateBitmap.mConnMode ==
(baIsRunning ? BaTxtData::kConnModePskc : BaTxtData::kConnModeDisabled));
VerifyOrQuit((stateBitmap & kMaskConnectionMode) == aNode.Get<Manager>().IsRunning() ? kConnectionModePskc
: kConnectionModeDisabled);
switch (aNode.Get<Mle::Mle>().GetRole())
{
case Mle::DeviceRole::kRoleDisabled:
threadIfStatus = kThreadIfStatusNotInitialized;
threadRole = kThreadRoleDisabledOrDetached;
VerifyOrQuit(info.mStateBitmap.mThreadIfState == BaTxtData::kThreadIfNotInit);
VerifyOrQuit(info.mStateBitmap.mThreadRole == BaTxtData::kRoleDisabledDetached);
break;
case Mle::DeviceRole::kRoleDetached:
threadIfStatus = kThreadIfStatusInitialized;
threadRole = kThreadRoleDisabledOrDetached;
VerifyOrQuit(info.mStateBitmap.mThreadIfState == BaTxtData::kThreadIfInit);
VerifyOrQuit(info.mStateBitmap.mThreadRole == BaTxtData::kRoleDisabledDetached);
break;
case Mle::DeviceRole::kRoleChild:
threadIfStatus = kThreadIfStatusActive;
threadRole = kThreadRoleChild;
VerifyOrQuit(info.mStateBitmap.mThreadIfState == BaTxtData::kThreadIfActive);
VerifyOrQuit(info.mStateBitmap.mThreadRole == BaTxtData::kRoleChild);
break;
case Mle::DeviceRole::kRoleRouter:
threadIfStatus = kThreadIfStatusActive;
threadRole = kThreadRoleRouter;
VerifyOrQuit(info.mStateBitmap.mThreadIfState == BaTxtData::kThreadIfActive);
VerifyOrQuit(info.mStateBitmap.mThreadRole == BaTxtData::kRoleRouter);
break;
case Mle::DeviceRole::kRoleLeader:
threadIfStatus = kThreadIfStatusActive;
threadRole = kThreadRoleLeader;
VerifyOrQuit(info.mStateBitmap.mThreadIfState == BaTxtData::kThreadIfActive);
VerifyOrQuit(info.mStateBitmap.mThreadRole == BaTxtData::kRoleLeader);
break;
}
@@ -1306,10 +1359,12 @@ void ValidateMeshCoPTxtData(TxtData &aTxtData, Node &aNode)
if (aNode.Get<EphemeralKeyManager>().GetState() != EphemeralKeyManager::kStateDisabled)
{
VerifyOrQuit(stateBitmap & kFlagEpskcSupported);
VerifyOrQuit(info.mStateBitmap.mEpskcSupported);
}
else
{
VerifyOrQuit(!(stateBitmap & kFlagEpskcSupported));
VerifyOrQuit(!info.mStateBitmap.mEpskcSupported);
}
}
@@ -84,6 +84,8 @@
#define OPENTHREAD_CONFIG_BORDER_AGENT_TRACKER_ENABLE 1
#define OPENTHREAD_CONFIG_BORDER_AGENT_TXT_DATA_PARSER_ENABLE 1
#define OPENTHREAD_CONFIG_DIAG_ENABLE 1
#define OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE 1