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 introduces gRPC support to the Nexus simulator, enabling
remote control and monitoring of simulations. This infrastructure allows
external tools and visualizers to interact with the simulated network
in real-time.
Key changes:
- Defined `simulation.proto` providing the `NexusService` definition for
simulation control and event streaming.
- Implemented `GrpcServer` in `nexus_grpc.cpp` which functions as a
Nexus simulation observer, pushing events to connected clients.
- Added RPCs for dynamic node creation, position updates, node state
control, and network orchestration (forming and joining).
- Implemented a real-time event stream that includes node state changes,
link updates, and packet captures (with basic protocol decoding).
- Introduced `nexus_native.cpp` as an entry point for a persistent
simulation server that can be controlled via gRPC.
- Updated `Core` and `Observer` interfaces to support a list of
concurrent observers instead of a single instance.
- Enhanced the CMake build system to optionally find and link against
gRPC and Protobuf, including automatic source generation.
- Updated CI (GitHub Actions) to include build and test steps for the
new gRPC functionality.
- Added comprehensive unit tests in `test_grpc.cpp` to verify all
exposed gRPC service methods.
This commit moves the `OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE`
configuration from the build scripts to the nexus-specific core
configuration header file.
Specifically:
- Added `#define OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE 1` to
`tests/nexus/openthread-core-nexus-config.h`.
- Removed `-DOT_MULTIPLE_INSTANCE=ON` from `tests/nexus/build.sh`.
- Removed `-DOT_MULTIPLE_INSTANCE=ON` from `tests/fuzz/oss-fuzz-build`.
This change centralizes nexus-specific configurations in the header
file, making the build scripts cleaner and ensuring consistent
configuration across different build environments that use the
nexus core config."
This commit introduces the ability to set and manage log levels on a
per-instance basis when dynamic logging is enabled, while maintaining
backward compatibility with existing logging behaviors.
The existing `otLoggingGetLevel()` and `otLoggingSetLevel()` APIs are
repurposed to manage the "global" log level. They continue to behave
exactly as before in both single-instance and multi-instance
configurations, ensuring that existing users of these APIs do not need
to change their implementations. To provide more granular control, new
APIs `otGetLogLevel()` and `otSetLogLevel()` are added to handle
per-instance log levels.
Specifically, this commit makes the following changes:
- Adds `mLogLevel` to `Instance` to track the instance-specific log
level.
- Renames the global log level static variable to `sGlobalLogLevel` and
introduces `GetGlobalLogLevel()` and `SetGlobalLogLevel()` to manage
it in a multi-instance configuration.
- Updates `otGetLogLevel()` and `otSetLogLevel()` APIs to handle
per-instance log level retrieval and configuration. If a specific
level is not set for an instance, it falls back to the global
log level.
- Adds `mIsLogLevelSet` to distinguish between an explicitly set
instance log level and the global fallback in multi-instance builds.
- Introduces `otPlatLogHandleLogLevelChanged()` platform callback to
notify the platform when an instance-specific log level is updated.
- Updates Nexus tests to use `SetGlobalLogLevel()` instead of the
deprecated instance `SetLogLevel()` method.
This commit implements CSL transmitter and receiver functionality in
the Nexus simulation platform. It enables the necessary OpenThread
configurations and provides the platform-level support for CSL.
It also implements the otPlatRadioGetNow platform API to provide a
high-resolution 64-bit microsecond time base, which is required for
accurate CSL timing and synchronization.
Changes:
- Added GetNowMicro64() to Nexus::Core to expose the raw 64-bit
microsecond timer.
- Implemented otPlatRadioGetNow() in nexus_radio.cpp.
- Enabled OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE and
OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE in Nexus config.
- Added otRadioContext to Nexus::Radio to track CSL parameters and
manage security material for radio operations.
- Implemented otPlatRadioEnableCsl, otPlatRadioResetCsl,
otPlatRadioUpdateCslSampleTime, and otPlatRadioGetCslAccuracy.
- Implemented otPlatRadioSetMacKey, otPlatRadioSetMacFrameCounter,
and otPlatRadioSetAlternateShortAddress to keep radio context
synchronized with OpenThread stack.
- Updated otPlatRadioSetExtendedAddress and otPlatRadioEnableCsl to
use AsCoreType for better readability and project conventions.
- Moved Radio member initializations to the initializer list in its
constructor.
- Refactored radio SFD processing: moved otMacFrameProcessTxSfd and
UpdateFcs from otPlatRadioTransmit (radio platform) to
Core::ProcessRadio (simulation engine), ensuring CSL IEs and
security headers are updated exactly when transmission starts.
- Enhanced Nexus::Core::ProcessRadio to support generating Enhanced
ACKs with CSL IEs for 802.15.4-2015 frames.
- Updated Nexus and fuzz build systems to include necessary Nexus
platform and utils headers/utilities.
Add `SuccessOrQuit()` to check the return `Error` value of
`RoutingManager::SetEnabled()` in `fuzz_*.cpp` source files. This
addresses warnings about ignoring the return value.
Rename all fuzzer source files in `tests/fuzz` from `{name}.cpp` to
`fuzz_{name}.cpp`.
Update the `ot_nexus_test` macro in `tests/fuzz/CMakeLists.txt` to
reflect this change, using `fuzz_{name}.cpp` as the source file while
naming the test `{name}-fuzzer`.
This change improves consistency and makes it easier to distinguish
fuzzer source files from other similarly named files during searches.
This change moves the management of the infrastructure interface state
out of the `RoutingManager` and centralizes it within the `InfraIf`
class. This makes `InfraIf` a more self-contained component and
simplifies the logic in `RoutingManager`.
The `RoutingManager` now depends on an initialized `InfraIf`. Its
`Init()` method is simplified and is now called from
`InfraIf::Init()`.
The public API `otBorderRoutingInit()` now directly initializes the
`InfraIf`. The `InfraIf::Init()` method is updated to support
re-initialization, allowing to switch to a new interface. When
switching, it ensures that components on the previous interface are
stopped before restarting on the new one.
Increases the `nexus.AdvanceTime()` in the CLI fuzzer test from 10 to
60 seconds to make the test more robust.
For example, the previous 10-second wait was not sufficient for
`Dns::Client` operations to complete, especially considering retries.
This could cause false fuzzer memory leak reports.
The Sequence Number Suppression field and AR can be both 1 in fuzz test,
in which case, the frame is not valid. And no ack should be expected.
This commit changes the expectation in this case.
The length of diag output messages is limited by the diag buffer size.
Developers have to change the diag buffer size to allow diag module to
output long messages. If diag output messages become longer and
longer, developers have to keep changing the diag buffer size.
This commit adds an output callback to diag module to output diag
messages. Then the length of diag output messages won't be limited by
the diag buffer size.
This commit fixes the typo and enables SRP_ADV_PROXY - also by turning
on the dependent components.
Signed-off-by: Łukasz Duda <lukasz.duda@nordicsemi.no>
This commit adds a generic SRP Advertising Proxy implementation to
OpenThread core, which uses a set of newly defined `otPlatDnssd`
platform APIs for DNS-SD (mDNS) support on infrastructure network on
a Border Router.
`Srp::Server` provides `ServiceUpdateHandler` callback mechanism that
allows platforms to implement their own advertising proxy function.
While this is still supported, the new generic advertising proxy
implementation makes it easier to port and support the proxy function
on new platforms. The platform needs to provide the DNS-SD platform
APIs, which are designed to be simple and easy to implement.
The `AdvertisingProxy` directly interacts with `Srp::Server` and its
registered `Host` and `Service` entries, tracking whether an entry
has been successfully advertised, is currently being advertised, or
has been replaced by a new registration.
The `AdvertisingProxy` ensures that consecutive SRP updates for the
same host or service are committed on the server in the order they
are received, even if their advertisements are finished in a
different order. This is important for SRP Replication support, as
the server may receive a large number of SRP updates back-to-back for
the same host.
The `AdvertisingProxy` will also register key records for SRP host and
service instance names. This will keep the claim on the name of a
removed entry while its key lease is not expired. It is also used
when an SRP host registration has no off-mesh routable address.
This commit adds a detailed unit test `test_srp_adv_proxy` that
validates the `AdvertisingProxy` under many scenarios. The test
covers a range of cases, including delayed registration callbacks and
timeouts, new registrations replacing outstanding advertisements,
platform DNS-SD state changes and failures, host address changes
adding/removing OMR addresses.
This feature allows the RCP to support multiple host stacks on different PANs
by making use of the spinel Interface ID.
Created unit tests for testing multipan feature with multiple ot-instance
support.
Based on Si-Labs PR #8914 by @parag-silabs, but a little different approach.
Instead of handling everything by a single sub-mac instance, multiple
OpenThread instances are created on RCP side that map to different IID.
Thanks to this there are separate data kept for each interface. Platform
is able to determine interface by ot instance pointer passed as an argument
to most of the API functions.
Tx/scan queue was removed as it is possible to request transmission in
parallel, it is up to the platform to decide if it should fail or queue
second tx or it has two radios available.
NOTE:
Platform needs to provide different otRadioFrame of each instance and
the processing needs to take into account the instance being used.
Signed-off-by: Marek Porwisz <marek.porwisz@nordicsemi.no>
Add a new `OT_RADIO_CAPS_RX_ON_WHEN_IDLE` radio capability which lets
OpenThread know what the radio idle state operation will be: receive
or sleep.
This allows to save power on sleepy devices since the active --> idle
transition is much faster, specially for the cases in which there is
some kind of serialization between OpenThread core and the radio
driver.
This commit introduces `Server` and `Client` classes breaking the
`NetworkDiagnostic` module into two components. The `Server` responds
to queries and requests (handling Net Diag TMF commands), while
`Client` issues queries/requests and processes responses. The
`Server` is available under both FTD and MTD (which follows the
requirement of Thread spec). The client is enabled using newly added
`OPENTHREAD_CONFIG_TMF_NETDIAG_CLIENT_ENABLE` config option which is
also available as `OT_NETDIAG_CLIENT` CMake option or the autoconf
build switch `NETDIAG_CLIENT`. The client functionality is by default
enabled on Border Routers (tied to `CONFIG_BORDER_ROUTING_ENABLE`
config).
The previous `TMF_NETWORK_DIAG_MTD_ENABLE` config is now removed
along with its CMake `OT_MTD_NETDIAG` and autoconf switch. This
commit adds checks to trigger build error if the previous config
and/or its related CMake option are used.
This commit contains changes to child supervision feature. It adds a
new mechanism for a child to inform its desired supervision interval
to its parent. A new optional MLE TLV is added with type 27 and value
of `uint16_t` indicating the supervision interval in seconds. This
TLV is included in MLE Child ID Request and MLE Child Update Request
(sent from the child). The parent echoes back this TLV in the
corresponding responses to indicate that it supports supervision. This
commit changes the parent implementation to track the supervision
interval per child.
This commit also updates the OT public APIs along with the related
CLI commands:
- API now allows the supervision interval to be set on a child.
- New field in `otChildInfo` to indicate the child's supervision
interval.
- New counter is added to track the number of supervision check
timeouts failures on a child (intended for testing and debugging).
This commit adds a test `test_child_supervision` to cover behavior of
child supervision and its new behaviors.
This change allows backward compatibility: If the parent does not
support child supervision, it ignores the new TLV in the MLE messages
and the child would fall back to periodically exchanging MLE Child
Update Request with parent. If the child does not support supervision
and/or does not indicate its desired child supervision interval, the
parent will fall back to use the configured default interval.
This commit makes the core pass the sensitive keys to the platform
settings initialization, so that the platform settings implementation
can know which keys are sensitive keys during the initializing and do
the migration when needed.
This commit adds a new module `Uptime` which tracks the number of
milliseconds since OpenThread stack initialization as an `uint64_t`
value. It also adds public OT APIs to get the current uptime value
(either as the number of milliseconds or in human-readable string
format like "2 days 12:45:12.762"). A CLI `uptime` command is also
added. This feature can be enabled using the newly added config
option `OPENTHREAD_CONFIG_UPTIME_ENABLE` (or the related CMake
`OT_UPTIME` option).
This commit adds History Tracker feature and its CLI support. This
feature records history of different events as the Thread network
operates (e.g., history of RX and TX IPv6 messages or network info
changes).
Recorded entries are timestamped. When the history list is read, the
timestamps are given as the entry age relative to the time the list
is being read. For example in CLI a timestamp can be shown as
`02:31:50.628 ago` indicating the entry was recorded 2 hours, 31 min,
50 sec, and 628 msec ago. Number of days is added for events that are
older than 24 hours, e.g., `31 days 03:00:23.931 ago`. Timestamps use
millisecond accuracy and are tacked up to 49 days. If an event is
older than 49 days, the entry is still tracked in the list but the
timestamp is shown as old or `more than 49 days ago`.
The `HistoryTracker` currently maintains 3 lists. The Network Info
history tracks changes to Device Role, Mode, RLOC16 and Partition ID.
The RX/TX history list records information about the received/sent
IPv6 messages:
- Message type (UDP, TCP, ICMP6 (and its subtype), etc.)
- Source and destination IPv6 addresses and port numbers
- IPv6 payload length
- The message checksum (for UDP, TCP, or ICMP6).
- Whether or not the link-layer security was used
- Message priority: low, norm, high, net (for control messages)
- Short address (RLOC16) of neighbor who send/received the msg
- Received Signal Strength (in dBm) for RX only
- Radio link info (15.4/TREL) on which msg was sent/received
(useful when `OPENTHREAD_CONFIG_MULTI_RADIO` is enabled)
Config `HISTORY_TRACKER_EXCLUDE_THREAD_CONTROL_MESSAGES` can be used
to configure `HistoryTracker` to exclude Thread Control message
(e.g., MLE, TMF) from TX and RX history.
The number of entries recorded for each history list is configurable
through a set of OpenThread config options, e.g., number of entries
in Network Info history list is specified by OpenThread config option
`OPENTHREAD_CONFIG_HISTORY_TRACKER_NET_INFO_LIST_SIZE`. The
`HistoryTracker` will keep the most recent entries overwriting oldest
ones when the list gets full.
This commit also adds support for `HistoryTracker` in CLI. The CLI
commands provide two style for printing the history information: A
table format (more human-readable) and list style (better suited for
parsing by machine/code). `README_HISTORY.md` is added to document
the commands and the info provided by each history list entry.
This commit also adds `test_history_tracker.py` test-case which
covers the behavior of `HistoryTracker`.
This commit implements a new feature "Network Data Publisher" which
provides mechanisms to limit the number of similar entries (service
and/or prefix) in the Thread Network Data by monitoring the Network
Data and managing if or when to add or remove entries. This feature is
enabled using `OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE` config, or
`NETDATA_PUBLISHER` in autoconf, or `OT_NETDATA_PUBLISHER` cmake
option.
This commit adds support for publishing DNS/SRP anycast/unicast
service, on-mesh prefix, and external route prefix entries.
When there is a request to publish an entry, the `Publisher` monitors
the Network Data and counts the number of similar entries. If there
are fewer entries than a desired target number, the entry is added
after a short random delay.
If there are too many similar entries, `Publisher` starts the process
of removing its own entry (again after some random wait time). When
removing entries, certain entries are preferred over others (e.g., an
entry from a router over one from an end-device or if they are from
the same type of node, the one with smaller RLOC16). If `Publisher`
determines that its own entry is a preferred one, it adds an extra
wait time before removing its entry. This gives higher chance for a
non-preferred entry from another device to be removed before removing
a preferred entry which helps towards quicker convergence of the
process to the desired number of entries.
On-mesh prefix and external route entries have a "preference" field.
When publishing such an entry, a matching entry in the network data is
counted only if its preference is same or higher than the entry's
preference. This ensures that a device with a higher preference entry
publishes its entry even when there are many lower preference similar
entries in the network data (potentially causing a lower preference
entry to be removed).
This commit also adds `test_netdata_publisher.py` to verify the
behavior of the `Publisher`.
This commit removes application library CLI/NCP dependency on platform
layer UART APIs. Instead, application layer provides callbacks sending
CLI/NCP data.
With this change, platforms with native support for formatted output
can simply implement the CLI output callback with something like
`vprintf()`.