mirror of
https://github.com/espressif/openthread.git
synced 2026-09-27 11:27:36 +00:00
In nexus tests, DNS browser and resolver objects must be initialized using ClearAllBytes before use to ensure predictable behavior. This commit adds missing ClearAllBytes calls for: - Dns::Multicast::Core::Browser - Dns::Multicast::Core::TxtResolver - Dns::Multicast::Core::SrvResolver - Dns::Multicast::Core::AddressResolver In test_1_3_SRP_TC_4.cpp, ClearAllBytes is now called before browser reuse in Step 19. Redundant includes of common/clearable.hpp were removed as it is available transitively. A blank line was added after Browser declarations for consistency.
297 lines
11 KiB
C++
297 lines
11 KiB
C++
/*
|
|
* Copyright (c) 2026, 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.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include "platform/nexus_core.hpp"
|
|
#include "platform/nexus_node.hpp"
|
|
|
|
namespace ot {
|
|
namespace Nexus {
|
|
|
|
/**
|
|
* Time to advance for a node to form a network and become leader, in milliseconds.
|
|
*/
|
|
static constexpr uint32_t kFormNetworkTime = 13 * 1000;
|
|
|
|
/**
|
|
* Time to advance for the BR to perform automatic actions (RA, Network Data), in milliseconds.
|
|
*/
|
|
static constexpr uint32_t kBrActionTime = 20 * 1000;
|
|
|
|
/**
|
|
* Time to advance for DNS query processing, in milliseconds.
|
|
*/
|
|
static constexpr uint32_t kDnsQueryTime = 20 * 1000;
|
|
|
|
/**
|
|
* Infrastructure interface index.
|
|
*/
|
|
static constexpr uint32_t kInfraIfIndex = 1;
|
|
|
|
/**
|
|
* Active Timestamp components.
|
|
*/
|
|
static constexpr uint64_t kActiveTimestampSeconds = 0x666af1;
|
|
static constexpr uint16_t kActiveTimestampTicks = 0x1880;
|
|
|
|
/**
|
|
* Service name parameters.
|
|
*/
|
|
static const char kMeshCoPServiceType[] = "_meshcop._udp";
|
|
|
|
void Test_1_3_GEN_TC_2(const char *aJsonFileName)
|
|
{
|
|
/**
|
|
* 9.2. [1.3] [CERT] Border Router mDNS discovery of v1.3/v1.4 TXT records
|
|
*
|
|
* 9.2.1. Purpose
|
|
* - This test verifies that the Border Router DUT implements TXT records that were added in the v1.3 / v1.4
|
|
* specifications: “omr”, “xa”, and “id”. It also verifies changed rules in the v1.4.0 specification on use of
|
|
* vendor-specific records. It also validates, to the extent possible, that BR vendors provide correct values
|
|
* for TXT record keys.
|
|
*
|
|
* 9.2.2. Topology
|
|
* - BR_1: Thread Border Router DUT and Leader
|
|
* - Eth_1: Reference device
|
|
*
|
|
* Spec Reference | V1.3.0 Section
|
|
* ---------------|---------------
|
|
* Thread 1.3.0 | 9.2
|
|
*/
|
|
|
|
Core nexus;
|
|
|
|
Node &br1 = nexus.CreateNode();
|
|
Node ð1 = nexus.CreateNode();
|
|
|
|
br1.SetName("BR_1");
|
|
eth1.SetName("Eth_1");
|
|
|
|
SuccessOrQuit(Instance::SetGlobalLogLevel(kLogLevelNote));
|
|
|
|
br1.mSettings.Wipe();
|
|
eth1.mSettings.Wipe();
|
|
br1.Reset();
|
|
eth1.Reset();
|
|
|
|
for (uint8_t i = 0; i < 2; i++)
|
|
{
|
|
Log("---------------------------------------------------------------------------------------");
|
|
Log("Iteration %u", i);
|
|
|
|
/**
|
|
* Step 0
|
|
* - Device: BR_1 (DUT) / Harness
|
|
* - Description (GEN-9.2): Harness configures DUT with Active Operational Dataset, either via THCI or via
|
|
* the vendor specified setup method for the BR. This includes the following: Network Name: "Thread Cert
|
|
* 9.2", Active Timestamp (uint64): 0x000000666AF13100. Note: this timestamp can be set using the OT CLI
|
|
* command "dataset activetimestamp 1718284593"
|
|
*/
|
|
Log("Step 0: Harness configures DUT with Active Operational Dataset.");
|
|
{
|
|
MeshCoP::Dataset::Info datasetInfo;
|
|
SuccessOrQuit(br1.Get<MeshCoP::ActiveDatasetManager>().CreateNewNetwork(datasetInfo));
|
|
|
|
datasetInfo.mActiveTimestamp.mSeconds = kActiveTimestampSeconds;
|
|
datasetInfo.mActiveTimestamp.mTicks = kActiveTimestampTicks;
|
|
datasetInfo.mActiveTimestamp.mAuthoritative = false;
|
|
datasetInfo.mComponents.mIsActiveTimestampPresent = true;
|
|
|
|
{
|
|
MeshCoP::NetworkName networkName;
|
|
SuccessOrQuit(networkName.Set("Thread Cert 9.2"));
|
|
datasetInfo.Set<MeshCoP::Dataset::kNetworkName>(networkName);
|
|
}
|
|
|
|
br1.Get<MeshCoP::ActiveDatasetManager>().SaveLocal(datasetInfo);
|
|
|
|
SuccessOrQuit(br1.Get<MeshCoP::BorderAgent::Manager>().SetServiceBaseName("OpenThread "));
|
|
|
|
{
|
|
uint8_t vendorTxtData[] = {
|
|
14, 'v', 'n', '=', 'N', 'e', 'x', 'u', 's', 'V', 'e', 'n', 'd', 'o', 'r', 13, 'm', 'n',
|
|
'=', 'N', 'e', 'x', 'u', 's', 'M', 'o', 'd', 'e', 'l', 6, 'v', 'o', '=', 0x00, 0x00, 0x01,
|
|
};
|
|
br1.Get<MeshCoP::BorderAgent::TxtData>().SetVendorData(vendorTxtData, sizeof(vendorTxtData));
|
|
}
|
|
|
|
br1.Get<MeshCoP::BorderAgent::Manager>().SetEnabled(true);
|
|
}
|
|
|
|
/**
|
|
* Step 1
|
|
* - Device: BR_1 (DUT)
|
|
* - Description (GEN-9.2): Form topology. DUT becomes Leader of its Thread Network. It configures an OMR ULA
|
|
* prefix OMR_1 and sends the prefix OMR_1 in ND RA multicast messages on the AIL. Harness records the
|
|
* value of OMR_1 for validation in future test steps.
|
|
*/
|
|
Log("Step 1: Form topology. DUT becomes Leader. Configures OMR prefix.");
|
|
br1.Get<ThreadNetif>().Up();
|
|
SuccessOrQuit(br1.Get<Mle::Mle>().Start());
|
|
|
|
br1.Get<BorderRouter::InfraIf>().Init(kInfraIfIndex, true);
|
|
br1.Get<BorderRouter::RoutingManager>().Init();
|
|
SuccessOrQuit(br1.Get<BorderRouter::RoutingManager>().SetEnabled(true));
|
|
nexus.AdvanceTime(kFormNetworkTime);
|
|
|
|
// Wait for BR to advertise prefixes and for verification script to catch RAs
|
|
nexus.AdvanceTime(kBrActionTime);
|
|
|
|
VerifyOrQuit(br1.Get<Mle::Mle>().IsLeader());
|
|
|
|
SuccessOrQuit(eth1.Get<Dns::Multicast::Core>().SetEnabled(true, kInfraIfIndex));
|
|
|
|
/**
|
|
* Step 2
|
|
* - Device: Eth_1
|
|
* - Description (GEN-9.2): Harness instructs the device to send via mDNS a DNS-SD QType=PTR query for
|
|
* services “_meshcop._udp.local”.
|
|
*/
|
|
Log("Step 2: Eth_1 sends mDNS PTR query for _meshcop._udp.local.");
|
|
Dns::Multicast::Core::Browser browser;
|
|
|
|
ClearAllBytes(browser);
|
|
browser.mCallback = [](otInstance *, const Dns::Multicast::Core::BrowseResult *) {};
|
|
browser.mServiceType = kMeshCoPServiceType;
|
|
browser.mInfraIfIndex = kInfraIfIndex;
|
|
SuccessOrQuit(eth1.Get<Dns::Multicast::Core>().StartBrowser(browser));
|
|
nexus.AdvanceTime(kDnsQueryTime);
|
|
SuccessOrQuit(eth1.Get<Dns::Multicast::Core>().StopBrowser(browser));
|
|
|
|
/**
|
|
* Step 3
|
|
* - Device: BR_1 (DUT)
|
|
* - Description (GEN-9.2): Automatically responds with mDNS response with PTR records, and optionally
|
|
* Additional Records (SRV/TXT).
|
|
*/
|
|
Log("Step 3: BR_1 (DUT) responds with mDNS response with PTR records.");
|
|
|
|
/**
|
|
* Step 4
|
|
* - Device: Eth_1
|
|
* - Description (GEN-9.2): Harness instructs the device to send via mDNS a query QType=TXT, with the DNS
|
|
* name set to the service instance name that is included in the PTR record in step 3.
|
|
*/
|
|
Log("Step 4: Eth_1 sends mDNS TXT query for the service instance.");
|
|
{
|
|
Dns::Multicast::Core::TxtResolver resolver;
|
|
char serviceInstance[64];
|
|
|
|
ClearAllBytes(resolver);
|
|
snprintf(serviceInstance, sizeof(serviceInstance), "OpenThread%s",
|
|
br1.Get<Mac::Mac>().GetExtAddress().ToString().AsCString());
|
|
|
|
Log("Querying TXT for instance: %s", serviceInstance);
|
|
|
|
resolver.mCallback = [](otInstance *, const Dns::Multicast::Core::TxtResult *aResult) {
|
|
Log("TXT Callback: instance=%s", aResult->mServiceInstance);
|
|
};
|
|
resolver.mServiceType = kMeshCoPServiceType;
|
|
resolver.mInfraIfIndex = kInfraIfIndex;
|
|
resolver.mServiceInstance = serviceInstance;
|
|
|
|
SuccessOrQuit(eth1.Get<Dns::Multicast::Core>().StartTxtResolver(resolver));
|
|
nexus.AdvanceTime(kDnsQueryTime);
|
|
SuccessOrQuit(eth1.Get<Dns::Multicast::Core>().StopTxtResolver(resolver));
|
|
}
|
|
|
|
/**
|
|
* Step 5
|
|
* - Device: BR_1 (DUT)
|
|
* - Description (GEN-9.2): Automatically responds with mDNS response with TXT record.
|
|
*/
|
|
Log("Step 5: BR_1 (DUT) responds with mDNS response with TXT record.");
|
|
|
|
/**
|
|
* Step 6
|
|
* - Device: BR_1 (DUT) / Harness
|
|
* - Description (GEN-9.2): Verify that the DUT responded with the right data in the TXT record keys. This
|
|
* uses the TXT record found in step 5.
|
|
*/
|
|
Log("Step 6: Verify TXT record keys.");
|
|
|
|
{
|
|
char varName[64];
|
|
snprintf(varName, sizeof(varName), "BR_1_EXT_ADDR_%u", i);
|
|
nexus.AddTestVar(varName, br1.Get<Mac::Mac>().GetExtAddress().ToString().AsCString());
|
|
|
|
Ip6::Prefix omrPrefix;
|
|
BorderRouter::RoutePreference preference;
|
|
if (br1.Get<BorderRouter::RoutingManager>().GetFavoredOmrPrefix(omrPrefix, preference) == kErrorNone)
|
|
{
|
|
snprintf(varName, sizeof(varName), "BR_1_OMR_PREFIX_%u", i);
|
|
nexus.AddTestVar(varName, omrPrefix.ToString().AsCString());
|
|
Log("Iteration %u OMR Prefix: %s", i, omrPrefix.ToString().AsCString());
|
|
}
|
|
}
|
|
|
|
if (i == 0)
|
|
{
|
|
/**
|
|
* Step 7
|
|
* - Device: BR_1 (DUT)
|
|
* - Description (GEN-9.2): Factory reset the device.
|
|
*/
|
|
Log("Step 7: Factory reset the device.");
|
|
SuccessOrQuit(br1.Get<BorderRouter::RoutingManager>().SetEnabled(false));
|
|
br1.mSettings.Wipe();
|
|
br1.Reset();
|
|
|
|
SuccessOrQuit(eth1.Get<Dns::Multicast::Core>().SetEnabled(false, kInfraIfIndex));
|
|
|
|
// Wait for reset and restart
|
|
nexus.AdvanceTime(20 * 1000);
|
|
}
|
|
else
|
|
{
|
|
/**
|
|
* Step 8
|
|
* - Device: BR_1 (DUT)
|
|
* - Description (GEN-9.2): Repeat steps 0 to 6 again.
|
|
*/
|
|
Log("Step 8: Repeat steps 0 to 6 again.");
|
|
}
|
|
}
|
|
|
|
Log("All steps completed.");
|
|
|
|
nexus.SaveTestInfo(aJsonFileName);
|
|
}
|
|
|
|
} // namespace Nexus
|
|
} // namespace ot
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
ot::Nexus::Test_1_3_GEN_TC_2((argc > 2) ? argv[2] : "test_1_3_gen_tc_2.json");
|
|
printf("All tests passed\n");
|
|
return 0;
|
|
}
|