mirror of
https://github.com/espressif/openthread.git
synced 2026-09-06 17:20:09 +00:00
[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:
+89
-88
@@ -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
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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_
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ×tamp = 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
|
||||
|
||||
Reference in New Issue
Block a user