Files
openthread/tests/nexus/test_1_3_DPR_TC_1.cpp
Abtin Keshavarzian 2a120a9ddf [nexus] remove redundant mInfraIf initializations (#12851)
This commit removes redundant calls to `mInfraIf.Init()` and
`mInfraIf.AddAddress()` from various Nexus test cases.

The infrastructure interface (`mInfraIf`) is automatically initialized
and assigned a link-local address by the core framework when a new
`Node` is added. The `InfraIf::Init()` method derives the link-local
address from the MAC address and adds it to the interface. Therefore,
these explicit manual calls in individual test scripts are unnecessary
and can be removed to simplify the test setup.
2026-04-08 16:09:17 -05:00

369 lines
14 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* 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 "platform/nexus_core.hpp"
#include "platform/nexus_node.hpp"
#include "net/mdns.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 a node to join as a child and upgrade to a router, in milliseconds.
*/
static constexpr uint32_t kJoinNetworkTime = 200 * 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 wait for SRP registration to complete.
*/
static constexpr uint32_t kSrpRegistrationTime = 5 * 1000;
/**
* Time to wait for DNS response.
*/
static constexpr uint32_t kDnsResponseTime = 20 * 1000;
/**
* Infrastructure interface index.
*/
static constexpr uint32_t kInfraIfIndex = 1;
/**
* Service and Host names.
*/
static const char kInfraServiceType[] = "_infra-test._udp";
static const char kInfraHostName[] = "host-test-eth";
static const char kDiscoveryProxyType[] = "_infra-test._udp.default.service.arpa.";
struct ServiceInfo
{
const char *mInstanceName;
uint16_t mPort;
const char *mTxtData;
};
static const ServiceInfo kInfraServices[] = {
{"service-test-1", 55551, "\x0Adummy=abcd\x0Fthread-test=a49"},
{"service-test-2", 55552, "\x04a=2\x12thread-test=b50_test"},
{"service-test-3", 55553, "\x0Ba_dummy=42\x0Cthread-test="},
{"service-test-4", 55554, "\x0Dthread-test=1\x15ignorethis=thread-test="},
{"service-test-5", 55555,
"\x0B"
"a88=thread-\x10THREAD-TEST=C51\x14ignorethis=thread-test"},
};
static void RegisterMdnsServices(Node &aEth1)
{
Dns::Multicast::Core &mdns = aEth1.Get<Dns::Multicast::Core>();
SuccessOrQuit(mdns.SetEnabled(true, kInfraIfIndex));
{
Dns::Multicast::Core::Host host;
ClearAllBytes(host);
host.mHostName = kInfraHostName;
host.mAddresses = &aEth1.mInfraIf.GetAddresses()[1]; // ULA address
host.mAddressesLength = 1;
SuccessOrQuit(mdns.RegisterHost(host, 0, nullptr));
}
for (const ServiceInfo &info : kInfraServices)
{
Dns::Multicast::Core::Service service;
ClearAllBytes(service);
service.mServiceInstance = info.mInstanceName;
service.mServiceType = kInfraServiceType;
service.mHostName = kInfraHostName;
service.mPort = info.mPort;
service.mTxtData = reinterpret_cast<const uint8_t *>(info.mTxtData);
service.mTxtDataLength = static_cast<uint16_t>(strlen(info.mTxtData));
SuccessOrQuit(mdns.RegisterService(service, 0, nullptr));
}
}
void Test_1_3_DPR_TC_1(const char *aJsonFileName)
{
/**
* 5.1. [1.3] [CERT] Service discovery of services on Thread and Infrastructure - Single BR
*
* 5.1.1 Purpose
* To test the following:
* 1. Discovery proxy on the BR to perform mDNS query on the infrastructure link in the case where it doesn’t have
* any answer.
* 2. Respond to unicast DNS queries made by a Thread Device on the Thread interface.
* 3. Thread Device can discover services advertised by infrastructure device (mDNS) via BR DUT.
* 4. Single BR case
*
* 5.1.2 Topology
* - BR_1 (DUT) - Thread Border Router, and the Leader
* - ED_1 - Test Bed device operating as a Thread End Device, attached to BR_1
* - Eth_1 - Test Bed border router device on an Adjacent Infrastructure Link
*
* Spec Reference | V1.1 Section | V1.3.0 Section
* --------------------|--------------|---------------
* Discovery Proxy | N/A | 5.1
*/
Core nexus;
Node &br1 = nexus.CreateNode();
Node &ed1 = nexus.CreateNode();
Node &eth1 = nexus.CreateNode();
Srp::Client::Service service;
Dns::TxtEntry txtEntry;
br1.SetName("BR_1");
ed1.SetName("ED_1");
eth1.SetName("Eth_1");
nexus.AdvanceTime(0);
SuccessOrQuit(Instance::SetGlobalLogLevel(kLogLevelNote));
Log("---------------------------------------------------------------------------------------");
Log("Step 1: Device: BR_1 (DUT) Description (DPR-5.1): Enable");
/**
* Step 1
* - Device: BR_1 (DUT)
* - Description (DPR-5.1): Enable
* - Pass Criteria: N/A
*/
br1.Form();
nexus.AdvanceTime(kFormNetworkTime);
VerifyOrQuit(br1.Get<Mle::Mle>().IsLeader());
Log("---------------------------------------------------------------------------------------");
Log("Step 2: Device: Eth_1, ED_1 Description (DPR-5.1): Enable");
/**
* Step 2
* - Device: Eth_1, ED_1
* - Description (DPR-5.1): Enable
* - Pass Criteria: N/A
*/
ed1.Join(br1, Node::kAsFed);
nexus.AdvanceTime(kJoinNetworkTime);
VerifyOrQuit(ed1.Get<Mle::Mle>().IsAttached());
Log("---------------------------------------------------------------------------------------");
Log("Step 3: Device: BR_1 (DUT) Description (DPR-5.1): Automatically adds its SRP Server information...");
/**
* Step 3
* - Device: BR_1 (DUT)
* - Description (DPR-5.1): Automatically adds its SRP Server information in the Thread Network Data.
* Automatically configures an OMR prefix on the Thread Network. Automatically configures a ULA prefix on the AIL.
* - Pass Criteria:
* - The DUT’s SRP Server information MUST appear in the Thread Network Data.
* - It MUST be a DNS/SRP Unicast Dataset, or DNS/SRP Anycast Dataset, or both.
*/
br1.Get<BorderRouter::InfraIf>().Init(kInfraIfIndex, true);
br1.Get<BorderRouter::RoutingManager>().Init();
SuccessOrQuit(br1.Get<BorderRouter::RoutingManager>().SetEnabled(true));
SuccessOrQuit(br1.Get<Srp::Server>().SetAddressMode(Srp::Server::kAddressModeUnicast));
br1.Get<Srp::Server>().SetEnabled(true);
nexus.AdvanceTime(kBrActionTime);
Ip6::Prefix omrPrefix;
SuccessOrQuit(br1.Get<BorderRouter::RoutingManager>().GetOmrPrefix(omrPrefix));
nexus.AddTestVar("OMR_PREFIX", omrPrefix.ToString().AsCString());
Ip6::Prefix pre1Prefix;
SuccessOrQuit(br1.Get<BorderRouter::RoutingManager>().GetOnLinkPrefix(pre1Prefix));
nexus.AddTestVar("PRE_1_PREFIX", pre1Prefix.ToString().AsCString());
Log("---------------------------------------------------------------------------------------");
Log("Step 4: Device: Eth_1 Description (DPR-5.1): Harness instructs device to advertise N=5 services...");
/**
* Step 4
* - Device: Eth_1
* - Description (DPR-5.1): Harness instructs device to advertise N=5 services using mDNS.
* - Pass Criteria: N/A
*/
RegisterMdnsServices(eth1);
nexus.AdvanceTime(kDnsResponseTime);
Log("---------------------------------------------------------------------------------------");
Log("Step 5: Device: ED_1 Description (DPR-5.1): Harness instructs the device to send an SRP Update...");
/**
* Step 5
* - Device: ED_1
* - Description (DPR-5.1): Harness instructs the device to send an SRP Update to DUT as follows:
* $ORIGIN default.service.arpa. service-test-6._thread-test._udp ( SRV 0 0 55551 host-test-1 TXT
* thread-te=trick=value ) host-test-1 AAAA <OMR address of ED_1>
* - Pass Criteria: N/A
*/
ed1.Get<Srp::Client>().EnableAutoStartMode(nullptr, nullptr);
SuccessOrQuit(ed1.Get<Srp::Client>().SetHostName("host-test-1"));
SuccessOrQuit(ed1.Get<Srp::Client>().EnableAutoHostAddress());
ClearAllBytes(service);
service.mName = "_thread-test._udp";
service.mInstanceName = "service-test-6";
service.mPort = 55551;
txtEntry.mKey = "thread-te";
txtEntry.mValue = reinterpret_cast<const uint8_t *>("trick=value");
txtEntry.mValueLength = 11;
service.mTxtEntries = &txtEntry;
service.mNumTxtEntries = 1;
SuccessOrQuit(ed1.Get<Srp::Client>().AddService(service));
nexus.AdvanceTime(kSrpRegistrationTime);
Log("---------------------------------------------------------------------------------------");
Log("Step 6: Device: BR_1 (DUT) Description (DPR-5.1): Automatically sends SRP Update Response with SUCCESS");
/**
* Step 6
* - Device: BR_1 (DUT)
* - Description (DPR-5.1): Automatically sends SRP Update Response with “SUCCESS”.
* - Pass Criteria:
* - The DUT MUST send SRP Update Response with status 0 ( “NoError” ).
*/
VerifyOrQuit(ed1.Get<Srp::Client>().GetHostInfo().GetState() == Srp::Client::kRegistered);
Log("---------------------------------------------------------------------------------------");
Log("Step 7: Device: ED_1 Description (DPR-5.1): Harness instructs the device to unicast DNS query QType=PTR...");
/**
* Step 7
* - Device: ED_1
* - Description (DPR-5.1): Harness instructs the device to unicast DNS query QType=PTR to the DUT for services
* of type “_infra-test._udp.default.service.arpa.”
* - Pass Criteria: N/A
*/
const Ip6::Address &br1Mleid = br1.Get<Mle::Mle>().GetMeshLocalEid();
Dns::Client::QueryConfig queryConfig;
queryConfig.Clear();
AsCoreType(&queryConfig.mServerSockAddr.mAddress) = br1Mleid;
queryConfig.mServerSockAddr.mPort = Dns::ServiceDiscovery::Server::kPort;
SuccessOrQuit(ed1.Get<Dns::Client>().Browse(kDiscoveryProxyType, nullptr, nullptr, &queryConfig));
Log("---------------------------------------------------------------------------------------");
Log("Step 8: Device: BR_1 (DUT) Description (DPR-5.1): Automatically MAY send mDNS query...");
/**
* Step 8
* - Device: BR_1 (DUT)
* - Description (DPR-5.1): Automatically MAY send mDNS query on the infrastructure link.
* - Pass Criteria: N/A
*/
nexus.AdvanceTime(1000);
Log("---------------------------------------------------------------------------------------");
Log("Step 9: Device: Eth_1 Description (DPR-5.1): In case DUT queried in step 8, it automatically sends mDNS...");
/**
* Step 9
* - Device: Eth_1
* - Description (DPR-5.1): In case DUT queried in step 8, it automatically sends mDNS response with its active
* services.
* - Pass Criteria: N/A
*/
nexus.AdvanceTime(kDnsResponseTime);
Log("---------------------------------------------------------------------------------------");
Log("Step 10: Device: BR_1 (DUT) Description (DPR-5.1): Automatically sends a DNS response to ED_1");
/**
* Step 10
* - Device: BR_1 (DUT)
* - Description (DPR-5.1): Automatically sends a DNS response to ED_1.
* - Pass Criteria: N/A (validation of response in the next step)
*/
Log("---------------------------------------------------------------------------------------");
Log("Step 11: Device: ED_1 Description (DPR-5.1): Receives the DNS response with at least one of the N services");
/**
* Step 11
* - Device: ED_1
* - Description (DPR-5.1): Receives the DNS response with at least one of the N services.
* - Pass Criteria:
* - The DUT must send a valid DNS Response, containing in the Answer records section at least one of the services
* advertised by Eth_1, specifically the below where N is a number out of 1, 2, 3, 4, 5:
* $ORIGIN default.service.arpa. _infra-test._udp ( PTR service-test-N._infra-test._udp )
* - It MAY contain in the Additional records section one or more of the below services identified by number N
* plus the host (AAAA) record:
* $ORIGIN default.service.arpa. service-test-1._infra-test._udp ( SRV 0 0 55551 host-test-eth TXT
* dummy=abcd;thread-test=a49 ) ... host-test-eth AAAA <ULA address of Eth_1>
* - Response MUST NOT contain any AAAA record with a link-local address.
* - Response MUST NOT contain “service-test-6” records.
* - Response MUST NOT contain any “host-test-1” records.
*/
nexus.SaveTestInfo(aJsonFileName);
}
} // namespace Nexus
} // namespace ot
int main(int argc, char *argv[])
{
const char *jsonFile = (argc > 1) ? argv[argc - 1] : "test_1_3_DPR_TC_1.json";
ot::Nexus::Test_1_3_DPR_TC_1(jsonFile);
printf("All tests passed\n");
return 0;
}