This commit adds support for interacting with nodes via the CLI in the
Nexus simulation framework. This enables writing higher-level
integration tests that verify stack behavior and state through
standard CLI commands.
Key changes:
- Integrated `Cli::Interpreter` into the `Nexus::Node` class.
- Added `Node::InputCli()` to allow sending commands to a node with
`printf`-style formatting.
- Implemented output capturing logic in `Node::HandleCliOutput()` to
buffer and parse CLI responses into individual lines, stored in a
`CliOutputArray`.
- Added helper methods to `CliOutputLine` for matching and validating
the captured output.
- Added a new `cli_basic` Nexus test to demonstrate and validate the
CLI interaction functionality.
This commit reorganizes the `Node` class declaration in
`nexus_node.hpp` to improve readability and maintainability.
The methods and members are now logically grouped into marked
sections.
This commit adds support for building the Nexus simulator for
WebAssembly (WASM) using the Emscripten toolchain. This enables the
simulator to run in a web browser environment with a JavaScript-based
control interface and visualization.
Key implementation details:
- Introduced `nexus_wasm.cpp` which defines Emscripten bindings (using
Embind) for core simulation controls, including stepping time,
node creation, topology orchestration, and state manipulation.
- Implemented a `WasmObserver` and a global event queue to capture
simulation events (node state changes, link updates, packet events)
and expose them to JavaScript via a polling mechanism (`pollEvent`).
- Updated the CMake build system to support the `EMSCRIPTEN` platform,
configuring specific linker options for ES6 module export,
modularization, and memory growth.
- Enhanced `build.sh` to allow targeting WASM via `emcmake`.
- Guarded file-system-dependent operations in `nexus_pcap.cpp` and
adjusted `nexus_core.cpp` to handle WASM-specific constraints where
standard I/O or multiple observers might not be applicable.
- Added `test_wasm_bindings.mjs`, a Node.js-based smoke test that
verifies the integrity of the WASM bindings and event pipeline.
- Integrated `nexus-wasm-tests` into the GitHub Actions workflow to
ensure continuous verification of the WASM build and functionality.
Added `Core::AllowLinkBetween()` and `Core::UnallowLinkBetween()`
helper methods to the Nexus test platform. These methods simplify
establishing bidirectional links between nodes in simulation tests by
handling the reciprocal `AllowList()` calls in a single step.
Updated various Nexus test cases to utilize these new helpers,
replacing manual bidirectional `AllowList()` calls. This change
reduces verbosity and ensures consistency in how links are established
in the test topology.
This commit introduces the `SimulationObserver` interface and integrates
it into the Nexus core simulation logic. This allows external systems to
observe node state changes, link updates, and packet events in real-time.
Key changes:
- Defined `SimulationObserver` interface to handle node state changes,
link updates, packet events, and event clearing.
- Added `SetObserver` and `GetObserver` methods to the `Core` class.
- Implemented `Core::HandleNeighborTableChanged` to notify the observer
of neighbor additions and removals.
- Implemented `Core::HandleStateChanged` to track node role transitions
and parent changes, updating links accordingly.
- Integrated packet event notification in `Core::ProcessRadio`,
including basic destination node ID resolution for unicast frames.
- Added `Core::SetNodeEnabled` to allow enabling or disabling Thread and
MLE on specific nodes at runtime.
- Updated `Core::Reset` to clear events via the observer.
- Increased `OPENTHREAD_CONFIG_MAX_STATECHANGE_HANDLERS` to accommodate
the new nexus state change handler.
- Added `mLastParentId` to `Node` class to correctly manage link updates
during parent switches or detachment.
This commit updates the Nexus platform to use the internal core C++
API `Ip6::SetReceiveCallback()` instead of the public C API
`otIp6SetReceiveCallback()`.
This commit implements the Nexus test specification 1_4_DNS_TC_3 for
upstream DNS resolver selection in OpenThread.
Nexus Platform Enhancements:
- Added OPENTHREAD_CONFIG_DNS_UPSTREAM_QUERY_ENABLE and
OPENTHREAD_CONFIG_PLATFORM_DNS_ENABLE to nexus config.
- Implemented platform DNS APIs in nexus_dns.cpp, supporting
upstream server selection based on prefix lifetimes and reachability.
- Added UdpHook to Core to allow tests to intercept and simulate
responses for backbone UDP traffic on port 53.
- Updated InfraIf::Receive to call Core::HandleUdp for generic UDP
interception.
- Added raw buffer delivery overloads for InfraIf::SendUdp.
Test Implementation:
- Created test_1_4_DNS_TC_3.cpp which performs network formation,
RA signaling (PIO/RIO/RDNSS), and DNS resolution triggers.
- Created verify_1_4_DNS_TC_3.py to validate network behavior,
RA contents, and correct upstream query routing using pktverify.
- Integrated the new test into CMakeLists.txt and the default
run_nexus_tests.sh suite.
This commit updates the address-based node lookup methods in `Core`
to use the `FindMatching()` and `ContainsMatching()` methods provided
by the `LinkedList` class. This replaces manual `for` loops with
cleaner, built-in list operations.
To facilitate this, a new `AddressNetif` enum and a `Matches()` method
are added to the `Node` class. The `Matches()` method accepts an
`Ip6::Address` and an `AddressNetif` indicator, allowing it to check
if the node has the specified address on its Thread interface, its
Infrastructure interface, or any.
Additionally, a `const` overload for the `Get()` template method is
added to the `Node` class to ensure proper const-correctness.
This commit updates the IPv6 receive path in the Nexus platform to
utilize `OwnedPtr<Message>` for message lifecycle management. It
also removes the need for a large local buffer and redundant
message allocations.
Previously, `Node::HandleReceive()` copied the entire `otMessage`
payload into a local array, and `InfraIf::SendIp6()` allocated a new
`Message` to enqueue for transmission.
With this change:
- `Node::HandleIp6Receive()` wraps the received `otMessage` in an
`OwnedPtr<Message>`, ensuring proper cleanup upon exit without
explicitly calling `otMessageFree()`.
- The `Ip6::Header::ParseFrom` is used which reads and validates
the IPv6 header and the message.
- The hop limit is updated in-place within the `Message` using
`Write()` to overwrite previous header.
- `InfraIf::SendIp6()` accepts the `OwnedPtr<Message>` directly,
taking ownership and enqueuing it without requiring reallocation
or memory copying.
- Condition checks in `Node::HandleIp6Receive()` are reordered
to match the comment.
This commit updates `Node::Reset()` in the Nexus platform to correctly
set the IPv6 receive callback after the OpenThread `Instance` has been
re-initialized via placement `new`.
Previously, `otIp6SetReceiveCallback()` was called before the new
`Instance` was constructed, meaning the callback registration would
be lost when the instance memory was overwritten. Additionally, the
callback registration now passes the associated `Node` object as the
context.
This commit removes the active node tracking logic from the Nexus
simulation framework.
Previously, `Core` maintained a pointer to the `mActiveNode` and updated
it dynamically during processing and network events. This was necessary
so that log messages could be attributed to the correct node/instance.
With the recent introduction of "instance-aware logging" in the OpenThread
core, the logging mechanism natively knows which `otInstance` generated a
log. Therefore, manually tracking and context-switching the active node
in the Nexus framework is no longer required.
This change simplifies `nexus::Core`, removes context-switching overhead
from heavily utilized inline methods like `Node::Get<Type>()`, and allows
us to simplify the signature of `InfraIf::Receive()`.
Update mDNS traffic simulation in the Nexus platform to flow through
the simulated infrastructure link. This ensures mDNS packets are
automatically written to the PCAP file generated by the simulated
infrastructure link.
Changes:
- Wrap mDNS messages in UDP/IPv6 headers and enqueue them on the
simulated infrastructure interface (InfraIf).
- Implement a new SendUdp overload in InfraIf that accepts a Message
payload.
- Update InfraIf::Receive to intercept mDNS UDP packets (port 5353)
and deliver them to the Mdns module.
- Remove the dedicated ProcessMdns loop and manual PendingTx list from
Core and Mdns, consolidating traffic processing through InfraIf.
- Initialize Mdns with a reference to the Node to allow access to
InfraIf.
- Add GetMulticastAddress static helper to Mdns for 'ff02::fb'.
This commit implements the MATN-TC-12 test case in the Nexus
simulation framework to verify that a Primary BBR correctly
decrements the IPv6 Hop Limit when forwarding multicast packets
between the backbone link and the Thread network.
Key implementation details include:
- Implementation of MATN-TC-12 in C++ simulating a topology with a
Border Router (BR_1 as DUT), a Thread Router, and a Host.
- Enhancement of the Nexus platform to support hop limit processing:
- Updated InfraIf::Receive to decrement Hop Limit when forwarding
from the backbone to the Thread network.
- Updated Node::HandleReceive to decrement Hop Limit when forwarding
from the Thread network to the backbone.
- Added support for simulating packets with Hop Limit 0 by setting
mAllowZeroHopLimit in Node::SendEchoRequest.
- Addition of a Python verification script to validate:
- Multicast forwarding from backbone to Thread with decrement.
- Multicast forwarding from Thread to backbone with decrement.
- Dropping of packets with Hop Limit 1 (or 0) during forwarding.
- Use of unique ICMPv6 identifiers to reliably distinguish between
pings in different test steps.
- Inclusion of the full test specification as inline comments in
both the C++ and Python files.
- Registration of the new test case in tests/nexus/CMakeLists.txt
and tests/nexus/run_nexus_tests.sh.
This commit implements the MATN-TC-07 test case in the Nexus
simulation framework to verify default multicast forwarding
behavior on Border Routers.
Key implementation details include:
- Implementation of the MATN-TC-07 test scenario in C++ to
trigger various multicast ping requests across different
IPv6 scopes (realm-local, admin-local, site-local, global,
and link-local).
- Enhancement of the Python verification script to strictly
validate that only the Primary BBR forwards multicast
packets to the backbone link using Ethernet source address
filtering.
- Support for Ethernet link type in Nexus PCAP generation by
prepending Ethernet headers to infrastructure IPv6 packets.
- Exposure of infrastructure MAC addresses (ethaddrs) in the
test information JSON to enable identification of the
forwarding node on the backbone link.
- Support for verifying source addresses of MPL-encapsulated
multicast packets by checking both outer and inner headers.
- Addition of FindGlobalAddress() helper in the Nexus node
platform.
Implement the InfraIf class and associated platform logic to simulate
a shared infrastructure link (backbone) between Border Routers and
external hosts within the Nexus simulation environment.
Infra interface simulation:
- Implement shared Ethernet-like link for IPv6 traffic delivery.
- Add automated SLAAC address configuration based on ICMPv6 RAs.
- Support sending/receiving ICMPv6 Neighbor Discovery (RS, RA, NS, NA).
- Implement manual ICMPv6 checksum calculation for raw packets.
- Add infrastructure-level loop prevention and destination filtering.
- Provide helper methods to find nodes by infrastructure addresses.
Platform integration:
- Implement otPlatInfraIf APIs and integrate with otInstance.
- Use native Message and MessageQueue for pending traffic management.
- Add support for custom test variables in SaveTestInfo() JSON output.
- Update Node::Reset() to properly clear pending infra interface tasks.
Core enhancements:
- Add MulticastListenersTable::Has() to check for address presence.
- Add PrefixInfoOption::GetPrefixLength() and SetPrefixLength().
- Enable MLR and Backbone Router multicast routing in Nexus config.
This commit refactors Nexus test 1.2.LP.5.3.1 to better align with
the specification and improves the robustness of the test logic and
verification script. It also removes the kAsSsed join mode to favor
explicit CSL configuration in tests.
Changes:
- Removed kAsSsed from Nexus::Node::JoinMode and Node::Join() to
encourage tests to manage CSL parameters explicitly.
- Updated test_1_2_LP_5_3_1.cpp to join as a regular SED first and
enable CSL after attachment. This matches the specification's
requirement to establish synchronization via Child Update Request.
- Introduced constants in test_1_2_LP_5_3_1.cpp for CSL period,
synchronization time, and other parameters to avoid magic numbers.
- Enhanced verify_1_2_LP_5_3_1.py with comprehensive checks for:
- MLE Child Update Request/Response exchange.
- IEEE 802.15.4-2015 frame versions.
- ICMPv6 Echo Request/Response forwarding through the Leader.
- Absence of MAC Data Requests after CSL synchronization.
- Fixed an issue in verify_1_2_LP_5_3_1.py where packet numbers
were not correctly handled in pkts.range().
This commit adds a new Nexus test case 1.2.LP.5.3.1 which validates
SSED attachment and CSL synchronization.
Changes:
- Added kAsSsed JoinMode to Nexus::Node platform to support joining
as a Synchronized Sleepy End Device with default CSL parameters.
- Implemented test_1_2_LP_5_3_1.cpp following the test specification
for SSED attachment.
- Implemented verify_1_2_LP_5_3_1.py to verify pcap output, ensuring
correct use of 802.15.4-2015 frames and CSL synchronization.
- Updated CMakeLists.txt and run_nexus_tests.sh to include the new
test in the Nexus test suite.
This commit implements the otPlatAlarmMicro* platform APIs in the
Nexus simulation environment. It also transitions the simulation's
internal time base from millisecond to microsecond granularity to
ensure that both millisecond and microsecond alarms operate on a
consistent and shared time reference.
Changes include:
- Enabled OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE in Nexus config.
- Updated Nexus::Core to use a 64-bit microsecond time base (mNow).
- Implemented otPlatAlarmMicroGetNow, otPlatAlarmMicroStartAt, and
otPlatAlarmMicroStop.
- Refactored Nexus::Node to support separate millisecond and
microsecond alarm instances (mAlarmMilli and mAlarmMicro).
- Updated radio timestamps and PCAP logging to use the new high-
resolution microsecond time base.
- Adjusted simulation time advancement and alarm triggering logic to
handle both alarm types correctly.
This commit updates `Node::Join()` to allow specifying whether a node
joining as an SED should request the full network data or only the
stable subset via the `JoinMode` parameter.
Previously, `kAsSed` implicitly requested full network data. This
change updates `kAsSed` to request only the stable subset (the
default behavior for an SED). A new `kAsSedWithFullNetData` mode is
introduced to explicitly request full network data when joining as
an SED.
This change provides more flexibility in test scenarios, allowing
validation of SEDs with different network data requirements.
This commit updates the Nexus::Node::SetName(prefix, index) method
to use an underscore ('_') instead of a space between the prefix
and the index when generating the node name.
Corresponding verification scripts verify_5_2_3.py and
verify_5_2_4.py are also updated to match the new naming convention
when looking up nodes in the test environment.
All Nexus tests have been verified to pass with this change.
This commit adds the `Node::FindMatchingAddress()` helper method to the
`Nexus::Node` class. This method simplifies the process of finding a
unicast address on a node that matches a given IPv6 prefix.
This commit adds helper methods in Nexus to simplify ICMPv6 echo
exchanges:
- `Node::SendEchoRequest()`: sends an ICMPv6 Echo Request with
configurable parameters such as payload size and hop limit.
- `Core::SendAndVerifyEchoRequest()`: sends an Echo Request and
validates the matching Echo Reply within a timeout.
This commit also update various certification tests to use these
helpers, removing duplicate local utility functions.
Adds a new Nexus test case for 'Leader rejects CoAP Address Solicit
(2-hops from Leader)' (5.2.3) as specified in the test specification.
Summary of changes:
- Implemented Nexus test 5.2.3:
- Added test_5_2_3.cpp: Sets up a topology with a Leader, 31 routers
(fully connected to Leader), and a 32nd router (Router 32) that is
2-hops away from the Leader via Router 1. Verifies that the Leader
rejects the Address Solicit Request from the 33rd router with a
'No Address Available' status (1).
- Added verify_5_2_3.py: PCAP verification script for test 5.2.3.
Ensures the Address Solicit Request is sent by Router 32 to the
Leader, and that the Leader responds with a CoAP ACK containing
a Status TLV with value 1 (NL_NO_ADDRESS_AVAILABLE).
- Updated build and execution scripts:
- Modified CMakeLists.txt to build the new 5.2.3 test executable.
- Updated run_nexus_tests.sh to include 5.2.3 in the default test
list.
This commit adds a new mechanism to emulate a node reset on
`Nexus::Node`. This is realized by resetting all platform components
while ensuring the non-volatile `mSettings` remains unchanged, then
reinitializing the `ot::Instance` by invoking its constructor.
This is used to add a new `test_full_network_reset` test, which
emulates a full simultaneous reset of all nodes in a large network,
tracking how long it takes for the network to stabilize after the
reset event.
This commit enhances the TREL module to manage mDNS/DNSSD service
registration and peer discovery (browse and resolving for TREL
services). This feature can be controlled through
`OPENTHREAD_CONFIG_TREL_MANAGE_DNSSD_ENABLE` (and/or the CMake option
`OT_TREL_MANAGE_DNSSD`).
When enabled, TREL will utilize the `Dnssd` module, which provides
mDNS-related APIs. This can be tied to OpenThread's native mDNS
implementation or to `otPlatDnssd` (i.e., provided by the platform
layer).
This commit also adds support for the TREL platform in the `Nexus`
test framework and uses this to add a detailed `test_trel` case. This
test covers basic TREL peer discovery and operation, along with
specific scenarios such as peer removal delay, delayed mDNS start,
TREL service name conflict resolution, host address changes, and
supporting multiple services on the same host (while unlikely in
actual deployments, this can be useful for testing and simulation
where a single machine may act as multiple Thread nodes, thus
advertising multiple TREL services from the same hostname. This is
explicitly supported by the implementation and covered in the
tests).
This commit refactors the `Mle` modules and combines the `MleRouter`
and `Mle` classes into a single `Mle` class which now handles both
FTD and MTD functionalities.
The `MleRouter` and `Mle` classes were originally intended as
sub-classes, where the base class `Mle` would provide MTD and common
behaviors, and `MleRouter` would implement FTD-specific behaviors.
However, over the years and as new features were implemented, these
two classes became more intertwined, and the `Mle` class began to
include many FTD-related functions and interactions with `MleRouter`
private variables and methods.
This commit simplifies the code by combining the two into a single
class. The previous `mle_router.cpp` file is also renamed to
`mle_ftd.cpp` to indicate that it implements FTD-specific MLE
behaviors.
This commit introduces a new test framework named Nexus. The
framework includes the Nexus platform implementation that emulates
platform behavior, allowing multiple nodes running the OpenThread
core stack to be simulated and interact with each other within the
same process.
Unlike the simulation platform, where nodes run in separate processes
and interact via POSIX sockets, Nexus nodes are simulated within a
single process. Nexus tests can interact directly with the C++ or C
OT core APIs, providing more control than the simulation platform's
CLI-based interactions. The flow of time in Nexus tests is directly
controlled by the test itself, allowing for quick time interval
advancement.
This model allows for faster and more scalable simulations, enabling
quick simulation of larger networks for longer durations.
This commit introduces the basic platform implementation, including:
- `nexus_alarm`, `nexus_radio`, and `nexus_settings` modules.
- Logging support, allowing logs to be distinguished per emulated
node.