Compare commits

..

498 Commits

Author SHA1 Message Date
Abtin Keshavarzian da08ac73fd [netdiag] refactor network diagnostics TLV parsing (#13247)
This commit refactors the TLV parsing logic within the Network
Diagnostics `Client`.

The monolithic `GetNextDiagTlv` method has been refactored. The large
switch statement that parsed individual TLV payloads was extracted
into a dedicated `ParseDiagTlv` helper method. This separation of
concerns cleans up the `while` loop that iterates over TLVs,
improving readability and making future TLV parsing updates easier.
The new `ParseDiagTlv()` method can also be used in the future by
other modules such as `MeshDiag`.

Additionally, `ParseEnhancedRoute()` was refactored and simplified
to be a member method instead of a static standalone function,
utilizing the newly introduced `EnhRoute` typedef.
2026-06-16 08:52:59 -05:00
Abtin Keshavarzian 9c8374a44c [netdiag] extract answer sending logic into AnswerSender (#13242)
This commit introduces the `NetDiag::AnswerSender` class to manage the
transmission of multipart CoAP answer messages for Network Diagnostics
and History Tracker queries.

Previously, both `NetDiag::Server` and `HistoryTracker::Server`
contained duplicated logic to queue allocated answer messages, track
responses, and send subsequent messages one by one using an internal
CoAP message queue.

By extracting this into the new `AnswerSender` class, it eliminates the
redundancy in message queue management, freeing of related answers, and
CoAP response handling across both modules. The `AnswerSender` takes
ownership of the messages generated by an `AnswerBuilder` and manages
the asynchronous transmission lifecycle.
2026-06-16 08:39:05 -05:00
Yakun Xu 0a6d0e793f [radio] remove unused mCslPresent (#13232)
This commit removes RadioContext.mCslPresent. Instead we directly
check whether the CSL is in the frame data, so there is not risk of
mismatch.
2026-06-15 09:38:43 -05:00
Abtin Keshavarzian a411e563d6 [mle] remove unused router threshold variables (#13239)
This commit removes `mRouterUpgradeThreshold` and
`mRouterDowngradeThreshold` from the `Mle` class. These variables
were previously moved into the `RoleTransitioner` class, but their
declarations in `Mle` were left behind. Removing them cleans up the
class definition and eliminates unused state.
2026-06-15 09:31:47 -05:00
Abtin Keshavarzian f833942769 [netdiag] extend AnswerBuilder to support HistoryTracker (#13235)
This commit extends the `NetDiag::AnswerBuilder` class to support
generating and managing answer messages for the `HistoryTracker` module.

This refactor eliminates redundant implementation in
`HistoryTracker::Server`, removing its internal `AnswerInfo` struct
and related message allocation and length checking methods, replacing
them with the unified `NetDiag::AnswerBuilder` workflow.
2026-06-15 09:30:22 -05:00
dependabot[bot] bf9d441ebd github-actions: bump step-security/harden-runner from 2.14.2 to 2.19.4 (#13246)
Bumps [step-security/harden-runner](https://github.com/step-security/harden-runner) from 2.14.2 to 2.19.4.
- [Release notes](https://github.com/step-security/harden-runner/releases)
- [Commits](https://github.com/step-security/harden-runner/compare/5ef0c079ce82195b2a36a210272d6b661572d83e...9af89fc71515a100421586dfdb3dc9c984fbf411)

---
updated-dependencies:
- dependency-name: step-security/harden-runner
  dependency-version: 2.19.4
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-15 09:24:53 -05:00
Abtin Keshavarzian 252918bf10 [tmf] introduce SendResponseWithStateTlv() helper (#13238)
This commit adds `SendResponseWithStateTlv()` to `Tmf::Agent` to
streamline sending TMF responses that consist solely of a `StateTlv`.

By encapsulating message allocation, TLV appending, and message
transmission into a single method, this reduces duplicate boilerplate
code across `DatasetManager`, `Leader`, and `NetworkData::Leader`.
2026-06-12 10:47:40 -07:00
Abtin Keshavarzian b1d4150426 [posix] implement otPlatTcp platform abstraction (#13193)
This commit provides a complete POSIX implementation of the new
`otPlatTcp` platform abstraction APIs. It leverages the existing
OpenThread `Mainloop` polling mechanism to build a fully event-driven,
non-blocking TCP socket implementation without requiring extra threads.

Key features and implementation details:
- Uses `Mainloop` read/write/error sets to monitor socket states.
- Implements `otPlatTcpEnableListener` and `otPlatTcpAccept` to handle
  incoming connection requests over IPv6.
- Implements `otPlatTcpConnect` for asynchronous non-blocking outgoing
  TCP connections, monitoring `SO_ERROR` to detect handshake completion.
- Handles data transmission utilizing `otPlatTcpIsTxPending` to
  monitor the write descriptor and correctly signal `HandleTxReady`.
- Implements `otPlatTcpSend` and `otPlatTcpReceive` ensuring proper
  buffering, suppressing `SIGPIPE` safely using `SO_NOSIGPIPE` and
  `MSG_NOSIGNAL`.
- Encodes socket file descriptors directly within the platform data
  `mData.mDescriptor` union, avoiding dynamic memory allocation.
2026-06-11 20:22:29 -07:00
Jonathan Hui fcf7b4cef5 [spi-hdlc-adapter] define explicit worst-case HDLC frame size macro (#13237)
This commit replaces the implicit sizing of `escaped_frame_buffer`
with an explicit macro `HDLC_MAX_FRAME_SIZE` in the standalone
`spi-hdlc-adapter` tool.

Previously, `escaped_frame_buffer` was sized statically to
`MAX_FRAME_SIZE * 2` (4096 bytes). While this size is mathematically
sufficient to hold a worst-case escaped payload (4091 bytes for a
2043-byte max payload, 4 escaped CRC bytes, and 1 flag byte), it was
not self-documenting and relied on implicit math.

This commit defines `HDLC_MAX_FRAME_SIZE` explicitly as:
`((MAX_FRAME_SIZE - HEADER_LEN) * 2 + 5)`
making the worst-case framing overhead bounds clear and robust to
any future changes to the constants.
2026-06-11 18:00:57 -07:00
Jonathan Hui 11acd4a26e [posix] fix SPI platform driver sanity check boundaries (#13236)
This commit corrects the SPI frame sanity checks in the POSIX platform
driver (`spi_interface.cpp`).

Previously, the sanity checks compared `mSpiSlaveDataLen` and
`slaveAcceptLen` against `kMaxFrameSize` (8192). However,
`mSpiSlaveDataLen` is the payload size, which excludes the 5-byte SPI
frame header. If the slave advertised a data length of exactly
`kMaxFrameSize` (8192), it would pass the sanity check, but the
subsequent `DoSpiTransfer` would request a transfer length of
`kMaxFrameSize + kSpiFrameHeaderSize + alignment` (e.g. 8213 bytes).
This would cause an out-of-bounds read on `mSpiTxFrameBuffer` which is
sized `kMaxFrameSize + kSpiAlignAllowanceMax` (8208 bytes).

This commit updates the sanity checks to use
`kMaxFrameSize - kSpiFrameHeaderSize` as the maximum allowed payload
length, ensuring that worst-case transfers always fit within the
tx buffer allocation.
2026-06-11 18:00:38 -07:00
evilgensec 1f8d922465 [spi-hdlc-adapter] validate RCP frame lengths against the MTU (#13206)
The slave (RCP) controls the `data_len` and `accept_len` fields of the SPI
header. Both carry a payload length that excludes the 5-byte header, as
shown by `sMTU = MAX_FRAME_SIZE - HEADER_LEN`, so the largest valid value
is the MTU, `MAX_FRAME_SIZE - HEADER_LEN`.

The two sanity checks in `push_pull_spi()` only rejected values greater
than `MAX_FRAME_SIZE`, allowing an RCP to advertise a length in the range
(MAX_FRAME_SIZE - HEADER_LEN, MAX_FRAME_SIZE]. That value flows into
`spi_xfer_bytes`, and `do_spi_xfer()` then transfers
`spi_xfer_bytes + HEADER_LEN + sSpiRxAlignAllowance` bytes into
`sSpiRxFrameBuffer` / `sSpiTxFrameBuffer`. Those buffers are sized
`MAX_FRAME_SIZE + SPI_RX_ALIGN_ALLOWANCE_MAX`, so the extra HEADER_LEN
added by the transfer can write up to 5 bytes past the end of both.

Clamp both checks to `MAX_FRAME_SIZE - HEADER_LEN` so the advertised
payload plus the header always fits within the existing buffers.
2026-06-11 16:18:19 -07:00
Jake Swensen 5e68d008b5 [posix] add build time config of netinf loss (#13192)
Allow build time configuration of `OPENTHREAD_POSIX_CONFIG_EXIT_ON_INFRA_NETIF_LOST_ENABLE`
2026-06-11 11:50:41 -07:00
Abtin Keshavarzian 0fbee98fd5 [crypto] simplify AesCcm public APIs and introduce internal Engine (#13215)
This commit refactors the `AesCcm` class to simplify its public interface,
decoupling the high-level API from the underlying cryptographic execution.

Key improvements:
- Redesigned the API from a series of procedural method calls
  (`Init()`, `Header()`, `Payload()`, `Finalize()`) into a unified,
  stateful model. Callers now pre-configure the operation parameters using
  dedicated setters (`SetKey()`, `SetNonce()`, `SetAuthData()`,
  `SetTagLength()`) and execute the entire cryptographic operation in a
  single step via unified `Process()` methods.
- Introduced a nested `Engine` class to encapsulate the low-level AES-CCM
  mathematical and cryptographic state. The `Engine` provides clean internal
  interfaces for both optimized one-shot (single-part) and multi-part
  operations.
- This architectural separation allows the outer `AesCcm` class to focus on
  parameter validation, high-level buffer management, and complex `Message`
  chunk iterations, while the `Engine` remains focused purely on the
  cryptographic core. This also provides a clean extension point to easily
  route one-shot operations to platform-specific hardware acceleration APIs
  in the future.
- Updated `Mac` and `Mle` modules to use the simplified APIs, reducing
   boilerplate code.
- Retained a static `Perform()` wrapper to support the legacy public
  `otCrypto` API.
- Updated unit tests to validate the new stateful interfaces, including
  robust in-place message chunk processing and separate-buffer
  validations.
2026-06-10 10:24:34 -07:00
Abtin Keshavarzian a055c4b9b8 [platform] define otPlatTcp platform abstraction APIs (#13175)
This commit introduces a new platform abstraction layer for TCP
connections and listeners, enabling OpenThread to leverage platform-
provided TCP stacks. The API is designed for asynchronous, event-driven
environments and can easily support POSIX as well as various embedded
network stacks.

In the core, `Ip6::PlatTcp` and its nested `Connection` and `Listener`
classes are introduced to manage these platform interactions, providing
a clean C++ interface for the OpenThread core. The `PlatTcp` manager
is integrated into the `Instance` class and utilizes `Tasklet` for
asynchronous resource cleanup.

Additionally, this commit adds a comprehensive unit test to verify the
TCP platform abstraction and `Ip6::PlatTcp` implementation. The tests
cover listener and connection lifecycles, data flow, flow control,
incoming connection acceptance, and active object iteration.
2026-06-10 10:23:06 -07:00
Abtin Keshavarzian 1b80561802 [mle] introduce AesCcmAuthData for message security processing (#13210)
This commit refactors `Mle::ProcessMessageSecurity()` to use a new packed
structure, `AesCcmAuthData`, to represent the authenticated data used during
AES-CCM security processing.

The `AesCcmAuthData` structure encapsulates the sender and receiver IPv6
addresses along with the Auxiliary Security Header. By packing these fields
together, we can pass them as a single contiguous buffer to `AesCcm::Header()`.
This eliminates the need for multiple separate calls to `AesCcm::Header()`
and allows the removal of the generic template-based `Header<ObjectType>()`
method in the `AesCcm` class.

Callers to `ProcessMessageSecurity()` have been updated to populate the
`AesCcmAuthData` structure before passing it for processing.
2026-06-09 08:40:38 -07:00
Abtin Keshavarzian a49c1f5c98 [mle] introduce ComposeMeshLocalAddress() helper method (#13225)
This commit introduces a new `ComposeMeshLocalAddress()` helper method
in the `Mle` class. This method constructs a full IPv6 Address by
combining the Mesh-Local Prefix with a provided Interface Identifier (IID).

By using this helper, we eliminate the repetitive two-step process of
calling `SetPrefix()` followed by `SetIid()` previously scattered across
`Commissioner`, `AddressResolver`, `Child`, and unit tests. This
improves code readability and correctly encapsulates address composition
logic within the `Mle` module.
2026-06-08 20:44:46 -07:00
Abtin Keshavarzian c238bd9a62 [ip6] remove InitAsRoutingLocator and InitAsAnycastLocator (#13222)
This commit replaces `Ip6::Address::InitAsRoutingLocator()` and
the now unused `Ip6::Address::InitAsAnycastLocator()` with the
single unified method `Ip6::Address::InitAsLocator()`.

Callers in `Mle` have been updated to use the unified method.
2026-06-08 19:43:31 -07:00
Abtin Keshavarzian 8abf9667c3 [common] refactor FrameBuilder and FrameData to use templated API (#13216)
This commit refactors the `FrameBuilder` and `FrameData` modules,
replacing multiple distinct endian-specific methods with a unified,
type-safe templated API.

Key changes:
- Introduced `enum Encoding` (`kBigEndian`, `kLittleEndian`) and a
  templated `HostSwap<Encoding, UintType>` helper in `encoding.hpp` to
  centralize byte-swapping logic.
- Replaced `AppendBigEndianUint16()`, `AppendLittleEndianUint32()`,
  and other variations in `FrameBuilder` with a single templated
  method: `AppendUint<Encoding, UintType>()`.
- Replaced `ReadBigEndianUint16()`, `ReadLittleEndianUint32()`,
  and other variations in `FrameData` with a single templated
  method: `ReadUint<Encoding, UintType>()`.
- Updated all callers in `Lowpan` and `Mac` modules to use the new
  templated encoding APIs.
- Updated `test_frame_builder.cpp` to validate the new syntax.
2026-06-08 19:34:19 -07:00
Abtin Keshavarzian 87b971ef96 [child-table] use Array to manage mChildren (#13217)
This commit replaces the raw array `mChildren` in `ChildTable` with
the `Array` class from the common utilities.

By switching to `Array`, we can leverage its built-in array management,
bounds checking, and iterator support. This removes boilerplate code
associated with keeping track of `mMaxChildrenAllowed` and simplifies
methods like `GetChildAtIndex`, `FindChild`, `HasChildren`, and
`GetNumChildren` by using `Array` methods.

Additionally, the commit renames `Neighbor::MatchesFilter()` to simply
`Neighbor::Matches()`, which aligns with the expected indicator matching
API used by `Array` and `LinkedList`.
2026-06-08 19:33:49 -07:00
Jonathan Hui 44f5382330 [mac] update HasCslIe and refactor GetTimeIe for robust IE parsing (#13224)
This commit introduces two robustness improvements to Header Information
Element (IE) parsing in Frame:

1. Aligned HasCslIe() with GetCslIe():
Previously, HasCslIe() returned true if a Header IE matching the CSL ID
was present, regardless of whether its declared content length was valid
(>= 4 bytes). Updating HasCslIe() to check GetCslIe() != nullptr ensures
that presence checks enforce the same length validation as retrieval,
preventing callers from assuming a malformed CSL IE is valid.

2. Robust Multi-Vendor IE Iteration in GetTimeIe():
GetTimeIe() previously retrieved the Vendor IE by matching ID 0x00
using GetHeaderIe(), which returns only the first matching element. If
a frame contained multiple Vendor IEs (e.g., a standard Thread Vendor IE
followed by a Nest Time Vendor IE), GetTimeIe() inspected only the
first element, failed the OUI check, and returned nullptr. GetTimeIe()
is refactored to iterate through all Header IEs until a matching Nest
OUI and Time SubType are found, ensuring correct discovery across
multi-vendor frames.
2026-06-08 19:33:10 -07:00
Esko Dijk 2d602dcd9c [ble] update BLE API docs to make platform's BLE advertising explicit (#12913)
Also, changes term 'method' to correct term 'function'.
2026-06-08 14:47:21 -07:00
Esko Dijk baaf93a74f [tcat][ble] update BLE API with missing error status values and aInterval details (#12913)
Both otPlatBleGapAdvSetData() and otPlatBleGapAdvUpdateData() now have the same set of retvals.
The aInterval parameter is explained better: it's a request/hint to the BLE platform for the
advertising interval, but not a requirement.
2026-06-08 14:47:21 -07:00
Esko Dijk 926dc828d2 [tcat][ble] improve internal state management of ble simulation platform (#12913)
This adds sIsEnabled for more realistic BLE simulation platform behavior. Also
improves internal disconnection state management, per review comments.

Adds asynchronous calling of otPlatBleGapOnDisconnected() to avoid doing the
'disconnected' callback twice, per review comments. A unit test is extended to
verify that the callback happens once.

For test_platform.cpp 2 instances of '#ifdef' are fixed to '#if'.
2026-06-08 14:47:21 -07:00
Esko Dijk ec498f0c0e [tcat][ble] introduce notifier events to update TCAT advertisement data / use bool for advertising state (#12913)
To get an update of TCAT advertisement data when the active dataset changes, notifier events are
introduced. This also refactors the existing adv update on MLE role change to use a notifier event.

This update now covers all cases where an application/CLI/user changes the active dataset, which should
be then reflected in TCAT advertisement flag values.

The 'requested advertising state' is refactored from a BleState to a bool, to make the code more
readable and avoid subtle errors.
2026-06-08 14:47:21 -07:00
Esko Dijk 9403edeaaf [tcat][ble] Fix BLE advertisement contents after Commissioner disconnect (#12913)
This fixes the issue observed in tests, that the BLE advertisement contents (flags) were not updated
after a TCAT Commissioner disconnects. A unit test is added for BLE advertisement contents to
validate the advertisement data changes.

It also adds an explicit 'disconnect' CLI command to the TCAT expect tests, which wasn't tested
before.
2026-06-08 14:47:21 -07:00
Esko Dijk fee7292f15 [tcat][ble] update BLE API and related TCAT agent change to re-enable advertising after disconnect (#12913)
This fixes some ble.h issues and makes explicit that BLE advertising will stop once a client connects.
The TCAT agent is updated to re-enable advertising after a client disconnects (in the default case).
This fixes an issue observed in cert tests. For easier testing in the future, debug log messages are
added for the simulation BLE platform.

The simulation platform (ble.c) is improved to act more like a real BLE platform, by now supporting
client connection state and calling of otPlatBleGapOnConnected() and otPlatBleGapOnDisconnected().
This is required to manually test the TCAT Commissioner/Device flow in Posix simulation.
2026-06-08 14:47:21 -07:00
Adil Burak Şen c801d291b3 [mac] validate Header IE content length before reading IE structs (#13184)
GetThreadIe(), GetCslIe(), and GetTimeIe() read a fixed content struct
(VendorIeHeader / CslIe / TimeIe) at `ie + sizeof(HeaderIe)` after
matching the IE id, without first checking that the IE's Length field
covers that struct. FindPayloadIndex() only guarantees the IE header
plus its declared Length fit within the frame, so a matching IE whose
Length is shorter than the content struct (e.g. a zero-length vendor IE
placed at the end of the header-IE region) causes a read past the IE
content, and past the PSDU buffer when the IE ends at the frame
boundary.

Gate each content read on the IE Length being at least the
corresponding kIeContentSize before dereferencing the struct.
2026-06-08 14:30:09 -07:00
Abtin Keshavarzian 9b180d4c09 [crypto] introduce AesCcm::Nonce for IEEE 802.15.4 nonce (#13208)
This commit introduces the `AesCcm::Nonce` class to represent the IEEE
802.15.4 nonce byte sequence, replacing the previous `GenerateNonce()`
method which operated on a raw byte array.

Replacing `uint8_t *` buffers and `kNonceSize` with a dedicated, packed
`Nonce` class makes the code cleaner and prevents potential buffer size
mismatches at call sites. The new class provides an `InitFrom()` method
to safely initialize the nonce from an extended address, frame counter,
and security level.

All callers in `Mac` (frame transmission and reception) and `Mle`
(message security) have been updated to use the new `Nonce` class.
2026-06-08 14:21:27 -07:00
Jonathan Hui 260f44f2d3 [mesh-forwarder] evict insecure reassembly messages first (#13211)
Enhance `MeshForwarder::EvictMessage` to prioritize evicting messages
from `mReassemblyList` that were received without link security when
reclaiming message buffers (reason `kEvictReasonNoMessageBuffer`).

This helps protect secure messages in the send queue from being
evicted due to buffer exhaustion, by prioritizing the dropping of
insecure, potentially incomplete, reassembled fragments.

Both FTD and MTD implementations of `EvictMessage` are updated.
2026-06-08 13:00:02 -07:00
dependabot[bot] 709a1b00a3 github-actions: bump docker/setup-buildx-action from 3.11.1 to 4.1.0 (#13220)
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 3.11.1 to 4.1.0.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/e468171a9de216ec08956ac3ada2f0791b6bd435...d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-version: 4.1.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-08 12:49:39 -07:00
Jonathan Hui 21c983f0fb [github-actions] update codecov-action pin to fb8b358 (v7.0.0) (#13221)
This commit updates the commit hash pin for codecov/codecov-action
from 671740a (v5.5.2) to fb8b358 (v7.0.0) across all CI workflows.

Workflows updated:
- otbr.yml
- posix.yml
- simulation.yml
- toranj.yml
- unit.yml
2026-06-08 11:06:07 -07:00
Abtin Keshavarzian 1316bcebc8 [mle] introduce ComposeRloc() and ComposeAloc() (#13199)
This commit introduces `ComposeRloc()` and `ComposeAloc()` in the `Mle`
module and updates the codebase to use them.

These methods streamline the construction of Routing Locators and
Anycast Locators by automatically combining the Mesh-Local Prefix with
the provided RLOC16 or ALOC16. This centralizes address composition
logic within `Mle` instead of relying on manually formatting
`Ip6::Address` instances across various modules.
2026-06-08 09:12:47 -07:00
Jonathan Hui 318b4b0771 [bbr] remove domain prefix support from stack and harness (#13203)
This commit removes all Domain Prefix configuration and management logic
from the OpenThread stack, CLI commands, unit tests, and GRL harness
THCI wrapper.

- Removed public Backbone Router Domain Prefix APIs.
- Removed Domain Prefix flag ('mDp') and 'D' flag parser/formatter
  from core network data types, Spinel, and CLI.
- Cleaned up local Backbone Router and Leader logic to exclude Domain
  Prefix configuration, tracking, and events.
- Updated RoutingManager prefix advertisement (RIO) to exclude
  special handling for Domain Prefix.
- Updated CLI documentation to remove Domain Prefix references.
- Removed domain prefix helper methods from python test certification
  scripts.
- Removed auto-addition of default domain prefix and D flag support
  from GRL harness OpenThread.py.
2026-06-04 19:36:33 -07:00
Jonathan Hui c4a85578f5 [mle] validate peer extended address in Link Accept (#13207)
This commit ensures that the peer's extended address matches the stored
extended address when receiving a Link Accept for an already valid link,
preventing unintended frame counter resets and neighbor table updates.

To achieve this:
- We validate that the peer's extended address (extracted from the
  IPv6 peer address IID) matches the router's stored extended address
  when processing Link Accepts for a neighbor that is already in the
  kStateValid state. If there is a mismatch, the packet is rejected
  with kErrorSecurity.
- We gate InitNeighbor() and the resetting of MLE frame counters
  so they only execute if the neighbor is not already kStateValid.
  For valid neighbors, we only update link statistics (RSS, last
  heard, link quality, key sequence) and clear the Link Accept
  timeout without modifying the frame counters or average RSS history.
2026-06-04 13:33:07 -07:00
Abtin Keshavarzian b72d7144ee [cli] refactor IPv6 address parsing and synthesis helper (#13205)
This commit renames the static helper `Utils::ParseToIp6Address()` to
`Utils::ParseOrSynthesizeIp6Address()` to better reflect its behavior
of parsing an IPv6 address or synthesizing one from an IPv4 address
via NAT64.

Additionally, the method is refactored into a non-static member of the
`Utils` class. This eliminates the need to manually pass the `otInstance`
pointer, as the `Utils` class already maintains it. The internal
implementation is also simplified to reduce nesting by exiting early
upon successful IPv6 address parsing.

All callers in the CLI module (TCP, UDP, Ping, DNS) have been updated
to use the new member method.
2026-06-03 19:19:25 -07:00
Abtin Keshavarzian b2093f4f9e [dns] check for null character in read label (#13187)
This commit updates `Name::LabelIterator::ReadLabel()` to explicitly
check that the read label from the message does not contain any embedded
`kNullChar` (`\0`) characters. It uses `StringLength()` to verify that
the length of the string matches the expected label length. If a null
character is found before the end of the label, `kErrorParse` is
returned to prevent potential string truncation issues or
misinterpretation of the label name.

This broader check replaces a recent fix in `PtrRecord::ReadPtrName()`
from #13183 which only verified that the first label was not empty
or malformed by checking for a single-character label with a null
byte. By enforcing this validation centrally at the `ReadLabel()`
level, we now ensure that labels of any length are properly
protected against embedded null characters across all DNS record
types.
2026-06-03 14:55:20 -07:00
Abtin Keshavarzian 15e1c233bf [tests] simplify RLOC address creation using GetMeshLocalRloc() (#13198)
This commit refactors several Nexus diagnostic test cases to use the
existing `Mle::GetMeshLocalRloc()` method instead of manually assembling
the RLOC by combining the mesh-local prefix and the node's RLOC16. This
improves code readability and adheres to the standard pattern for
retrieving a node's Routing Locator.
2026-06-03 14:45:42 -07:00
Abtin Keshavarzian 3d7b9fb686 [mle] rename Get{Addr}() to Compose{Addr}() (#13197)
This commit renames several methods in the `Mle` class that construct
an IPv6 address from the mesh-local prefix and an RLOC16/ALOC16 from
`Get...()` to `Compose...()` to better reflect their behavior.

The affected methods are:
- `GetLeaderRloc()` -> `ComposeLeaderRloc()`
- `GetLeaderAloc()` -> `ComposeLeaderAloc()`
- `GetCommissionerAloc()` -> `ComposeCommissionerAloc()`
- `GetServiceAloc()` -> `ComposeServiceAloc()`
2026-06-03 14:42:43 -07:00
Abtin Keshavarzian ab3c6600a0 [icmp6] use Icmp6Header instead of Icmp::Header (#13194)
This commit updates the codebase to use the `Icmp6Header` type
directly, replacing the nested `Ip6::Icmp::Header` definition.
This change aligns the ICMPv6 header type definition with the
conventions used for other network protocol headers and simplifies
type references across the network, border router, and utility
modules.
2026-06-03 14:39:21 -07:00
Jonathan Hui ecd4c92465 [dua] completely remove DUA features and configurations (#13191)
This commit removes the OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE feature
and all associated code, tests, CLI commands, and harness references.

Changes:
- Removed OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE definition and all
  assert/preprocessor checks.
- Completely deleted dua_manager.cpp and dua_manager.hpp.
- Removed DUA registration notifying and request URI paths.
- Cleaned up all references to Domain Unicast Address (DUA) across
  child management, notifier, time ticker, and MLE.
- Removed DUA commands and logic from the CLI and Python cert tests
  (including packet verifier).
- Verified that the entire codebase compiles clean and all tests
  successfully pass using the Nexus test suite.
2026-06-03 12:29:18 -07:00
Jonathan Hui b69c905763 [nexus] fix and update 1_3_SRP_TC_1 integration test (#13200)
This commit updates the SRP registration and verification logic to pass
the 1_3_SRP_TC_1 test case in the Nexus simulator:

1. In test_1_3_SRP_TC_1.cpp, temporarily disable/enable the eth1 DNS-SD
   agent during SRV, AAAA, and browser resolver queries to force a
   clear of the local cache. This ensures the queries are sent over the
   wire to the Border Router (DUT) instead of being answered from the
   resolver's cache.
2. In verify_1_3_SRP_TC_1.py, add checks for mDNS query and response
   packets for Steps 9b, 9c, 15b, and 15c. Relax the Step 15c check to
   not require the ML-EID in the mDNS response, as advertising
   Mesh-Local addresses on the infrastructure link is optional and not
   done by the OpenThread SRP advertising proxy.
2026-06-03 10:55:54 -07:00
Abtin Keshavarzian c410733490 [tcp] add OPENTHREAD_CONFIG_TCP_ENABLE guards to headers (#13195)
This commit wraps the contents of `tcp6.hpp` and `tcp6_ext.hpp` with
`#if OPENTHREAD_CONFIG_TCP_ENABLE` feature guards to ensure that TCP
definitions and types are cleanly excluded when TCP support is disabled
in the build configuration. Additionally, it explicitly disables the
`OPENTHREAD_CONFIG_TCP_ENABLE` feature flag in the Toranj test
configuration to validate building without TCP support.
2026-06-03 08:29:35 -07:00
Jonathan Hui 1b238bffc0 [tests] remove test_trel_connectivity.py (#13196)
This commit removes the deprecated `test_trel_connectivity.py`
integration test. The TREL connectivity test functionality is
already fully covered by the Nexus simulation test suite, which
provides faster and more reliable testing.
2026-06-03 08:06:30 -07:00
Jonathan Hui c01cad7ba2 [nexus] migrate publish meshcop service cert test to nexus (#13186)
This commit migrates the legacy Thread certification test
'test_publish_meshcop_service.py' to the C++ simulation test suite
in the Nexus platform.

To avoid redundancy and keep the test suite clean, the coverage
is consolidated directly within 'tests/nexus/test_border_agent.cpp'
instead of introducing a new redundant test file.

Consolidated coverage and changes:
- Extended the state bitmap parser and 'ValidateMeshCoPTxtData' in
  'test_border_agent.cpp' to verify Backbone Router (BBR) active
  and primary flags (kFlagBbrIsActive, kFlagBbrIsPrimary) when
  OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE is enabled.
- Added a new test block in 'TestBorderAgentServiceRegistration' to
  enable Backbone Router on node0, verify that BBR active and primary
  flags are dynamically advertised in the MeshCoP TXT record over
  mDNS, and verify that disabling BBR correctly updates the TXT
  record state bitmap.
- Fully deleted the legacy Python certification script
  'test_publish_meshcop_service.py' from 'thread-cert'.
2026-06-02 07:46:15 -07:00
Abtin Keshavarzian 7ad13c8adb [ip4] use Icmp4Header directly for ICMPv4 (#13180)
This commit updates the codebase to use the `Icmp4Header` type directly,
replacing the nested `Ip4::Icmp::Header` type. The empty `Ip4::Icmp`
wrapper class is removed to simplify the header definition. This change
aligns the ICMPv4 header structure with the flat naming conventions used
for other IP headers (e.g., `Ip6::Icmp6Header`, `Ip6::UpdHeader`).
2026-06-02 07:45:50 -07:00
dependabot[bot] f6598900cf github-actions: bump docker/build-push-action from 7.1.0 to 7.2.0 (#13188)
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 7.1.0 to 7.2.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/bcafcacb16a39f128d818304e6c9c0c18556b85f...f9f3042f7e2789586610d6e8b85c8f03e5195baf)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: 7.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-02 07:33:12 -07:00
Jonathan Hui 136bdb6e2a [dua] remove OPENTHREAD_CONFIG_DUA_ENABLE build feature (#13165)
This commit completely removes the local Domain Unicast Address (DUA)
registration feature flag (OPENTHREAD_CONFIG_DUA_ENABLE) and all of
its associated implementation, public APIs, CLI commands, Spinel
property handlers, and certification tests.

Thread 1.2 FTD Border Router/Router DUA proxying features for MTD
children (OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE) are preserved and
updated to only compile/instantiate components when proxy DUA
features are active.

Detailed Changes:
- Remove default definition of OPENTHREAD_CONFIG_DUA_ENABLE from
  misc.h.
- Remove OT_DUA and openthread_config_dua_enable from CMake/GN
  configs.
- Remove otThreadSetFixedDuaInterfaceIdentifier and
  otThreadGetFixedDuaInterfaceIdentifier from
  include/openthread/thread.h
  and implementation src/core/api/thread_api.cpp.
- Remove CLI DUA interpreter from src/cli/cli.cpp.
- Remove SPINEL_CAP_DUA capability and SPINEL_PROP_THREAD_DUA_ID
  Spinel property handlers and dispatchers from NCP.
- Strip local DUA management features (conflict checking, SLAAC DUA
  interface identifiers, and dad info settings) from DuaManager, MLE,
  Address Resolver, and settings.
- Clean up Notifier, TimeTicker, and TMF dispatcher guards.
- Clean up -DOT_DUA=ON compilation flags across build/test scripts.
- Delete obsolete DUA certification tests:
  - v1_2_test_domain_unicast_address
  - v1_2_test_domain_unicast_address_registration
  - v1_2_test_dua_handle_address_error
2026-06-01 15:16:19 -07:00
mohammadmseet-hue 675162556b [mdns] reject empty PTR target label on receive (#13183)
`PtrRecord::ReadPtrName()` reads a PTR target's first label with
`Name::ReadLabel()`, which performs no emptiness check. A response whose
first label is a single NUL byte (wire `01 00`) is stored as an empty
C-string and cached by the browse cache as a service instance. When the
cache later builds a known-answer question, it calls
`Name::AppendLabel("")`, which returns `kErrorInvalidArgs`; the
surrounding `SuccessOrAssert()` turns that into an abort. A single
unauthenticated link-local mDNS response thus crashes any node with an
active browser.

Reject an empty first label in `ReadPtrName()` so the record is dropped
on receive and never cached. This matches the `Name::ValidateLabel`
checks already applied on the registration and resolver paths, and makes
the "ReadPtrName() validates that PTR record is well-formed" comment at
the call site accurate.

Add a regression test that delivers a PTR response with a single
NUL-byte instance label and verifies no result is reported and the
browser keeps querying without the malformed entry.
2026-06-01 13:19:16 -07:00
Abtin Keshavarzian 32b96a0d98 [docs] add missing TCP and UDP Doxygen groups (#13178)
This commit adds the missing Doxygen groups for TCP (`core-tcp`),
TCP Extensions (`core-tcp-ext`), and UDP (`core-udp`). These groups
are used in the code but were not previously defined.
2026-06-01 13:13:33 -07:00
Abtin Keshavarzian 831f2d3868 [net] use TcpHeader and UdpHeader directly (#13179)
This commit updates the codebase to use `TcpHeader` and `UdpHeader` types
directly, instead of the nested `Tcp::Header` and `Udp::Header` types.
The `TcpHeader` and `UdpHeader` classes are already defined in
`ip6_headers.hpp`. This change reduces dependencies on the `Tcp` and
`Udp` class definitions, which is particularly useful when TCP
is disabled in the build configuration, avoiding the need to include
their respective class headers just for the header definitions.
2026-05-29 18:25:36 -07:00
Abtin Keshavarzian 55b3adbf81 [docs] fix double 'the' typos across the codebase (#13176)
This commit fixes instances of "the the" typos found in various
files across the codebase, including documentation, headers, source
files, and test scripts.
2026-05-29 17:34:54 -07:00
Abtin Keshavarzian e4df5ddac2 [github] set puppeteer executable path for linkspector (#13181)
This commit updates the `markdown-lint-check` job to explicitly set
the `PUPPETEER_EXECUTABLE_PATH` environment variable to use the
system-installed Google Chrome (`/usr/bin/google-chrome`) for the
`linkspector` action. This resolves issues where the action fails
to find a browser environment to execute properly.
2026-05-29 14:30:14 -07:00
arnulfrupp fa3213ec85 [tcat] implement vendor policy for TLV support and automatic advertisement activation/deactivation (#13038)
This commit implements additional vendor application or ecosystem
policy settings for TCAT including:

1) Automatic deactivation of the TCAT agent / TCAT advertisement after
   the thread network has been started over TCAT
2) Automatic activation of the TCAT agent / TCAT advertisement after
   the thread network has been stopped over TCAT
3) Automatic activation of the TCAT agent / TCAT advertisement after
   decommissioning over TCAT
4) Blocking support of certain TCAT TLVs by the application /
   ecosystem

The commit also fixes an issue with certificate storage after
decommissioning.
2026-05-28 22:02:29 -07:00
Abtin Keshavarzian 2a2d4be953 [ip6] rename methods fully initializing an Ip6::Address/Prefix (#13169)
This commit renames several methods in `Ip6::Address`,
`Ip6::InterfaceIdentifier`, `Ip6::Prefix`, and `Ip4::Address` that
fully initialize the object from `Set...()` to `Init...()`.

This creates a clear semantic distinction in the API:
- `Init...()`: Fully (re-)initializing the object.
- `Set...()`: Modifies a specific property or a sub-component of
   the object (e.g., `SetPrefix()`,  `SetLocator()`,
   `SetSubnetId()`).

Some examples of renames include:
- `SetFromExtAddress()` -> `InitFromExtAddress()`
- `SetToLocator()` -> `InitAsLocator()`
- `SetToLinkLocalAddress()` -> `InitAsLinkLocalAddress()`
- `SetToRoutingLocator()` -> `InitAsRoutingLocator()`
- `SetToAnycastLocator()` -> `InitAsAnycastLocator()`
- `SetToIp4Mapped()` -> `InitAsIp4Mapped()`

All calls to these methods across the codebase have been updated
to reflect the new names.
2026-05-28 20:52:05 -07:00
Jonathan Hui e1b34bc5bc [simulation] increase socket receive buffer size to 2MB (#13173)
This commit sets the SO_RCVBUF socket option to 2MB on the
multicast receiving sockets in the simulation platform.

Under heavy simulation load (such as expect tests with 15 nodes
all sending MLE advertisements and discovery packets), the default
OS UDP receive socket buffer can overflow, leading to silent
packet drops. This occasionally caused expect tests like
cli-big-table.exp to fail with "Join failed [NotFound]" because
Node 4's discovery requests or response beacons were dropped.

Increasing the receive buffer size to 2MB prevents packet loss
during dense simulation runs, resolving intermittent CI test
failures.
2026-05-28 16:52:16 -07:00
Jonathan Hui fa374236a5 [tests] fix flake in trickle timer unit test (#13172)
This commit fixes a frequent unit test flake in ot-test-trickle_timer
under the TestTrickleTimerMinMaxIntervalChange test case.

The test case starts the trickle timer with Imin = 2000 and
Imax = 2000. The random time t (mTimeInInterval) is chosen in
[1000, 2000), so t can range up to 1999.

When t randomly evaluates to 1999, t + 1 becomes 2000. Calling
timer.SetIntervalMax(2000) triggers an early-exit optimization
in TrickleTimer::SetIntervalMax because mIntervalMax is already 2000,
leaving the scheduled timer's fire time unchanged. The test then
crashes on the assertion expecting the fire time to have changed.

This is resolved by setting the new interval max to
Min(t + 1, interval - 1). This ensures that the requested value is
strictly less than 2000 even when t = 1999, successfully triggering
the interval shortening and rescheduling logic tested by this case.
2026-05-28 15:07:05 -07:00
Jonathan Hui 73b6b13678 [tests] add startup delay to prevent expect desync (#13174)
This commit adds a brief 0.1-second sleep delay immediately after
spawning node processes (rcp, cli, and mtd types) in the expect test
harness.

Under high CPU load on GitHub Actions runner VMs, the PTY file
descriptors can take a fraction of a second to fully initialize. If
commands are sent immediately after spawn without delay, the initial
expect match can fail with an instant timeout. This triggers duplicate
retransmissions in wait_for, leaving extra "Done" strings in expect's
PTY read buffer. The leftover "Done" strings desynchronize subsequent
assertions, causing tests to match cached output instead of waiting
for actual command execution (e.g., sending "diag stats" during an
active "diag send" command, which fails).

Adding a 100ms delay gives the PTY and child process enough time to
fully initialize and stabilize, avoiding instant timeouts and
subsequent test harness desynchronization.
2026-05-28 13:50:31 -07:00
Jonathan Hui 5bc532472f [github-actions] add gcc-15 to arm-gcc build matrix (#13171)
This commit adds GCC 15 (version 15.2.rel1) to the `arm-gcc` job
matrix in the OpenThread build (`build.yml`) workflow.

Including GCC 15 in the builds helps ensure that OpenThread compiles
successfully and is free from warnings or errors with the latest GCC
15.2.rel1 release.
2026-05-28 13:49:38 -07:00
Jonathan Hui 9bd35de29a [tests] fix flakiness in publish meshcop service test (#13170)
Increase wait delay after starting the OTBR service in the
test_publish_meshcop_service.py script.

Starting otbr-agent requires the node to re-attach to the simulated
Thread network and transition to the leader role. In virtualized CI
environments, this role transition can take up to 14.5 seconds. Using
a hardcoded 10-second delay results in a race condition where the
service is published very late, causing the subsequent browse query to
miss the service and fail with AssertionError.

Substituting the delay with BORDER_ROUTER_STARTUP_DELAY (20s) ensures
the node has sufficient time to attach, become leader, start the border
agent, and fully register the mDNS service before browsing.
2026-05-28 13:46:28 -07:00
Abtin Keshavarzian eac46963bb [mlr] simplify MLR state tracking on Child (#13166)
This commit simplifies MLR state tracking for child devices. Previously,
`Child::Ip6AddrEntry` inherited from `Ip6::Address` to encapsulate the
MLR registration check using the `Child` reference. This introduced
tight coupling between `Child` and `Ip6AddrEntry`.

The logic is refactored by removing `Ip6AddrEntry`. Instead, `Child`
now directly manages a `Child::Ip6AddressArray` and encapsulates the
MLR state querying/updating through new methods:
  - `SetAddressMlrRegistrationState()`
  - `GetAllMlrRegisteredAddresses()`
  - `ClearAllAddressesMlrRegistrationState()`

In `Mlr::Manager`, the redundant `ChildAddressArray` typedef and
`kMaxChildAddresses` constant are removed, reusing the
`Child::Ip6AddressArray`. The method `UpdateProxiedSubscriptions()`
is  renamed to the more intuitive `UpdateChildRegistrations()`, and
overloaded to allow calling it without an old address list during
initial child registration.
2026-05-28 07:25:40 -07:00
Jonathan Hui 290919b178 [tests] fix uninitialized memory in nexus test 1_3_DBR_TC_7A (#13168)
The test `test_1_3_DBR_TC_7A` was failing occasionally due to
uninitialized stack memory in `NetworkData::OnMeshPrefixConfig config`.

Because `OnMeshPrefixConfig` inherits from `otBorderRouterConfig`
and does not automatically initialize its fields in its default
constructor, declaring `NetworkData::OnMeshPrefixConfig config;`
on the stack left its members (including `mDp` and `mNdDns` flags)
with arbitrary stack garbage. If `mDp` (Domain Prefix flag)
evaluated to true, it caused the registered `PRE_1` prefix to be
erroneously processed as a Domain Prefix. Consequently, the border
router did not include `PRE_1` as a Route Information Option (RIO)
in its emitted Router Advertisements, causing packet verification
to fail in Step 4.

This commit fixes the issue by explicitly initializing the
`config` struct using `config.Clear()` right after declaration.
2026-05-27 19:09:34 -07:00
Jonathan Hui 61be1c0e45 [nexus] isolate both leaders during Step 2 in announce flap test (#13167)
Fixes an intermittent failure in the
`nexus_announce_no_flap_on_unmergeable_partitions` test.

Previously, only LEADER_NEW was isolated (by enabling allowlist
mode with an empty address list) in Step 2. Because LEADER_OLD
still had allowlist mode disabled, it could receive advertisements
from LEADER_NEW. If LEADER_NEW's randomly allocated partition ID
happened to be larger than LEADER_OLD's, LEADER_OLD would see it
as a "better partition" and initiate a transition to child to
attach to LEADER_NEW.

Although this attempt would initially fail in Step 2 (since
LEADER_NEW dropped all RX), it kept retrying. In Step 3, when the
allowlist was opened on both sides, the queued/retried attach
attempt from LEADER_OLD succeeded, making it a child and causing
the Leader assertion to fail.

Isolating both nodes during Step 2 ensures that LEADER_OLD never
hears LEADER_NEW's initial good-link advertisements. When Step 3
begins, it only hears LEADER_NEW through the weak link and
correctly rejects the advertisements, keeping both nodes stable
leaders of separate partitions.
2026-05-27 15:20:38 -07:00
Jonathan Hui eb671b2a6d [bit-set] cast bitwise NOT in FlipBits to uint8_t (#13164)
Explicitly cast the result of the bitwise NOT operator ~ to uint8_t in
BitSetUtils::FlipBits to resolve a build error under AppleClang.

In C++, using the bitwise NOT operator on a uint8_t value promotes it to
an int. Assigning the promoted int back to uint8_t triggers an implicit
conversion warning/error (-Wimplicit-int-conversion) under newer
compiler versions, which fails the build when compiled with -Werror.
2026-05-27 13:24:56 -07:00
Abtin Keshavarzian 3243bc3529 [dataset] introduce AffectsConnectivity() and public API (#13134)
This commit introduces helper methods to `MeshCoP::Dataset` to determine
if a given Dataset affects network connectivity or the Network Key.
It also adds a corresponding public API `otDatasetAffectsConnectivity()`.

A Dataset is considered to affect connectivity if it contains a
different Channel, PAN ID, Mesh Local Prefix, or Network Key than
the current values in use.
2026-05-27 12:48:31 -07:00
Abtin Keshavarzian 597ca44261 [instance] fix typo in mIsLogLevelOverridden member variable (#13160)
This commit fixes a spelling error in `Instance` class where
`mIsLogLevelOverriden` was misspelled. It has been corrected to
`mIsLogLevelOverridden`.
2026-05-27 12:46:37 -07:00
Tobías Lifschitz 96c85c24e7 [mle] skip announce driven attach when channel/PAN ID match (#13139)
`Mle::AnnounceHandler::HandleAnnounce` previously executed the
`kAnnounceAttachAfterDelay` action on an attached node even when
the announced channel and PAN ID already equaled the current MAC
parameters. The `!channelAndPanIdMatch` guard was only consulted
in the `IsDetached()` branch. For an attached node this scheduled
`StartAnnounceAttach`, which calls `Stop()` then `Start()` with
the same channel/PAN ID -- accomplishing nothing while disrupting
attached children.

This causes an endless role flap in a topology where two FTDs
share channel, PAN ID, and network credentials but hold different
Active Dataset Timestamps, and where their RF link is too weak to
merge partitions (Advertisements rejected with LinkMarginLow at
`mle_router.cpp`). Each side restarts on every Announce received
from the higher-timestamp peer; the reactive `kSendAnnouceBack`
path further amplifies this because the lower-timestamp side's
own outgoing Announces draw Announce responses from the peer.

Apply the channel/PAN ID match guard unconditionally in
`kAnnounceAttachAfterDelay`. Mirror it on the FTD
`kSendAnnouceBack` path (matching the existing `isFromOrphan`
behavior) so peers sharing MAC parameters are not prompted to
migrate to the channel/PAN ID they already use.

Add `addon_test_announce_no_flap_on_unmergeable_partitions.py`
which builds the topology above and asserts that both nodes
retain their original partition IDs across a 20-minute simulated
window. Without this change the lower-timestamp node is
repeatedly demoted from leader during that window.
2026-05-27 11:41:21 -07:00
Abtin Keshavarzian 7ff1b5c661 [child-table] move max child IP addresses logic from Mle (#13159)
This commit moves the state and logic for managing the maximum number
of IP addresses per child from `Mle` to `ChildTable`. The logic for
checking the limit is also moved to the `Child` class itself.
This change better encapsulates the child table properties.
2026-05-27 11:36:59 -07:00
Jonathan Hui dcbd870245 [dhcp6] obsolete DHCPv6 Server Unicast Option per RFC 9915 (#13146)
This commit updates the DHCPv6 Prefix Delegation (PD) client to
comply with RFC 9915, which obsoletes the Server Unicast option
(Option 12) and the UseMulticast status code.

Changes:
- Removed `mServerAddress` and `ProcessServerUnicastOption()` from
  `Dhcp6PdClient`.
- Modified `Dhcp6PdClient::SendMessage` to always transmit via
  multicast to `ff02::1:2`.
- Removed `UseMulticast` status code handling in `HandleReply()`.
- Added `otMessageFree` weak stub in simulation platform's
  `infra_if.c` to resolve linking errors on simulation radio-only
  targets when DHCPv6 PD client is enabled.
- Updated `test_dhcp6_pd_client.cpp` to expect multicast and
  removed the obsolete UseMulticast test case.
2026-05-27 10:31:00 -07:00
Abtin Keshavarzian 494a4868a3 [net-diag] convert MAC and MLE counters TLVs to SimpleTlvInfo (#13157)
This commit updates `MacCountersTlv` and `MleCountersTlv` to use the
`SimpleTlvInfo` template. The original classes are replaced with
`MacCountersTlvValue` and `MleCountersTlvValue` which only represent
the TLV values. This helps simplify the TLV parsing and appending
logic and more importantly allows the TLV value formats to be
reused.
2026-05-27 10:25:03 -07:00
Abtin Keshavarzian 0693bceb75 [bit-set] enhance BitSet class (#13156)
This commit extends the `BitSet` class with several new
methods:
- `CountElements()`
- `IsSubsetOf()` and `IsSupersetOf()`
- `Complement()`
- `UnionWith()`, `IntersectWith()`, and `SubtractWith()`
- `SetMask()`, `AppendTo()`, and `ReadFrom()` message.

This commit also introduces a new `BitSetUtils` non-template base class
for the `BitSet<kNumBits>` template class. This change helps optimize
code by moving the common implementation logic for various bit
manipulation operations out of the template, reducing template
instantiation overhead.
2026-05-27 10:21:44 -07:00
Jonathan Hui a18123b349 [nexus] clean up test labels and sorting in CMakeLists (#13152)
This commit refactors the Nexus tests configuration in CMakeLists.txt
by properly classifying and sorting test cases:

- Moved `inform_previous_parent_on_reattach` from the "Cert tests"
  section to the "Misc tests" section, and changed its label from
  "cert;nexus" to "core;nexus".
- Moved `retransmission_security` from the "Cert tests" section
  to the "Misc tests" section where it belongs (retaining its
  "core;nexus" label) and sorted it alphabetically.

These changes ensure the CMake file remains clean and the tests are
properly categorized.
2026-05-27 10:17:22 -07:00
Jonathan Hui 9431d3a77e [tests] remove thread-cert backbone tests (#13161)
This commit removes the thread-cert/backbone tests and cleans
up all related configurations and references.

Specifically, the following changes are made:
- Deleted tests in tests/scripts/thread-cert/backbone/
- Removed the backbone-router job from .github/workflows/otbr.yml
- Removed backbone-router dependency from upload-coverage job
- Removed setup, cleanup, and checks for backbone tests in
  tests/scripts/thread-cert/run_cert_suite.py
2026-05-27 10:16:44 -07:00
Jonathan Hui 289abbd87b [github-actions] remove avahi configurations from otbr workflow (#13162)
This commit removes the `avahi` mDNS configurations from the
`thread-border-router` job matrix in the OpenThread Border Router
(`otbr.yml`) workflow.

With this change, the `thread-border-router` integration tests will
exclusively run using the `mDNSResponder` configuration.
2026-05-27 10:16:26 -07:00
Jonathan Hui 91a783f6ca [config] fix typo in core config check header (#13158)
Fix typo "was replaces" to "was replaced" in
openthread-core-config-check.h.
2026-05-27 07:37:23 -07:00
Abtin Keshavarzian 3ce616d835 [netdiag] rename namespace NetworkDiagnostic to NetDiag (#13154)
This commit renames the `NetworkDiagnostic` namespace in `src/core/thread/`
and its related types to `NetDiag` for brevity. It updates the
corresponding filenames and header guards as well.
2026-05-26 20:19:48 -07:00
Abtin Keshavarzian 337d424d4f [mlr] stop fast polls upon receiving response (#13149)
When a sleepy end device (where `Mle::IsRxOnWhenIdle()` returns
false) sends an MLR request, it initiates fast data polls via
`DataPollSender::SendFastPolls()` to quickly receive the response.
This commit updates `Manager::HandleResponse()` to call
`DataPollSender::StopFastPolls()` when the MLR response is processed
by a sleepy end device. This ensures that the device does not
unnecessarily continue fast polling.
2026-05-26 20:13:42 -07:00
Yakun Xu 06e210fe89 [sub-mac] redo security processing for every (re)transmission (#13093)
Retransmissions of frames containing time-dependent header Information
Elements (IEs), such as CSL or Time Sync, require updates to these
IEs to reflect the exact time of sending. If the frame counter is not
incremented for these retransmissions, it leads to nonce reuse in
AES-CCM encryption, which is a security vulnerability.

This commit addresses this issue by ensuring that every transmission
attempt (initial or retry) uses a fresh frame counter:
- Deferred security processing from `SubMac::Send()` to
  `SubMac::BeginTransmit()`.
- Upon retransmission in `SubMac::HandleTransmitDone()`, the frame is
  restored to plaintext via `TxFrame::DecryptTransmitAesCcm()` and
  security flags are cleared.
- This allows time-dependent IEs to be updated and a new frame counter
  to be assigned for every attempt.

Added a Nexus test case `retransmission_security` to verify that both
CSL and standard MAC retransmissions use incrementing frame counters
and updated CSL phases.
2026-05-26 10:36:55 -07:00
Abtin Keshavarzian 5783555d4c [mlr] introduce state machine and use timer in Mlr::Manager (#13132)
This commit introduces a structured state machine to `Mlr::Manager` to
coordinate Multicast Listener Registration (MLR) activities more
efficiently. The previous implementation relied on independent delay
variables and the global `TimeTicker`, which could lead to redundant
or premature registrations, especially when a Primary Backbone Router
(PBBR) was newly discovered or updated.

The new state machine (`kStateStopped`, `kStateIdle`,
`kStateToRegisterAll`, `kStateRegistering`, `kStateRegistered`,
`kStateNewAddrToRegister`) provides explicit transitions for the
entire MLR lifecycle. This ensures that registrations are properly
aggregated and that periodic renewals are correctly rescheduled after
successful out-of-band registrations.

Additionally, the manager now uses a dedicated `TimerMilli` instead of
`TimeTicker`, reducing system-wide overhead and providing more
precise timing control.
2026-05-26 08:38:18 -07:00
Esko Dijk cf7e5bb2b3 [srp] always send Update Lease (UL) option in success response (#13148)
Per RFC 9664, the UL option is always included in a success response (RCODE=0).
Comment in test_srp_server is updated also to avoid suggesting the opposite.
2026-05-26 07:37:39 -07:00
Abtin Keshavarzian 4de7bc578e [random] introduce template-based NonCrypto random APIs (#13142)
This commit introduces a new set of template-based APIs for
non-cryptographic random number generation in the `Random::NonCrypto`
namespace. These new methods provide a cleaner, type-safe, and more
robust interface compared to the previous methods.

Key additions:
- `Generate<UintType>()`: Returns a random value of the given
  unsigned integer type (`uint8_t`, `uint16_t`, or `uint32_t`).
- `GenerateUpToExcluding<UintType>(aMax)`: Returns a random value in
  the range `[0, aMax)`.
- `GenerateFromMinUpToExcluding<UintType>(aMin, aMax)`: Returns a
  random value in the range `[aMin, aMax)`.
- `GenerateInClosedRange<UintType>(aMin, aMax)`: Returns a random
  value in the closed range `[aMin, aMax]`.

The introduction of `GenerateInClosedRange` is an improvement as it
safely handles ranges up to the maximum value of the integer type
(e.g., `0xffff`) without the risk of overflow.

All call sites across the OpenThread core stack and tests have been
updated to adopt these new APIs. The public `otRandomNonCrypto`
functions are also updated to leverage the new internal methods.

Doxygen documentation is added for all new template methods,
detailing their behavior, including edge cases where the upper bound
is smaller than or equal to the lower bound.
2026-05-25 19:39:59 -07:00
Abtin Keshavarzian 9d95a19e52 [tests] use constexpr for constants in unit tests (#13145)
This commit refactors various unit tests to use `constexpr` for
defining constants instead of anonymous `enum` types.

Using `constexpr` is the modern and preferred approach in C++, as it
provides explicit types for constants and improves code clarity and
type safety.
2026-05-25 19:39:27 -07:00
Abtin Keshavarzian 6847b9acdf [routing-manager] fix minor style issues in StateToString() (#13144)
This commit fixes minor coding style issues in
`RoutingManager::RoutePublisher::StateToString()`. It adds a missing
semicolon after the `DefineEnumStringArray()` macro and corrects the
indentation of the return statement.
2026-05-25 19:39:13 -07:00
Abtin Keshavarzian d50b9b444f [tlv] define Tlv::AppendTlvHeader() public and use it in core (#13143)
This commit makes `Tlv::AppendTlvHeader()` public and updates call
sites to use it. This method automatically handles the formatting
of the TLV header as either a standard TLV header or an extended one
based on the provided length.
2026-05-25 19:38:59 -07:00
dependabot[bot] 2dc41cf9a2 github-actions: bump umbrelladocs/action-linkspector from 1.4.1 to 1.5.1 (#13147)
Bumps [umbrelladocs/action-linkspector](https://github.com/umbrelladocs/action-linkspector) from 1.4.1 to 1.5.1.
- [Release notes](https://github.com/umbrelladocs/action-linkspector/releases)
- [Commits](https://github.com/umbrelladocs/action-linkspector/compare/37c85bcde51b30bf929936502bac6bfb7e8f0a4d...963b6264d7de32c904942a70b488d3407453049e)

---
updated-dependencies:
- dependency-name: umbrelladocs/action-linkspector
  dependency-version: 1.5.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-25 10:28:28 -07:00
Jonathan Hui 5265a0bf48 [bbr] remove Backbone Router DUA ND Proxying feature (#13136)
This commit removes all code, configurations, APIs, and tests related
to the OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE feature.

Specifically, the following changes were made:
- Removed DUA ND Proxying Backbone Router configuration option and the
  related OPENTHREAD_CONFIG_NDPROXY_TABLE_ENTRY_NUM definition.
- Removed CLI commands: `bbr mgmt dua` and the proactive backbone
  notification fake command `/b/ba`.
- Removed NdProxyTable and bbr_manager DUA ND Proxying implementation.
- Removed public/internal APIs for ND Proxying and proactive backbone
  notifications.
- Deleted ndproxy_table source files and unit tests.
- Simplified CMake and GN build files to remove deleted targets.
2026-05-23 07:57:57 -07:00
Abtin Keshavarzian 0d297708e5 [nexus] add help and argument validation to build.sh (#13133)
This commit improves the `tests/nexus/build.sh` script by adding a
`display_usage()` function and implementing stricter command-line
argument validation.
2026-05-22 18:08:44 -07:00
Jonathan Hui 6e81f1d77c [tests] remove obsolete DUA-dependent backbone tests (#13141)
This commit removes the obsolete Backbone Router (BBR) certification
tests:
- tests/scripts/thread-cert/backbone/bbr_5_11_01.py
- tests/scripts/thread-cert/backbone/
  test_mlr_multicast_routing_across_thread_pans.py

These tests are removed because DUA (Domain Unicast Address) routing
features (specifically DUA ND Proxying) have been deprecated and
removed from the codebase. Since these features are no longer
supported, the corresponding certification and validation tests are
no longer valid or runnable.
2026-05-22 13:32:56 -07:00
Jonathan Hui eb6c7b7ad6 [tests] remove DUA and ND proxy backbone tests (#13135)
Remove obsolete backbone test cases for Domain Unicast Address
(DUA) Duplicate Address Detection (DAD), DUA routing, DUA routing
for Minimal End Devices (MED), and Neighbor Discovery (ND) Proxy.
These features and their corresponding tests are no longer needed.
2026-05-22 07:25:53 -07:00
sarveshkumarv3 494575f8fc [cli] add cli command to clear EID-RLOC cache (#9985)
Co-authored-by: Abtin Keshavarzian <abtink@google.com>
2026-05-21 17:18:54 -07:00
Jonathan Hui c1946b2c09 [tests] remove DUA validation from border router firewall test (#13131)
This commit removes all DUA (Domain Unicast Address) validation
and verification steps from test_firewall.py. Since DUA routing
features are being phased out or removed, this keeps the firewall
test in sync and prevents potential failures during test runs.

Specifically:
- Removed DUA ping validation from host to router.
- Removed DUA collection call (collect_duas).
- Removed the packet verifier checks checking for DUA ping traffic.
2026-05-21 17:07:24 -07:00
Jonathan Hui 4c9791cb9b [ci] clone ot-br-posix submodules recursively in CI/CD (#13130)
When cloning the ot-br-posix repository to run the Docker-in-Docker
integration tests, the clone was shallow and did not recursively
check out nested submodules (such as cJSON and cpp-httplib). This led
to build failures inside the Docker build container since libcjson
is not pre-installed on the base build image.

This commit resolves the issue by:
1. Appending the `--recurse-submodules` flag to the git-tool clone
   calls in `otbr-posix-dind.yml` and `script/test`.
2. Updating `script/git-tool`'s destination directory parsing to
   robustly handle multi-line output from recursive submodule
   checkouts. The new pattern extracts the path exclusively from
   the first line using `sed` to prevent SIGPIPE or parsing errors.
2026-05-21 15:34:05 -07:00
Jonathan Hui fa5bb3b94c [github-actions] add monthly CalVer release workflow (#13125)
This commit introduces a new GitHub Actions workflow to automate the
monthly release process using Calendar Versioning (CalVer).

The workflow:
- Runs automatically at 00:00 UTC on the 1st day of every month.
- Supports manual execution via `workflow_dispatch`.
- Automatically generates a CalVer tag (e.g., vYYYY.MM.0).
- Employs the GitHub CLI to create a release and auto-generate
  release notes based on merged pull requests.
2026-05-21 13:16:45 -07:00
Abtin Keshavarzian 4152ea10e4 [bbr] fix overflow in Config::SelectRandomReregistrationDelay() (#13128)
This commit fixes a potential `uint16_t` overflow in
`Config::SelectRandomReregistrationDelay()` which could occur if
`mReregistrationDelay` was set to the maximum `uint16_t` value.

The `Random::NonCrypto::GetUint16InRange(lower, upper)` function
includes the lower bound but excludes the upper bound. Previously,
the code called `GetUint16InRange(1, mReregistrationDelay + 1)`,
which would overflow the upper bound if `mReregistrationDelay` was
`0xffff`. The logic is updated to `1 + GetUint16InRange(0,
mReregistrationDelay)`, which safely produces a random value in the
range `[1, mReregistrationDelay]` without overflow.
2026-05-21 13:13:39 -07:00
Abtin Keshavarzian bd47a31674 [tlv] add Tlv::AppendTlvWithValueFromMessage() helper (#13120)
This commit introduces a new helper method that allows appending a
TLV by copying its value directly from a specified `OffsetRange` of
another `Message`.

This helper automatically handles formatting the TLV as an Extended
TLV if the length exceeds 254 bytes, eliminating the need for manual
length checks and TLV header construction at the call sites.

Key changes:
- Added `Tlv::AppendTlvWithValueFromMessage()`.
- Refactored TLV header construction into a private helper
  `Tlv::AppendTlvHeader()` to share logic between `AppendTlv` variants
  and `StartTlv()`.
- Updated `Commissioner::SendRelayTransmit()` and
  `JoinerRouter::HandleUdpReceive()` to use the new helper for
  `JoinerDtlsEncapsulation` TLVs.
- Updated `TcatAgent::HandlePing()` to use the new helper, significantly
  simplifying the payload response generation.
2026-05-21 08:41:01 -07:00
Tongze Wang 7048835ba1 [core] check if Instance has been initialized before logging (#13099)
When logging while `Instance` has not been initialized yet, use 0 as
return value of `GetUptime` and use `OPENTHREAD_CONFIG_LOG_LEVEL_INIT`
as default log level instead of accessing raw memory.
2026-05-20 12:39:33 -07:00
Abtin Keshavarzian 9137b82dbe [bbr] handle role changes directly in BackboneRouter::Local (#13112)
This commit updates `BackboneRouter::Local` to receive role change
events directly from the `Notifier`. Previously, `Bbr::Local` was
indirectly relying on `BackboneRouter::Leader` to emit events even
when the PBBR configuration had not changed (e.g., during role
transitions).

The previous design was fragile and created an unnecessary dependency.
`Bbr::Local` now independently tracks role changes to ensure it
correctly evaluates its own status (e.g., deciding whether to
register as the Primary BBR).
2026-05-18 22:02:40 -07:00
Abtin Keshavarzian c5efa406c2 [bbr-leader] introduce PrimaryEvent to represent PBBR changes (#13112)
This commit introduces `PrimaryEvent` to represent changes in the
Primary Backbone Router (PBBR) configuration, replacing the previous
`State` enum. Calling it `State` was misleading as the values
describe transitions or updates to the PBBR rather than a persistent
state.

The new `PrimaryEvent` enum provides a more descriptive way to notify
dependent modules (`Mlr::Manager`, `DuaManager`, and `Bbr::Local`)
about specific changes in the PBBR, such as when it is added,
removed, or when its configuration parameters (e.g., RLOC16, Sequence
Number, or MLR Timeout) are updated.
2026-05-18 22:02:40 -07:00
Abtin Keshavarzian 3bc8b3f29a [tcat] use Tlv::Info and OffsetRange in HandleSingleTlv() (#13119)
This commit simplifies and enhances the TLV parsing logic in
`TcatAgent` so to use the `Tlv::Info` helper class. This safely and
automatically handles both standard and extended TLVs, removing the
need for manual type checking and length/offset calculations.

Key changes:
- Updated `TcatAgent::HandleSingleTlv()` to use `Tlv::Info::ParseFrom()`.
- Replaced individual `aOffset` and `aLength` parameters with
  `const OffsetRange &` across various TLV handler methods (e.g.,
  `HandlePing`, `HandleSetActiveOperationalDataset`, `VerifyHash`).

This improves code readability, safety, and consistency with common
OpenThread TLV parsing patterns.
2026-05-18 21:19:30 -07:00
Abtin Keshavarzian 9d5539844c [ble] simplify BleSecure::HandleTlsReceive() (#13118)
This commit simplifies the logic in `BleSecure::HandleTlsReceive`
by reducing the nesting level through the use of early `ExitNow()`
calls and replacing a complex `if-else` block with a `switch`
statement for handling `errorTcatAgent`.

Key improvements:
- Removed a large `else` block by adding `ExitNow()` after the
  initial transparent mode check.
- Used a `switch` statement to handle `errorTcatAgent` returned
  by `MeshCoP::TcatAgent::HandleSingleTlv()`, clearly separating
  `kErrorNone`, `kErrorAbort` (disconnect), and default fatal
  error handling.
- Improved code formatting and comment readability.
2026-05-18 19:11:41 -07:00
Abtin Keshavarzian b42e3747ee [ble] clean up message parsing in BleSecure::HandleTransport() (#13117)
This commit refactors `BleSecure::HandleTransport()` to use the
`OffsetRange` and `Message::ReadAndAdvance()` helper methods. This
replaces manual length and offset tracking, resulting in cleaner
and safer message parsing logic.

Additionally:
- Simplified the payload length calculation by using nested `Min()`
  calls instead of multiple `if/else` blocks.
- Added a `RadioPacket` typedef in `BleSecure` to alias the public
  `otBleRadioPacket` structure, aligning with OpenThread's core
  namespace conventions.
2026-05-18 19:11:10 -07:00
Abtin Keshavarzian 98b26df890 [nexus] add OT_NEXUS_BUILD_TESTS cmake option (#13116)
This commit introduces a new CMake option `OT_NEXUS_BUILD_TESTS`
(defaulting to `ON`) to control whether the individual Nexus test
executables are built.

When developing or debugging the OpenThread core stack within the
Nexus framework, building the large number of certification tests can
be time-consuming. This option allows developers to skip building the
tests and only compile the `ot-nexus-platform` library and OT core.

The check is implemented inside the `ot_nexus_test` macro to ensure
all test definitions automatically respect the flag without requiring
large conditional blocks in the `CMakeLists.txt` file.

Additionally, a `no_tests` argument is added to `tests/nexus/build.sh`
to easily invoke this configuration from the command line.
2026-05-18 19:10:46 -07:00
Abtin Keshavarzian 9a4d2dc66b [bbr] improve Backbone Router callback and Config APIs (#13111)
This commit refactors and improves the Backbone Router callback and
`Config` introducing new methods and encapsulating configuration-related
logic.

Key changes:
- Added `Leader::GetConfig()` to provide direct access to the internal
  cached `Config` object.
- Renamed `Leader::GetConfig(Config &)` to `Leader::ReadConfig(Config &)`
  to better reflect its purpose.
- Added `Config::SelectRandomReregistrationDelay()` to encapsulate the
  logic for selecting a random re-registration delay.
- Simplified variosu `HandleBackboneRouterPrimaryUpdate()` callbacks
  to remove the parameter `aConfig`,  allowing these modules to use
  `Leader::GetConfig()` instead.
2026-05-18 19:10:12 -07:00
Esko Dijk 29bb6f634a [posix] add details to UDP bind failure and log at Warn level (#13109)
This adds details to the Posix platform UDP bind error message, showing address and
port just like for the otPlatUdpConnect case. Also the severity is changed from Crit
to Warn, since it's not a critical failure given that otPlatUdpBind() is used in a
loop to find an available ephemeral port - i.e. probe the ports in range until one
succeeds.

It also fixes an issue where `errno` might be modified by the logging code itself.

Ideally the platform code would discern 'port in use' vs 'unrecoverable failure to
bind the port', but the currently defined OT APIs don't allow for any other errors
apart from ok/failed. If the specific port number is really needed, the caller
is responsible to log a critical failure.
2026-05-18 13:41:26 -07:00
Esko Dijk 5dbe57331c [posix] DHCPv6-PD client handling of sendto() failure (#13100)
If the PD client sendto() fails, e.g. because of an unroutable IPv6
destination, currently the message remains in the queue. Then the
subsequent retries cause a 100% CPU use (without end). This fixes the
issue by dropping the message in case of an unresolvable sendto()
failure.
2026-05-18 13:13:09 -07:00
Abtin Keshavarzian 64c4124bd1 [sntp] clean up and improve Sntp::Client (#13114)
This commit refactors and improves the `Sntp::Client` class by
adopting common OpenThread patterns and simplifying the logic.

Key changes:
- Introduced `Sntp::Client::QueryInfo` core class to wrap the
  public `otSntpQuery` structure.
- Added `Timestamp` class to handle SNTP timestamps, simplifying
  the `Header` structure.
- Renamed methods and variables to be more concise and consistent
  (e.g., `FinalizeSntpTransaction` to `Finalize`,
  `mRetransmissionTimer` to `mTimer`).
- Simplified the `HandleUdpReceive` logic by splitting response
  processing into `ProcessResponse`.

This change improves code readability and maintainability of the
SNTP client module.
2026-05-18 13:04:37 -07:00
Abtin Keshavarzian 86b8bf6de4 [nexus] add support for CLI testing (#13110)
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.
2026-05-18 13:03:46 -07:00
Abtin Keshavarzian 56010e2f65 [bbr] introduce BackboneRouter::Config core class (#13108)
This commit introduces a new core class `BackboneRouter::Config` that
inherits from the public `otBackboneRouterConfig` struct. This aligns
with the OpenThread architectural pattern of using core-internal
classes to wrap public API structures, providing a cleaner interface
and encapsulating logic.

Importantly, this commit ensures that the `MlrTimeout` is adjusted
and clamped to valid ranges before comparing the new configuration
with the existing one. This ensures that the state transition
(e.g., `kStateRefreshed`) correctly reflects the actual values
that will be used.

Other improvements:
- Added helper methods `IsPresent()`, `MarkAsAbsent()`, and getters
  for configuration fields.
- Moved `MlrTimeout` adjustment logic into `Config::AdjustMlrTimeout()`.
- Added `Config::Log()` to log configuration details, and updated
  `Leader` to log both old and new configurations when a Primary
  Backbone Router event occurs.
2026-05-18 13:01:02 -07:00
dependabot[bot] 5c5c100fee github-actions: bump actions/github-script from 8.0.0 to 9.0.0 (#13115)
Bumps [actions/github-script](https://github.com/actions/github-script) from 8.0.0 to 9.0.0.
- [Release notes](https://github.com/actions/github-script/releases)
- [Commits](https://github.com/actions/github-script/compare/ed597411d8f924073f98dfc5c65a23a2325f34cd...3a2844b7e9c422d3c10d287c895573f7108da1b3)

---
updated-dependencies:
- dependency-name: actions/github-script
  dependency-version: 9.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-18 12:38:30 -07:00
Jonathan Hui 97ff74fc8b [github-actions] run DinD test with and without mDNSResponder (#13104)
Update `otbr-posix-dind.yml` workflow to run the DinD integration test
using a matrix strategy that covers both the default mDNS implementation
and `mDNSResponder`.

This mirrors the testing matrix used in `ot-br-posix` repository's
`docker-test.yml` workflow.
2026-05-16 07:38:34 -07:00
Shu Chen b6f6d34606 [diag] invoke SetDiagMode before setting channel/power (#12941)
In Host + RCP mode, running `diag start` from the host CLI may trigger
RadioSpinel warnings: InvalidState, “Error processing result” / “Error
waiting response”.

**Root cause**

Diags::ProcessStart sent channel / power commands before enabling diag
mode. On Spinel, these are forwarded to the RCP (via
`SPINEL_PROP_NEST_STREAM_MFG`), but the RCP only accepts other diag
commands after start.

```    
    if (!IsEnabled() && !StringMatch(aArgs[0], "start"))
    {
        Output("diagnostics mode is disabled\r\n");
        ExitNow(error = kErrorInvalidState);
    }
```

As a result, early channel / power commands are rejected with
InvalidState.
2026-05-15 07:31:14 -07:00
Abtin Keshavarzian 545a649ecd [bbr-leader] remove kDomainPrefixUnchanged from DomainPrefixEvent (#13107)
This commit removes the `kDomainPrefixUnchanged` event from the
`DomainPrefixEvent` enum and refactors the related logic in
`BackboneRouter::Leader`. This value was redundant, as the manager
should only report events when an actual change (addition, removal,
or refresh) occurs in the Domain Prefix configuration.
2026-05-14 22:57:51 -07:00
Abtin Keshavarzian a84fc2e50b [message] introduce ReadAndAdvance() to simplify sequential parsing (#13106)
This commit introduces `Message::ReadAndAdvance()` and its template
flavor to the `Message` class. This helper method reads data from a
`Message` at a given `OffsetRange` and advances the `OffsetRange` by
the number of bytes read upon success.

Sequential parsing of structured data (such as TLVs or protocol
headers) is a common pattern across the OpenThread codebase.
Previously, this required two separate calls: one to `Read()` and
another to `AdvanceOffset()`. The new `ReadAndAdvance()` method
consolidates these into a single, safer operation that ensures the
offset is only advanced if the read operation succeeds.

This commit updates numerous call sites across the core stack
(MLE, BBR, DatasetManager, NetworkDiagnostic, DHCPv6, etc.) to use
the new helper, improving code clarity and reducing boilerplate.
2026-05-14 22:57:08 -07:00
Abtin Keshavarzian 27737f616e [tlv] remove unused Tlv::FindTlv() method variations (#13105)
This commit removes the legacy `Tlv::FindTlv()` method variations
that read a TLV into a local buffer. These methods are no longer
used across the codebase, having been replaced by safer and more
efficient alternatives such as `Tlv::Find<TlvType>()`,
`Tlv::FindTlvValueOffsetRange()`, or `Tlv::Info::FindIn()`.

The removed methods were prone to misuse, as they did not always
handle Extended TLVs correctly if the caller provided a fixed-size
buffer. Removing these variations forces new code to use the modern
helper functions, which provide better validation and correctly
handle the decoupling of the TLV header from its value.
2026-05-14 22:56:29 -07:00
Abtin Keshavarzian 181405efc9 [mle] introduce RouteTlv::Data to represent parsed Route TLV (#13098)
This commit introduces a new model for handling `RouteTlv` by
adding the `RouteTlv::Data` and `RouteTlv::Data::Entry` classes.
Previously, `RouteTlv` directly represented the packed on-wire
format, which made it difficult to work with, especially when
supporting different configurations such as
`OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE`.

The new `RouteTlv::Data` class decouples the on-wire serialization
from the in-memory representation, providing a cleaner API for
parsing the TLV from a `Message` and accessing its entries and
their properties (Router ID, Route Cost, and Link Qualities).

This change improves code clarity and maintainability by providing
a structured way to handle route information.
2026-05-14 11:17:37 -07:00
Jonathan Hui c6fa686dd7 [github-actions] add ot-br-posix DinD integration test workflow (#13102)
This commit introduces a GitHub Actions workflow (OTBR DinD) to
verify that changes in the OpenThread repository do not break the
integration tests in ot-br-posix.

The workflow runs on every pull request and merge to main. It performs
the following steps:
1. Clones openthread/ot-br-posix using script/git-tool, which
   automatically applies any dependent PRs specified in the PR body.
2. Replaces the openthread submodule in ot-br-posix with the local
   OpenThread checkout containing the changes under test.
3. Builds the Docker-in-Docker (DinD) test runner image from
   etc/docker/test/Dockerfile.dind_runner in ot-br-posix.
4. Runs test_dind_dns_sd.sh inside the DinD container to ensure that
   DNS-SD advertising proxy and TREL integration tests pass
   successfully.
2026-05-14 13:13:20 -05:00
Jonathan Hui 83d334ce85 [posix] implement address labeling for mesh-local addresses (#13101)
Ideally, the mesh-local address (ML-EID) is only used when
communicating with devices in the Thread mesh. The mesh-local
address must not be used when communicating with other devices on
the infrastructure link or outside the Thread mesh.

This commit addresses this by implementing address labeling:
1. Modifying `UpdateUnicastLinux` in `src/posix/platform/netif.cpp`
   to stop marking mesh-local addresses as deprecated. They are now
   added as preferred addresses.
2. Implementing `AddAddressLabel` and `DeleteAddressLabel` to manage
   address labels via netlink (RTM_NEWADDRLABEL/RTM_DELADDRLABEL).
3. Calling `AddAddressLabel` when a mesh-local address is added to
   assign a specific label (99) to the Mesh-Local Prefix.

This ensures that the kernel prefers the ML-EID for destinations
sharing the same label (i.e., within the Thread mesh), while
avoiding its use for external traffic where other addresses with
standard labels would be a better match.

Issue: 8443
2026-05-14 11:11:13 -07:00
Stefan Agner 2cb137fabf [mesh-forwarder] lower log level on missing priority (#11062)
It seems that frames which are received through TREL do not have a
priority field. This creates quite some log noise when having notice log
level enabled. Lower this log entry to debug level.
2026-05-13 07:24:45 -07:00
Jonathan Hui 01006d241f [github-actions] combine simulation workflows into simulation.yml (#13097)
This commit combines simulation-1.1.yml and simulation-1.4.yml into
a single simulation.yml workflow.

The combined workflow includes:
- ot-commissioner (from 1.1)
- simulation-local-host (from 1.1)
- channel-manager-csl (from 1.4)
- expects (renamed from 1.4's expects)

The expects job from 1.1 is removed as requested. The jobs now rely
on the project's default THREAD_VERSION instead of explicitly
setting it in the environment. Artifact naming is updated to ensure
unique coverage files are generated and correctly merged by the
unified upload-coverage job.
2026-05-12 20:23:27 -07:00
Jonathan Hui a155bfb6bb [github-actions] remove thread-cert job from posix workflow (#13096)
This commit removes the thread-cert job from the POSIX GitHub Actions
workflow. These tests have been migrated to the Nexus test framework.

The removal of the thread-cert job simplifies the POSIX workflow and
relies on the Nexus-based tests for validating Thread stack behavior.
2026-05-12 20:23:11 -07:00
Abtin Keshavarzian f669d82a81 [tests] add Nexus test for redundant MLR registrations (#13092)
This commit adds a new Nexus test (`test_mlr_redundant.cpp`) to verify
that the MLR manager correctly handles registrations when multiple
entities (e.g., a parent router and its children) subscribe to the
same multicast address, without sending redundant requests.

The test sets up a topology with a Primary Backbone Router, an FTD
Router, and three SEDs. The Router and SEDs all subscribe to the same
multicast address. The Router then subscribes to 14 additional unique
multicast addresses to exceed the single CoAP message payload limit
(`kMaxIp6Addresses`).

A CoAP interceptor is registered on the Backbone Router to parse
incoming `MLR.req` messages and count the number of times the shared
multicast address is included in the payload. The test verifies that
the shared address is requested exactly once, ensuring that fragmented
state tracking does not lead to duplicate registrations.
2026-05-12 07:27:22 -07:00
Jonathan Hui 76db9dfec8 [cli] remove invalid log when tx buffer is full (#13091)
In CliUartOutput, if otPlatUartFlush() fails when trying to send
buffered output to make room for new output, it logs a warning using
otLogWarnPlat. However, this warning is added to the same full
buffer, which does not help and can cause further issues.

This commit removes the offending log line as suggested in issue #7478.
2026-05-11 18:25:38 -07:00
Abtin Keshavarzian ddfd66526e [mlr] simplify multicast address state tracking (#13089)
This commit simplifies the tracking of Multicast Listener Registration
(MLR) state for IPv6 addresses by removing intermediate states and
relying on the original CoAP request payload.

Previously, `Mlr::Manager` used a 3-state system (`kStateToRegister`,
`kStateRegistering`, `kStateRegistered`) which required core structures
like `Child` and `Netif` to track transient registration states.

This commit reduces the state to a single boolean (`IsMlrRegistered`)
tracked in `ChildTable` and `ThreadNetif`. When a CoAP response is
received, `Mlr::Manager` now uses `GetDispatchingRequest()` to
retrieve the original TMR MLE request message, parses the
`Ip6AddressesTlv` to determine exactly which addresses were included
in the request, and updates the registration states based purely on
this info (minus any explicitly failed addresses).

This change improves robustness, reduces RAM usage by eliminating
state-tracking arrays, and significantly cleans up the logical flow
within the MLR manager.
2026-05-11 16:46:17 -07:00
Will Rosenberg 1f24ace91a [spinel] fix writeable size in spinel logging (#13094)
There exists a NULL-byte OOB in the spinel logging. The initial stack
buffer is initialized with an extra byte for the NULL-byte. However,
the full size is passed into `spinel_datatype_unpack_in_place()` which
interprets it as the valid writable size (`require_action(NULL !=
block_len_ptr && *block_len_ptr >= block_len, bail, (ret = -1, errno =
EINVAL));`).

When `block_len` is the length of the buffer, the NULL-byte write
after the function call will be OOB.
2026-05-11 11:26:31 -07:00
dependabot[bot] d011ade0ac github-actions: bump github/codeql-action from 4.35.2 to 4.35.4 (#13095)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.35.2 to 4.35.4.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/95e58e9a2cdfd71adc6e0353d5c52f41a045d225...68bde559dea0fdcac2102bfdf6230c5f70eb485e)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.35.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-11 09:06:33 -07:00
Abtin Keshavarzian 2a56b165c7 [mlr] extract AddressArray and add FindIn() to Ip6AddressesTlv (#13088)
This commit moves the `AddressArray` class out of the `Mlr::Manager`
and into a dedicated `mlr_types.hpp` file as `Mlr::AddressArray`. This
decouples the type from the manager, making it available for broader
use across the module.

Additionally, the logic for parsing the `Ip6AddressesTlv` is extracted
from `Mlr::Manager::ParseResponse()` into a new `FindIn()` method on
the TLV class itself. This centralizes the TLV parsing logic within
the TLV class, which is more idiomatic. The `FindIn()` method also
provides a safety guarantee by clearing the output `AddressArray` if
parsing fails.

The build system configurations (`BUILD.gn` and `CMakeLists.txt`) are
updated to include the newly added `mlr_types.cpp` file. Doxygen
documentation is also provided for the new types and methods.
2026-05-11 09:06:11 -07:00
Abtin Keshavarzian c650cede5a [coap] add mechanism to access request message in response handler (#13081)
This commit updates `CoapBase::PendingRequests` to track the request
currently being processed during callback invocation via the new
`mDispatchingRequest` pointer.

It also introduces `GetDispatchingRequest()` which returns a copy of
the original request `Message`. This enables response handler
callbacks to inspect the original request (for example to read
specific TLVs). The method is restricted to confirmable requests and
must only be called from within the context of a response handler.
The method `InvokeResponseHandler` is renamed to `DispatchResponse`
to align with the new nomenclature.
2026-05-11 09:05:46 -07:00
Jonathan Hui 0841be04fd [posix] detect and fail on unused radio URL parameters (#13087)
This commit enhances the radio URL parsing logic to detect and fail
when unused parameters are provided in the URL. This prevents typos
or unsupported parameters from being silently ignored.

The following changes were made:

- Updated ot::Url::Url to track parameter usage by appending a
  trailing '&' delimiter in Init() and replacing it with '\0'
  in GetValue() when a parameter is matched. This marks the
  parameter as used and removes any limit on the number of
  trackable parameters.
- Added a Validate() method to ot::Url::Url to verify that all
  parameters in the query string were accessed.
- Refactored ot::Posix::Radio to share a single RadioUrl instance
  with SpinelManager, ensuring all components track usage on the
  same URL object.
- Integrated Validate() calls in otSysInit() and platformTrelInit()
  to perform validation after all platform components have been
  initialized.
- Updated Radio::ProcessMaxPowerTable to use a local copy of the
  parameter string to avoid premature modification of the URL buffer.
- Adjusted RadioUrl and unit tests to provide sufficient buffer
  space for the additional tracking delimiter.
- Added new unit tests in tests/unit/test_url.cpp to verify the
  usage tracking and validation logic.
2026-05-09 10:04:07 -07:00
Abtin Keshavarzian 545a83efbf [mlr] remove CheckInvariants() method (#13082)
This commit removes the `CheckInvariants()` method and all its calls
from `Mlr::Manager`.

The `CheckInvariants()` method verified internal state consistency
by checking the `kStateRegistering` status of multicast addresses
against variables like `mPending` and `mSendDelay`. As the MLR module
is being prepared for upcoming structural updates, including changes
to how address states and delays are tracked, these specific invariant
checks are no longer applicable. Removing them clears the way for
the planned redesign of the MLR state machine.
2026-05-09 07:32:47 -07:00
Abtin Keshavarzian 294eb9a065 [mle] rate-limit scheduled discovery responses (#13086)
This commit introduces a cap on the number of concurrently scheduled
discovery responses in `Mle::DelayedSender`.

By adding the `CountMatchingSchedules()` method, we can now track how
many discovery responses are currently queued. The newly defined
constant `kMaxScheduledDiscoveryResponse` sets this limit to 16. If
the limit is reached, further `ScheduleDiscoveryResponse()` requests
are ignored.

This change protects the device from resource exhaustion (RAM, CPU,
and network) if it is flooded with discovery requests, preventing
potential Denial of Service (DoS) conditions.
2026-05-08 13:02:44 -07:00
Abtin Keshavarzian e6d9a13144 [border-router] add Deprecate() method in OnLinkPrefix (#13084)
This commit introduces the `Deprecate()` method in the `OnLinkPrefix`
class. This method properly deprecates an on-link prefix by setting
its preferred lifetime to zero and bounding the remaining valid
lifetime to a maximum of two hours from the current time.

Previously, `RxRaTracker` only called `ClearPreferredLifetime()`,
which left the valid lifetime unchanged. By replacing
`ClearPreferredLifetime()` with the new `Deprecate()` method, we
ensure that the valid lifetime of deprecated prefixes is also
bounded.

This change ensures that if a router is deemed unreachable, its
on-link prefixes will live for a maximum of 2 more hours. This
allows the state associated with an unreachable router to age out
more quickly, even if the router had previously advertised the on-link
prefix with long valid lifetime.
2026-05-08 13:02:15 -07:00
Abtin Keshavarzian f66e04c9b5 [mdns] simplify and limit multi-packet rx message lists (#13083)
This commit simplifies the logic for limiting the number of messages
tracked in `MultiPacketRxMessages`.

It introduces a new cap, `kMaxRxMsgEntries` (set to 64), to restrict
the total number of unique `RxMsgEntry` items being tracked,
preventing unbounded memory growth. Additionally, the existing
message limit per entry is renamed from `kMaxNumMessages` to
`kMaxNumMessagesPerEntry` and moved within the `RxMsgEntry` scope.
The manual `for` loop used to count existing messages in
`RxMsgEntry::Add` is replaced with a clean check using
`CountAllEntries()`.
2026-05-08 13:01:53 -07:00
Abtin Keshavarzian 1e78442055 [mlr] simplify and improve MLR response parsing (#13077)
This commit simplifies the `Mlr::Manager::ParseResponse()` method and
improves its robustness.

Specific improvements include:
- Initializing the local `error` with the CoAP response result and
  using `SuccessOrExit()` to cleanly handle transport-layer failures.
- Simplify parsing of of `Ip6AddressesTlv`, ensuring duplicate entries
  are added only once in the `aFailedAddresses` array.
- Remove redundant `Ip6AddressesTlv` TLV length checks. Same checks are
  now performed as IPv6 addresses are read from the TLV value.
- Updating `AddressArray::AddUnique()` to return an `Error`,
- Consolidating the logging logic directly into `ParseResponse()`,
  removing the separate `LogResponse()` helper method.
- Explicitly clearing the `aFailedAddresses` array at the beginning of
  the parsing process.
2026-05-08 13:00:22 -07:00
Abtin Keshavarzian a07c50c00e [mlr] extract registration delay scheduling into a helper method (#13074)
This commit refactors the logic for scheduling Multicast Listener
Registration (MLR) delays by replacing `UpdateReregistrationDelay(bool)`
with a new, more expressive method: `ScheduleNextRegistration()`.

The new method takes a `RegistrationRequest` enum (`kReregister` or
`kRenew`), clearly distinguishing between the two different scheduling
scenarios:

- `kReregister`: Triggered after re-attaching or when a Primary BBR
  is added/updated. This schedules a rapid registration attempt
  using a random delay between 1 and the configured BBR
  reregistration delay.

- `kRenew`: Triggered periodically. This schedules a standard
  registration renewal using a delay randomized between half the MLR
  timeout and the timeout minus a 9-second guard time
  (`kRenewGuardTime`), as mandated by Thread Spec.

This change also introduces constants for `kLongRenewTimeout` and
`kRenewGuardTime` to replace magic numbers, improving overall code
readability and maintainability.
2026-05-08 13:00:00 -07:00
Abtin Keshavarzian 91d00c5fd1 [cli] add multi-interpreter support (#13027)
This commit introduces an opaque `otCliInterpreter` type and a set of
new public C CLI APIs (e.g., `otCliInterpreterInit()`,
`otCliInterpreterInputLine()`) to support multiple, dynamically
allocated CLI interpreters per OpenThread instance.

This architecture allows applications to instantiate and manage
multiple concurrent CLI sessions. Backward compatibility is preserved
by retaining the original `otCli*` APIs, which now interact with a
single built-in static interpreter.

The `OPENTHREAD_CONFIG_CLI_STATIC_INTERPRETER_ENABLE` configuration
is also added. It enables support for the static interpreter and is
enabled by default. It can be disabled to save RAM in deployments
that solely use the multi-interpreter APIs.
2026-05-07 16:56:00 -05:00
Will Rosenberg 1e784183f4 [posix] fix ICMPv6 RA length calculation in tryProcessIcmp6RaMessage (#13035)
There exists a stack OOB read in `tryProcessIcmp6RaMessage()`. The bug
originates from the posix packet processing in
`processTransmit()`. When an ICMPv6 RA packet is sent, this triggers
`tryProcessIcmp6RaMessage()`, which calculates: `raLength = length +
(ra - data)`

However, the length passed is the packet size, which can go up to the
`char packet[kMaxIp6Size];` stack buffer size. The correct calculation
is `raLength = length - (ra - data)`.

This small mistake can make `raLength` larger than the total stack
buffer size, causing a read OOB during RA processing in
`otPlatBorderRoutingProcessIcmp6Ra()`.
2026-05-07 13:12:54 -07:00
Jonathan Hui 92d7b9f93f [ip6] cap recursion depth in HandleDatagram to 4 (#13065)
This commit introduces a recursion depth limit of 4 in
Ip6::HandleDatagram to prevent unbounded stack recursion from deeply
nested IPv6-in-IPv6 tunnel packets (NextHeader = 41).

This mirrors the safety limit fix implemented in the 6LoWPAN layer
decompress path (issue #12669).

A new Nexus test case `ipv6_recursion` has been added to construct
and verify that packets exceeding the depth limit are correctly
dropped with kErrorDrop, while valid nesting depth succeeds.
2026-05-07 11:34:53 -07:00
Jesse Thompson 91e7c33733 [nexus] stricter tests related to MLE role transitions (#13068)
Key changes:
* Added `mle_router_role_allowed` nexus test, which includes a test of
  the correct type of advertisement used by each type of node.
* Updated the `router_downgrade_on_sec_policy_change` nexus test
  to also test changes of the Router role allowed/disallowed when
  multiple factors are changed
* Updated checks in `verify_1_1_5_3_6.py` to verify that only Router
  advertisments are sent during the test, to verify that REED
  advertisements are not sent unless the unit is no longer
  attempting to upgrade
2026-05-07 13:18:09 -05:00
Jonathan Hui ef6fabd758 [border-agent] improve DTLS session resource management (#13078)
Every DTLS ClientHello from an unseen port previously allocated a
dynamic CoapDtlsSession on the heap before DTLS cookie verification.
This allowed multiple connection attempts to leave allocated sessions
active indefinitely, leading to high memory utilization.

To resolve this:
- Enforce a 15-second handshake timeout on newly allocated sessions.
  Connecting sessions that do not successfully finish the handshake
  within 15 seconds are cleanly disconnected and freed.
- Enforce a session limit cap of 16 concurrent secure sessions on the
  Border Agent. Reaching this limit immediately rejects new session
  connection requests before triggering heap allocation.
- Implement Nexus test case TestBorderAgentSessionsLimit to robustly
  verify both session limit rejection and handshake timeout behavior.
2026-05-07 09:06:30 -07:00
Yakun Xu 87fdaa6946 [simulation] add IPv6 loopback address support (#12828)
This commit adds support for IPv6 loopback address (::1) in the
simulation platform. When the local interface is set to the IPv6
loopback address, it uses the interface-local multicast group
(ff01::116) instead of the link-local group (ff02::116) for
node-to-node communication.

It also ensures that the `sin6_scope_id` is correctly set for the
loopback address in the transmission socket.
2026-05-07 07:37:40 -07:00
Jonathan Hui 3d731aae2f [coap] fix null-pointer dereference on Block2 invalid requests (#13079)
This commit fixes a deterministic null-pointer dereference in
CoapBase::ProcessBlock2Request when receiving a Block2 request
with block number greater than 0 without a preceding active
blockwise transfer.

Previously, when mLastResponse was null, the option copying logic
would unconditionally attempt to initialize the iterator with a
dereferenced mLastResponse pointer (iterator.Init(*mLastResponse)),
causing a segmentation fault crash.

This fix inserts a VerifyOrExit check on mLastResponse inside
ProcessBlock2Request. If mLastResponse is null, it returns the
kErrorNoFrameReceived error code. In ProcessBlockwiseRequest, this
is mapped to a 4.08 Request Entity Incomplete response, matching the
spec-compliant error handling behavior of Block1.

An automated reproduction and verification test case has also been
added to tests/nexus/test_coap_block.cpp.
2026-05-07 07:31:04 -07:00
Jonathan Hui 772ddb9802 [nexus] fix occasional failure of test 1_1_5_8_4 (#13075)
This commit fixes the occasional/flaky failure of the Nexus test
1_1_5_8_4 by addressing a joiner expiration issue and strictly
verifying MLE Discovery Responses.

In test_1_1_5_8_4.cpp, the joiner was added with a timeout of 100s in
Step 1. However, the total simulated elapsed time before Step 11
(when the joiner is checked) is exactly 104s. This causes the
joiner to expire occasionally/consistently, resulting in the Leader
skipping the MLE Discovery Response in Step 12.

We increase the joiner timeout to 1000s so that it stays active
throughout the test. In addition, we update verify_1_1_5_8_4.py to
strictly verify the Step 12 Discovery Response and perform packet
matching chronologically rather than relying on seeking backward to
idx10.
2026-05-07 07:30:51 -07:00
Abtin Keshavarzian 41e07366fa [mlr] extract address registration success evaluation into helper (#13071)
This commit introduces a new static helper method,
`Manager::DidRegisterSuccessfully()`, to evaluate whether a specific
multicast address was successfully registered based on the MLR response
status and the list of failed addresses.

Previously, this evaluation logic was duplicated and inline within
`Manager::Finish()` using the expression:
`success = aSuccess || !aFailedAddresses.IsEmptyOrContains(addr)`.
This logic was not immediately intuitive and required reasoning through
the boolean conditions to understand the intended behavior.

Extracting this into a dedicated helper method improves code
readability and maintainability. It simplifies `Finish()` by
clearly separating the outcome evaluation from the actual state
transition logic (`kStateRegistering` to `kStateRegistered` or
`kStateToRegister`).

Additionally, the unused `AddressArray::IsEmptyOrContains()` method
has been removed.
2026-05-07 07:30:14 -07:00
Abtin Keshavarzian dd33295ce9 [mac] add RxFrame::IsSecuredWith() helper method (#13064)
This commit introduces a new helper method, `RxFrame::IsSecuredWith()`,
which allows callers to cleanly verify if a received MAC frame has
security enabled and uses a specific set of allowed Key ID Modes.

This eliminates redundant logic in `ThreadLinkInfo::SetFrom()`, where
the code previously had to manually check `GetSecurityEnabled()`,
extract the Key ID Mode, and validate it against `kKeyIdMode0` or
`kKeyIdMode1`. Mac::ProcessCsl()` is updated to use this new method
to cleanly enforce that CSL IE processing only occurs on frames
secured with Key ID Mode 1

Crucially, this commit also updates `DataPollHandler::HandleDataPoll()`
to use this new helper. Previously, it only checked if the frame
was secured (`GetSecurityEnabled()`), which would accept frames
using any Key ID Mode (including mode 2 with fixed/known keys). By
restricting the data poll handling to only accept Key ID Mode 1, we
ensure that data polls are only processed if they are secured with
a valid Thread network key.
2026-05-06 22:32:57 -07:00
Abtin Keshavarzian e6134cb828 [ip6] enforce filter rules when Thread role is disabled (#13050)
This commit updates `Ip6::Filter::Apply()` to remove the exception
that allowed all unsecure link-local IPv6 datagrams to pass through
when the Thread role was disabled (e.g., when the interface is up
but Thread has not yet started).

By removing this check, the device now consistently enforces strict
port filtering at all times. Only explicitly allowed traffic, such
as MLE messages, commissioner traffic, or user-configured unsecure
ports, will be permitted, improving the overall security posture
regardless of the current Thread role state.

For testing and backward compatibility on reference devices, the
`mAllowUnsecureWhenDisabled` flag is introduced (available when
`OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE` is enabled). This allows
the legacy behavior to be restored via the new public APIs
`otIp6SetAllowUnsecureWhenDisabled()`. The new APIs are also provided
in CLI under `unsecureport allwhendisabled` command.
2026-05-06 22:29:13 -07:00
Abtin Keshavarzian 3c77c52136 [mlr] extract registration criteria into ShouldRegister() helper (#13073)
This commit introduces a new private helper method, `ShouldRegister()`,
to the `Manager` class. This method consolidates the checks required
to determine if the device should perform MLR.
2026-05-06 22:26:18 -07:00
Abtin Keshavarzian 129afad2f5 [key-manager] add ClearKek() to remove KEK when no longer needed (#13072)
This commit introduces the `KeyManager::ClearKek()` method, which clears
the `Kek` and resets the `mIsKekSet` flag.

The KEK is a temporary key used during the commissioning and entrust
phases. To improve security and key hygiene, this commit updates the
`Joiner` and `JoinerRouter` to explicitly clear the KEK once these
operations have concluded.

Specifically:
- `Joiner::Finish()` clears the KEK when finishing in `kStateEntrust`
  or `kStateJoined`.
- `JoinerRouter::HandleJoinerEntrustResponse()` clears the KEK
  immediately upon handling the entrust response, before scheduling
  any delayed entrusts (which set their own KEK from metadata).
2026-05-06 21:03:07 -07:00
Abtin Keshavarzian 763af19c5d [nexus] remove redundant cast in SendMlrRequest() (#13076)
This commit removes a redundant `static_cast<const uint8_t *>` when
calling `Tlv::Append<Ip6AddressesTlv>()` in `SendMlrRequest()` in
`test_1_2_MATN_TC_21.cpp`. Since the method accepts `const void *`
as its value argument, the explicit cast is unnecessary and can be
safely removed to simplify the code.
2026-05-06 22:59:44 -05:00
Yakun Xu 2fbc9f43d9 [test] separate size report workflow (#13057)
This commit breaks the size report workflow into two workflows so that
we can use `pull-request` to collect the data.
2026-05-06 17:52:37 -07:00
Abtin Keshavarzian 0db06ebc77 [network-data] reject Context ID 0 in ContextTlv::IsValid() (#13069)
This commit updates the `ContextTlv::IsValid()` method to reject
Context TLVs that specify a Context ID of zero.

According to the Thread specification, Context ID 0 is reserved for
the Mesh-Local Prefix and should not be distributed in the Network Data.
Adding this check ensures that such invalid TLVs are correctly
identified as malformed and dropped during Network Data processing.
2026-05-06 17:51:17 -07:00
Abtin Keshavarzian 7b200c79df [srp] clear name on ExtractLabels() failure in AdvertisingProxy (#13061)
This commit updates `AdvertisingProxy::CopyNameAndRemoveDomain()` to
properly handle potential errors returned by `Dns::Name::ExtractLabels()`.

Previously, any error returned by `ExtractLabels()` was ignored, which
could leave the output name buffer in an indeterminate state. With this
change, if extracting the labels fails, the name buffer is explicitly
cleared by setting its first character to `kNullChar`.

This prevents subsequent code from using uninitialized or partially
written data in the event of a parsing or buffer size error.
2026-05-06 17:46:54 -07:00
Jonathan Hui 35fe1f3fbe [nexus] fix flakiness in history_tracker test (#13070)
This commit resolves the flaky test failures occasionally observed
in the history_tracker Nexus test during ping verification.

The flakiness was caused by two primary issues:
1. Concurrent background Thread control traffic (e.g. multicast
   Hop-by-Hop Options packets) sometimes interleaving with the Echo
   Request pings, polluting the HistoryTracker queues and causing
   the strict chronological checks to fail.
2. The FTD child node upgrading to a Router due to the
   TooFewRouters network threshold rule, which dynamically changed
   its RLOC16 and caused NeighborRloc16 history checks to fail.

To fix these, we:
1. Set the child node's router eligibility to false after joining
   to prevent any unwanted topology changes or Rloc16 updates.
2. Refactored the strict Leader TX and Child RX chronological checks
   with robust iterative loops filtering specifically for the
   OT_ICMP6_TYPE_ECHO_REQUEST packets.

Verified 100% stable after executing a loop of 50 successful runs.
2026-05-06 17:41:05 -07:00
Jonathan Hui 76dab3b963 [ip6] enforce strictly in-order IPv6 fragment reassembly (#13067)
This commit enforces strictly in-order IPv6 fragment reassembly
in the core stack to improve reassembly robustness and correctness.

Previously, the reassembly engine did not track contiguous bytes
received. An out-of-order or gapped fragment containing the M=0
flag could incorrectly trigger reassembly completion, potentially
leading to the forwarding or processing of incomplete packets.

To resolve this, we now:
1. Enforce that reassembly must start with a fragment offset
   of 0.
2. Verify that any subsequent fragment aligns perfectly with the
   offset where the contiguous payload data currently ends
   (`offset == message->GetOffset()`).
3. Safely advance `message->GetOffset()` as each fragment is
   successfully appended to keep track of the contiguous
   reassembled byte range.
4. Added a robust Nexus test case verifying that gapped
   reassembly is properly dropped and blocked.

This strictly in-order validation approach is consistent with the
preexisting 6LoWPAN fragment reassembly in MeshForwarder.
2026-05-06 17:40:25 -07:00
Jonathan Hui 88188e958b [lowpan] cap recursion depth in Lowpan::Compress to 4 (#13066)
This commit adds aRecursionDepth tracking and limit check in
Lowpan::Compress methods to prevent excessive recursive stack usage
from recursive compression of highly nested IP-in-IP headers.

Specifically:
- Threads aRecursionDepth parameter through 3-arg and 4-arg (now
  5-arg) Compress wrappers.
- Enforces aRecursionDepth <= kMaxRecursionDepth (4) in Compress.
- Increments recursion depth on nested IP-in-IP calls (Ip6::kProtoIp6).
- Adds a Nexus integration test to verify that highly nested packets
  are compressed up to the threshold limit, and successfully fall back
  to uncompressed inline transmission without excessive stack usage.
2026-05-06 15:33:42 -07:00
Jonathan Hui e2e7a78af5 [mac] enforce KEK validation for Key ID Mode 0 frames (#13056)
This commit adds validation to ensure that Key ID Mode 0 (implied KEK)
secured frames are only accepted if a KEK is configured. If KEK is not
configured, the frame is rejected.

Specifically:
- Added `mIsKekSet` boolean member variable to `KeyManager` to track
  KEK status.
- Implemented `KeyManager::IsKekSet()` to check if a KEK is
  configured.
- Enforced a guard in `Mac::ProcessReceiveSecurity()` under
  `kKeyIdMode0` to immediately reject incoming frames with
  `kErrorSecurity` when the KEK is not configured.
- Added unit test `TestKeyManagerKek()` in `test_pskc.cpp` to
  verify that `IsKekSet()` transitions from `false` to `true` as
  expected.
2026-05-06 14:51:38 -07:00
Jonathan Hui 74c2531738 [mle] handle invalid leader mask in HandleAddressSolicitResponse (#13063)
This commit resolves an issue in HandleAddressSolicitResponse where
a malformed or invalid leader-supplied Router ID Mask omitting the
leader ID could trigger an assertion.

When a node receives an Address Solicit Response, it installs the new
router ID mask. If the leader's router ID is missing from the mask,
the Router entry for the leader is removed from the local router table.
Subsequently, when the node tries to ensure it has a valid next hop
and cost towards the leader, `mRouterTable.GetLeader()` returns `nullptr`,
leading to an `OT_ASSERT(leader != nullptr)` failure or a null-pointer
write when assertions are disabled.

This is resolved by safely verifying that the leader's router ID is
indeed present in the received router ID mask before applying the
routing update, ensuring `GetLeader()` is guaranteed to find it.
2026-05-06 13:38:40 -07:00
Jonathan Hui 6954667dca [mac] enforce KeyIdMode1 for CSL synchronization processing (#13062)
This commit updates `Mac::ProcessCsl` to explicitly verify that CSL IE
data frames are secured using `KeyIdMode1` (utilizing the network key
and per-neighbor frame counter freshness checks).
2026-05-06 13:38:28 -07:00
Jonathan Hui 02d000c747 [dns-client] fix double-free of mSavedResponse on duplicate response (#13060)
Fix a double-free of `mSavedResponse` in `Dns::Client` when processing
duplicate DNS responses matching an active query.

When an SRV/TXT query needs to resolve a host address (AAAA), the DNS
client allocates a chained `newQuery` to handle it. If duplicate
responses are processed before the query chain is finalized, they
trigger multiple AAAA resolution allocations for the same parent query.
Because the new query inherits `mSavedResponse` from the parent query's
`QueryInfo`, multiple chained queries end up aliasing/sharing the same
cloned `mSavedResponse` message. During finalization, `FreeQuery`
walks the chain and frees `mSavedResponse` for each query, leading to
a double-free of the shared `Message` and free-list/heap corruption.

This commit resolves the issue by:
1. Rejecting duplicate responses early in `ParseResponse` if a response
   has already been received and saved for the query
   (`info.mSavedResponse != nullptr`), returning `kErrorDrop`.
2. Initializing the `mSavedResponse` field of the `QueryInfo` struct
   to `nullptr` before allocating the host resolution query (`newQuery`)
   to prevent it from inheriting a potentially non-null saved response
   from its parent.
2026-05-06 12:32:11 -07:00
Abtin Keshavarzian 7e646d19dc [cli] add OutputResult() in Utils (#13034)
This commit add a `OutputResult()` wrapper method in the `Utils` base
class.

Previously, several CLI sub-modules (`Dns`, `History`, `LinkMetrics`,
`MeshDiag`, and `PingSender`) implemented their own `OutputResult()`
wrappers that simply delegated to the `Interpreter`. Since all these
sub-modules inherit from `Utils`, this functionality is now provided
directly by the base class, removing redundant code and simplifying
the sub-module implementations.
2026-05-06 11:10:09 -07:00
Abtin Keshavarzian aae952a8a2 [mlr] introduce Mlr namespace and rename types (#13053)
This commit introduces the `Mlr` namespace to encapsulate all
Multicast Listener Registration related types and logic, improving
overall code organization and readability.

The following primary renames were performed:
- `MlrManager` to `Mlr::Manager`
- `MlrState` to `Mlr::State`
- `MlrStatus` to `Mlr::Status`
- Constants like `kMlrSuccess` to `Mlr::kStatusSuccess`

Additionally, methods within the newly scoped `Mlr::Manager` class
have been simplified by removing redundant `Mlr` prefixes (e.g.,
`SendMlr()` is now `Send()`, `FinishMlr()` is now `Finish()`).

External modules and tests have been updated to reference the new
scoped names.
2026-05-06 10:41:20 -07:00
Abtin Keshavarzian 8cbf0daae4 [thread-tlvs] add Ip6AddressesTlv::AppendTo() helper method (#13049)
This commit extracts the logic for appending an `Ip6AddressesTlv` into
a new `static` helper method, `Ip6AddressesTlv::AppendTo()`.

Previously, multiple locations in the codebase manually managed the
TLV construction and appending. This change centralizes this logic,
simplifying the call sites in `BackboneRouter::Manager` and
`MlrManager`.
2026-05-06 10:40:31 -07:00
Jonathan Hui 2dfac4d545 [ip6] restrict MPL option processing to Hop-by-Hop header (#13055)
RFC 7731 Section 4 specifies that the MPL Option MUST only reside
within a Hop-by-Hop Options extension header. However, previously,
Ip6::HandleOptions processed MplOption::kType regardless of whether the
enclosing header was Hop-by-Hop or Destination Options.

This commit fixes the issue by adding a boolean parameter to
Ip6::HandleOptions indicating if the enclosing header is Hop-by-Hop.
MplOption::kType is now only processed if this parameter is true.
If the MPL Option is encountered in a Destination Options header,
it is treated as unrecognized, and because its type action mandates
discarding the packet, the datagram is dropped safely.
2026-05-06 10:36:56 -07:00
Jonathan Hui 430034214e [mesh-forwarder] enhance EID-RLOC cache updates (#13054)
Gate `MeshForwarder::UpdateEidRlocCacheAndStaleChild` on link
security, ensuring that the received frame has security enabled.

Adding the link security check ensures that only fully authenticated
data frames (successfully decrypted and verified at the MAC layer)
can influence the EID-to-RLOC cache and the child table states.
2026-05-06 10:35:15 -07:00
Jonathan Hui e29e44b0c2 [ip6] drop host-untrusted IP-in-IP packets (#13052)
Host-untrusted IP-in-IP packets could reach the local TMF socket
without the intended port checks on the receive path if destined to
the Border Router's own OMR address with an inner destination set to
the Thread-side link-local address. When the outer message is
decapsulated, it recurses through the IPv6 stack receive path while
retaining its HOST_UNTRUSTED origin, but local UDP socket dispatching
lacks equivalent origin checks.

This commit introduces a validation check in Ip6::HandleDatagram to
immediately drop any message from a host-untrusted origin with a
next header of kProtoIp6 (IP-in-IP encapsulation). This securely
prevents this receive-path processing and the corresponding
forwarding behavior.

Added the tmf_origin Nexus integration test to verify that
host-untrusted IP-in-IP packets are successfully dropped by
returning kErrorDrop.
2026-05-06 10:35:01 -07:00
Abtin Keshavarzian 941a317899 [nexus] group and reorder methods in Node class (#13029)
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.
2026-05-05 17:58:17 -07:00
Jonathan Hui 99e21445b5 [mle] fix child state handling in ProcessAddressRegistrationTlv (#13051)
This commit removes an overly strict `OT_ASSERT` on child state
validity inside `ProcessAddressRegistrationTlv`.

When a valid child transitions to a link-reestablishment state
(e.g., `kStateChildUpdateRequest` or `kStateChildIdRequest`) with
registered MLR addresses, its MLR registered set is preserved. The
subsequent processing of the Child Update Response or Child ID Request
causes `ProcessAddressRegistrationTlv` to be invoked while the child
is not yet back in `kStateValid`, which triggers the assertion on the
parent router/leader.

Since the parsing logic and `MlrManager` handle non-valid child states
gracefully, this assertion is deleted.
2026-05-05 17:26:28 -07:00
Jonathan Hui 36b398ef61 [tmf] enforce link security for all TMF messages (#13048)
This commit updates Tmf::Agent::Filter to require link-layer security
for all incoming TMF requests.

Thread Management Framework (TMF) messages are used for network
management and configuration. The Thread specification requires that
all TMF messages be secured. While individual handlers often have
specific checks, enforcing this at the TMF Agent level provides a
consistent security layer for all TMF traffic.

For most TMF messages, security is provided by the Network Key. For
commissioning-related messages (like Joiner Entrust), security is
provided by the Key Encryption Key (KEK). In all cases, a valid TMF
message must have link-layer security enabled.

This change prevents unauthenticated attackers from sending unsecured
TMF messages to manipulate network state or configuration.
2026-05-05 15:22:45 -07:00
Abtin Keshavarzian bf79332530 [tasklet] fix Unpost() behavior during tasklet processing (#13039)
This commit fixes an issue where a tasklet could not be successfully
unposted if it was already scheduled for execution in the current
event loop iteration.

Previously, `Scheduler::ProcessQueuedTasklets()` copied and cleared the
queued tasklets before running them. If a running tasklet called
`Unpost()` on another tasklet that was also in the copied list, the
unpost operation would fail to remove it because it only checked the
main queue.

To address this, the `Scheduler` now explicitly maintains two separate
queues: `mPostedQueue` and `mRuningQueue`. The `Tasklet::Unpost()`
method is updated to remove the target tasklet from both queues,
ensuring it is correctly dequeued even if it is pending in the running
list.

The queue logic is encapsulated into a nested `Queue` class to manage
the circular singly linked-list operations cleanly. Additionally, unit
tests are expanded to cover scenarios where tasklets post or unpost
other tasklets during execution.
2026-05-05 12:12:37 -07:00
Jonathan Hui d0cab9aaba [joiner] require link security for Joiner Entrust (#13046)
This commit adds an explicit check in Joiner::HandleTmf<kUriJoinerEntrust>
to verify that the received message has link-layer security enabled.

According to the Thread specification, the Joiner Entrust message MUST
be protected by link-layer security using the Key Encryption Key (KEK).
Previously, this check was missing, allowing an unauthenticated
attacker to send unsecured Joiner Entrust messages. Such messages
could inject invalid network configuration, causing the device to
fail to attach to the correct network after a reboot.

By verifying IsLinkSecurityEnabled(), we ensure that the message
was successfully decrypted using the KEK (since the network key is
not yet known by the Joiner), thus authenticating the sender as the
valid Commissioner or Joiner Router.
2026-05-05 11:14:49 -07:00
Abtin Keshavarzian b45a1ad57c [cli] handle duplicate registration in Interpreter::SetUserCommands() (#13018)
This commit updates the `Interpreter::SetUserCommands()` method to
detect if a set of CLI commands is already registered. If a duplicate
registration is detected, the method now returns `OT_ERROR_NONE` and
exits early without consuming an additional slot in the user commands
table. It also ensures that `OT_ERROR_FAILED` is only returned when
there are no available slots for a new registration.
2026-05-05 09:36:49 -07:00
Abtin Keshavarzian 69dd33699f [mlr] simplify SendMlrMessage() arguments (#13043)
This commit simplifies the `MlrManager::SendMlrMessage()` method by
removing the `void *aContext` parameter.

Previously, all callers (`SendMlr()` and `RegisterMulticastListeners()`)
were passing `this` as the context for the CoAP response handler. The
context is now passed directly as `this` when invoking
`Tmf::Agent::SendMessageTo()`, removing the need to thread it through
the method arguments.
2026-05-05 07:50:10 -07:00
Abtin Keshavarzian 40ebd8d07f [router-table] append Route TLV directly to message (#13042)
This commit updates the way Route TLV is constructed and appended to
messages. Previously, a `RouteTlv` object with a large fixed-size
`mRouteData` array was allocated on the stack, filled by
`RouterTable`, and then appended to the message.

To simplify the code and improve efficiently a new helper method
`RouterTable::AppendRouteTlv()` is introduced which appends the TLV
content directly in the `Message`. It uses `Tlv::StartTlv()` and
`Tlv::EndTlv()` to encapsulate the `RouterIdMask` and the iteratively
appended route data entries.

A helper method `RouteTlv::AppendRouteDataEntry()` is added  which
handles encoding and adding a Route Data Entry, including the the
bit-packing logic(the staggered 1.5-byte packing under
`OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE`).
2026-05-05 07:49:35 -07:00
Jonathan Hui 8e0e65da63 [github-actions] migrate simulation tests to Nexus (#13041)
This commit removes several simulation test jobs from the GitHub Actions
workflows, specifically 'simulation-1.1.yml' and 'simulation-1.4.yml'.

The following jobs were removed:
- packet-verification
- cli-ftd
- cli-mtd
- cli-time-sync
- thread-1-4

These tests have been migrated to the Nexus test framework, which
allows for more efficient and scalable network simulations by
running multiple OpenThread nodes within a single process.
2026-05-05 07:48:32 -07:00
Abtin Keshavarzian 3f82c1dfa5 [bbr] simplify MulticastListenersTable implementation (#13036)
This commit simplifies the `MulticastListenersTable` by replacing the
custom heap-based sorting logic with a standard `Array` and integrating
an internal `TimerMilli` (`mTimer`) to handle entry expirations.

Previously, the table maintained a min-heap based on expiration times
(`FixHeap`, `SiftHeapElemDown`, `SiftHeapElemUp`) and required
external calls to `Expire()` every second. The new implementation
uses `mListeners.FindMatching()` and `mListeners.RemoveAllMatching()`,
significantly reducing code complexity and maintenance overhead.

The unit tests in `test_multicast_listeners_table.cpp` are also updated
to reflect the simplified model
2026-05-05 07:46:31 -07:00
Abtin Keshavarzian 4c12431b68 [cli] replace static Interpreter::GetInterpreter() calls (#13033)
This commit updates the CLI sub-modules to use a new, non-static
`GetInterpreter()` method provided by the `Utils` base class, rather
than relying on the static `Interpreter::GetInterpreter()` which
returns a global singleton.

The `Utils::GetInterpreter()` method downcasts its associated
`OutputImplementer` reference to the specific `Interpreter` instance
it belongs to. `OutputImplementer` is a base class of `Interpreter`.

This change is a step towards adding support for multiple CLI
interpreters (per OpenThread instance).

Additionally, the `OutputImplementer` constructor is made `protected`
as it is intended to serve as a base class.
2026-05-05 07:45:19 -07:00
Abtin Keshavarzian dca8d995d5 [instance] use constexpr for instance alignment size calculations (#13026)
This commit refactors the instance allocation logic in `Instance` to
use `constexpr size_t` constants replacing the preprocessor macros
(`OT_DEFINE_ALIGNED_VAR` and `OT_ALIGNED_VAR_SIZE`).

The new constants `kInstanceSizeInUint64s` and
`kMultiInstanceSizeInUint64s` provide better type safety and are more
idiomatic C++. The raw storage arrays (`gInstanceRaw` and
`gMultiInstanceRaw`) are now explicitly defined as `uint64_t` arrays
using these calculated sizes.

Additionally, this commit introduces `kNumStaticInstances` to represent
the configured number of multiple static instances.
2026-05-05 07:44:14 -07:00
Abtin Keshavarzian 4384c66e7b [mle] consolidate role transition management in RoleTransitioner (#12983)
This commit introduces the `RoleTransitioner` class (renamed from
`RouterRoleTransition`) to centralize the management of router role
eligibility, thresholds, and transitions.

The following state and logic are moved from the `Mle` class into
the `RoleTransitioner`:
- Router role eligibility and allowance state (`mRouterEligible`,
  `mRouterRoleAllowed`).
- Upgrade and downgrade thresholds.
- Downgrade blocking state (`mDowngradeBlocked`).
- Transition decision logic (`DecideWhetherToUpgrade()`,
  `DecideWhetherToDowngrade()`).
- The transition jitter timer and its management.

By consolidating these responsibilities, the complexity of the main
`Mle` class is reduced, and the role transition process is more
explicitly managed within its own sub-component.
2026-05-05 07:42:08 -07:00
Abtin Keshavarzian bdea2ae98c [trel] defer channel check in Link::ProcessReceivedPacket() (#13011)
This commit updates `Trel::Link::ProcessReceivedPacket()` to move
channel mismatch validation until after the acknowledgment logic.

TREL ACKs serve as a mechanism to monitor link status between peers.
By deferring the channel check, we ensure that TREL packets requiring
an acknowledgment are correctly acknowledged at the TREL layer even
if they are not further processed.

A primary use case is the MLE Announce message, which is sent on a
different channel as a broadcast. At the TREL layer, this broadcast
is converted to unicast TREL packet transmissions to each peer on the
same PAN, with packets marked to request a TREL ACK. This change
ensures the receiving TREL peer sends an ACK for such packets,
maintaining link monitoring, while still dropping the packet at the
TREL link layer due to the channel mismatch.
2026-05-04 10:02:55 -07:00
sarveshkumarv3 73cc8a5c05 [posix] add uart-exclusive option to enable flock / TIOCEXCL (#13015)
When uart-exclusive is specified as a radio URL parameter, the UART
device is locked using flock(LOCK_EX) to prevent concurrent access,
and TIOCEXCL is set where supported.
2026-05-04 09:23:57 -07:00
arnulfrupp 928c78a01b [tcat] implement rate limitation for TCAT TLVs 0x10, 0x11 and 0x12 and remove TLV 0x14 (#12211)
This commit implements rate limitation for the TCAT commands Present
PSKd Hash TLV (0x10), Present PSKc Hash TLV (0x11) and Present
Install-code Hash TLV (0x12) to prevent password guessing attacks.

It also removes the TCAT command Request PSKd Hash TLV (0x14), to
prevent offline password guessing attacks with a single Hash value
retrieved from the device.

Note: The commit does not remove the Request PSKd Hash TLV
implementation in the Python commissioner such that the non-existence
of the command TLV can still be tested.
2026-05-04 07:10:19 -07:00
sarveshkumarv3 d27c618ccb [posix] handle RCP disconnection (EOF from read()) (#13006)
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-05-04 07:07:54 -07:00
Abtin Keshavarzian 611c62126a [mle] use compact Route TLV in Link Accept to child neighbors (#13012)
This commit enhances MLE where a full Route TLV could be appended to
a Link Accept message sent to a child neighbor, potentially leading
to a message requiring lowpan fragmentation.

Previously, `Mle::SendLinkAccept()` relied on a `Router` pointer to
determine whether to use a full or compact Route TLV. When the Link
Request originated from a child, this pointer was null, causing a
full Route TLV to be used.

The changes in this commit include:
- Updating the `LinkAcceptInfo` struct to track the RLOC16 of the Link
  Request sender.
- Updating `Mle::TxMessage::AppendRouteTlv()` and adding
  `AppendCompactRouteTlv()` to replace the previous single method that
  took a `Neighbor` pointer. This makes the intent clearer and
  supports both router and child neighbors.
- Updating `RouterTable::FillRouteTlv()` to take an RLOC16 instead of
  a `Neighbor` pointer. It uses `Mle::RouterIdFromRloc16()` to ensure
  that if the destination is a child, its parent's Router ID is
  included in the compact Route TLV.
- Includes new Nexus test `test_compact_route_tlv` to validate the
  use of compact Route TLV in Link Accept.
2026-05-04 06:46:25 -07:00
Jonathan Hui 1e3fd039e2 [tests] remove test_route_table.py (#13025)
This commit removes the test_route_table.py test file
from the thread-cert test suite.
2026-05-04 06:42:12 -07:00
Jonathan Hui e7565cc51c [tests] remove test_ping.py (#13024)
This commit removes the test_ping.py test file from the
thread-cert test suite.

The ping functionality tested by this file is already
well covered by existing Nexus tests (e.g.,
test_ipv6_source_selection.cpp, test_radio_filter.cpp),
so this file is no longer needed.
2026-05-04 06:41:57 -07:00
dependabot[bot] 864f5ed373 github-actions: bump actions/download-artifact from 5.0.0 to 8.0.1 (#13040)
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 5.0.0 to 8.0.1.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/634f93cb2916e3fdff6788551b99b062d0335ce0...3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: 8.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-04 06:40:49 -07:00
Jonathan Hui fb274efe68 [nexus] migrate test_history_tracker to Nexus (#13023)
This commit migrates the test_history_tracker.py test
from the thread-cert test suite to the Nexus test
framework as a new C++ test.

The new C++ test, test_history_tracker.cpp, covers:
- Role changes (detached -> leader -> disabled)
- NetInfo age up to 49 days
- Child mode Rn changes
- Ping between leader and child, verifying message
  types, checksums, priority, and success flags

It directly uses HistoryTracker::Local methods instead
of the C APIs.
2026-04-30 18:52:22 -07:00
Jonathan Hui d4a7f2d0a4 [tests] remove test_set_mliid cert test (#13022) 2026-04-30 18:52:12 -07:00
Abtin Keshavarzian e0650292e2 [neighbor-table] introduce core Iterator type (#13020)
This commit introduces `NeighborTable::Iterator` and
`NeighborTable::kIteratorInit` as core type aliases for
the public `otNeighborInfoIterator` and its initializer
`OT_NEIGHBOR_INFO_ITERATOR_INIT`.
2026-04-30 16:31:08 -07:00
Abtin Keshavarzian fe3594e4e6 [tests] add nexus test for FED rx-only link establishment (#13019)
This commit adds a new Nexus test `TestFedRxOnlyLinkEstablishment` to
verify that a Full End Device (FED) successfully establishes rx-only
links with all its neighboring routers in the network.

The test forms a topology with a leader and 15 routers, then adds an
FED child. It uses the `NeighborTable` callback to track the addition
of routers to the FED's neighbor table and ensures that it
eventually establishes links with all available neighboring routers.
2026-04-30 16:30:26 -07:00
Abtin Keshavarzian 54dd6f0e7a [cli] move public C APIs to dedicated cli_api.cpp (#13016)
This commit moves the public C APIs for the CLI from `cli.cpp` to
a new dedicated file `cli_api.cpp`.
2026-04-30 12:22:45 -07:00
Abtin Keshavarzian 7650ecca55 [radio] rename local variable in SetMacKey() (#13013)
This commit renames the local variable `aKeyType` to `keyType` in
`Radio::SetMacKey()` to align with the project's naming conventions.
The `a` prefix is reserved for function arguments, while local
variables use `lowerCamelCase` without a prefix.
2026-04-30 08:14:03 -07:00
Jonathan Hui 7319d405f8 [nexus] migrate test_radio_filter.py to nexus (#13010)
This commit migrates the functionality covered by
`tests/scripts/thread-cert/test_radio_filter.py` to a new Nexus test
`tests/nexus/test_radio_filter.cpp`.

The new test covers:
- Initial state of radio filter (disabled).
- Enabling radio filter on Router blocks pings.
- Disabling radio filter on Router restores pings.
- Enabling radio filter on SED causes it to detach.
- Disabling radio filter on SED allows it to reattach.

To make the test pass in Nexus, the following fixes were applied:
- Set external poll period to 40ms for SED to receive ping replies.
- Forced parent search on SED using `BecomeChild()` to avoid long
  backoff interval.

The energy scan portion of the original test is skipped because
`otPlatRadioEnergyScan` is not implemented in the Nexus platform.

The original Python test file is removed.
2026-04-29 17:28:29 -07:00
Jonathan Hui 2e1fbc1f7b [nexus] migrate test_coaps.py to nexus (#13009)
This commit migrates the functionality covered by
`tests/scripts/thread-cert/test_coaps.py` to a new Nexus test
`tests/nexus/test_coaps.cpp`.

The new test covers:
- CoAP Secure with PSK.
- CoAP Secure with X.509 certificates.

The X509 test is conditionally compiled based on
`MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED`.

The original Python test file is removed.
2026-04-29 17:28:04 -07:00
Abtin Keshavarzian a97fa5bd32 [router-table] rename FindNextHopOf() to FindNextHopTowards() (#13008)
This commit renames the `RouterTable::FindNextHopOf()` method to
`RouterTable::FindNextHopTowards()` to more accurately reflect its
purpose: finding the next hop on the path towards a given destination
router.
2026-04-29 15:45:14 -07:00
Jonathan Hui d145aafeea [nexus] migrate CoAP observe test to Nexus (#13005)
This commit migrates the functionality covered by test_coap_observe.py
to the Nexus test framework.

- Enabled OPENTHREAD_CONFIG_COAP_OBSERVE_API_ENABLE in Nexus config.
- Created test_coap_observe.cpp to test CoAP observations and
  notifications in a simulated network.
- Handled edge cases in the test to avoid segfaults during cancel
  response processing.
- Removed the old Python test test_coap_observe.py.
2026-04-29 15:18:36 -07:00
Jonathan Hui 5db0dd3dcb [nexus] fix flaky test 1_2_MATN_TC_10 by increasing wait time (#13007)
This commit addresses an occasional failure in test 1_2_MATN_TC_10
where the Router's ping reply was not found in Step 8.

- Increased the time advanced in Step 8 from 10 seconds
  (kStabilizationTime) to 20 seconds (2 * kStabilizationTime).
- This allows more time for address resolution (NS/NA) and packet
  transmission in the simulated environment.
- Verified that the test passes consistently with 100 consecutive
  successful runs after applying this fix.
2026-04-29 13:36:11 -07:00
Jonathan Hui 84f682486e [nexus] migrate CoAP block transfer test to Nexus (#13003)
This commit migrates the functionality covered by test_coap_block.py
to the Nexus test framework.

- Enabled OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE in Nexus
  config.
- Created test_coap_block.cpp to test CoAP GET and PUT block
  transfers in a simulated network.
- Removed the old Python test test_coap_block.py.
2026-04-29 13:30:42 -07:00
Abtin Keshavarzian 2cf0bdae62 [vendor-info] add vendor OUI support (#12991)
This commit introduces support for configuring and retrieving a vendor
OUI-24 (Organizationally Unique Identifier). It defines the new
`OPENTHREAD_CONFIG_NET_DIAG_VENDOR_OUI` configuration option and adds
the `otThreadGetVendorOui()` and `otThreadSetVendorOui()` APIs.

When specified, the vendor OUI is included in the `BorderAgent`
mDNS/DNS-SD TXT data under the `vo` key.

The `VendorInfo` class is updated to manage the OUI value. This
commit also adds the `vendor oui` CLI command to get or set this
property. Finally, it updates the tests to validate the presence and
correctness of the new `vo` key in the TXT data.
2026-04-29 15:09:43 -05:00
Abtin Keshavarzian d37e9df698 [mle] remove OPENTHREAD_CONFIG_MLE_IP_ADDRS_TO_REGISTER (#12997)
This commit removes the `OPENTHREAD_CONFIG_MLE_IP_ADDRS_TO_REGISTER`
configuration option and the logic in `Mle` that limited the number of
IPv6 addresses registered by an MTD with its parent.

By removing this limit, MTDs will now attempt to register all their
valid unicast and multicast addresses. The parent router still
enforces its own limit on the number of addresses it accepts and
stores per child via `OPENTHREAD_CONFIG_MLE_IP_ADDRS_PER_CHILD`.

An error check is added to `openthread-core-config-check.h` to inform
users of the removal of this configuration macro.
2026-04-29 08:49:41 -07:00
Abtin Keshavarzian badb895045 [mlr] move address count constants to mlr_types.hpp (#12995)
This commit moves the constants for the minimum and maximum number of
IPv6 addresses allowed in a Multicast Listener Registration (MLR)
request from the `Ip6AddressesTlv` class to `mlr_types.hpp`.

The new constants are named `kMlrMinIp6Addresses` and
`kMlrMaxIp6Addresses`. This change decouples the protocol-specific
limits from the TLV definition, which is more appropriate as these
limits are specific to the MLR process rather than the TLV itself.

The `Ip6AddressesTlv` class is simplified to a `typedef` of `TlvInfo`.
Call sites in `MlrManager`, `BackboneRouter::Manager`, and `NcpBase`
are updated accordingly.
2026-04-28 18:38:18 -07:00
Abtin Keshavarzian 7a8634649f [mle] consolidate RouteTlv definitions (#12994)
This commit combines the two separate definitions of the `RouteTlv`
class, which were previously conditionally compiled based on the
`OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE` configuration, into a
single unified class definition.

The `#if`/`#else` preprocessor directives are now localized within the
specific getter and setter methods (e.g., `GetRouteDataEntryCount()`,
`GetRouteCost()`, `SetRouteData()`) to handle the different routing
data formats. This removes significant code duplication for shared
methods such as `Init()`, `IsValid()`, `GetRouterIdSequence()`, and
`IsSingleton()`.
2026-04-28 18:37:23 -07:00
Jonathan Hui ef3122b496 [nexus] migrate test_ping_lla_src.py to nexus (#12990)
This commit migrates the test_ping_lla_src.py script from thread-cert
to the Nexus test framework.

The new test_ping_lla_src.cpp implements the same test logic:
- Forms a network with a Leader and two Routers.
- Verifies that pings using a Link-Local Address (LLA) as the source
  succeed when sent to a neighbor's Mesh-Local EID (ML-EID).
- Verifies that pings using an LLA source fail when sent to a
  non-neighbor's ML-EID, as LLAs are only valid for single-hop
  communication.
- Verifies that external routes are not used for LLA-sourced packets.

To support this migration, the Nexus Core class was enhanced with:
- Overloads for SendAndVerifyEchoRequest that allow specifying a
  source address.
- New SendAndVerifyNoEchoResponse methods to verify that no echo
  response is received (useful for negative test scenarios).

Changes:
- Added tests/nexus/test_ping_lla_src.cpp
- Updated tests/nexus/CMakeLists.txt to include the new test.
- Enhanced tests/nexus/platform/nexus_core.hpp/cpp with new helpers.
- Removed tests/scripts/thread-cert/test_ping_lla_src.py.
2026-04-28 14:36:19 -07:00
Jonathan Hui 752581826b [github-actions] free disk space in Nexus workflow jobs (#12996)
Add the jlumbroso/free-disk-space action to all jobs in the Nexus
workflow. This ensures that the runner has sufficient disk space to
complete the build and test tasks, preventing failures due to exhausted
disk resources on GitHub-hosted runners.
2026-04-28 14:36:03 -07:00
Jonathan Hui 3f0cf36419 [nexus] configure parent search backoff interval (#12993)
Added OPENTHREAD_CONFIG_PARENT_SEARCH_BACKOFF_INTERVAL with a value of
10 minutes (10 * 60 seconds) to the Nexus core configuration. This
helps in controlling the backoff behavior during parent search in the
simulator, making it more interactive.
2026-04-28 12:47:21 -07:00
Jonathan Hui d8d1fe2134 [nexus] migrate test_pbbr_aloc.py to nexus (#12989)
This commit migrates the 'test_pbbr_aloc.py' script from the
thread-cert framework to the Nexus simulation framework.

The new 'test_pbbr_aloc.cpp' replicates the original test:
- Forms a network with PBBR, Leader, and Router nodes.
- Enables Backbone Router (BBR) on the PBBR node and waits for it
  to become the Primary BBR.
- Verifies connectivity to the Leader ALOC (0xfc00) and the PBBR
  ALOC (0xfc38) from the Router node using ICMPv6 Echo Requests.
- Confirms that the stack correctly uses Network Data for ALOC
  resolution.

Nexus tests provide faster and more scalable network simulations
within a single process, improving CI efficiency and reliability.

Original Python script 'tests/scripts/thread-cert/test_pbbr_aloc.py'
is removed as its functionality is now fully covered by Nexus.
2026-04-28 12:44:15 -07:00
Jonathan Hui 698c290a36 [nexus] migrate DNSSD special characters test to Nexus (#12972)
This commit migrates the test for DNSSD names with special characters
from the thread-cert functional tests to the Nexus simulation
framework.

The new Nexus test 'test_dnssd_name_with_special_chars.cpp' replicates
the logic from 'test_dnssd_name_with_special_chars.py' and covers:
- SRP service registration with an instance name containing special
  and Unicode characters ("O\T 网关").
- DNS-SD browse to discover the service instance.
- DNS-SD resolution of the service instance name, including
  verification of case-insensitive resolution.
2026-04-28 09:00:05 -07:00
MaikVermeulen c814ec7809 [posix] improve settings file resilience against corruption and power loss (#12872)
* [posix] truncate settings file to last valid offset on parse error

When Init() encounters a corrupt entry, it currently truncates the
entire file to 0 bytes, destroying all settings. Since the parse loop
already knows the exact offset where corruption starts, truncate to
that offset instead, preserving all entries that were successfully
parsed.

This prevents loss of the active operational dataset (and other
settings) when only trailing bytes are corrupt — a common failure
mode when power is lost during a write.

If corruption starts at offset 0 (no valid entries), behavior is
identical to the original code.

* [posix] fsync parent directory after settings file rename

SwapPersist() calls fsync() on the data file descriptor but does not
sync the parent directory after rename(). On journaling filesystems
(ext4, overlayfs), the rename metadata may not reach stable storage
before a power loss. This can leave the old swap file in place,
which triggers a parse error on the next Init().

Add a best-effort fsync() on the parent directory after the rename.
This is non-fatal since the file data is already persisted; only the
directory entry could lag behind.
2026-04-28 09:38:20 -05:00
Jonathan Hui 5bd05a573b [nexus] dynamically sync radio range circles with simulator parameters (#12987)
This commit exposes radio model parameters (path loss constant,
exponent, and sensitivity) and the minimum link request margin from
the Nexus simulator backend to the frontend.

Changes in backend:
- Expose constants in `RadioModel` and `Radio`.
- Add `GetRadioParameters` RPC to `simulation.proto` and implement it
  in gRPC and WASM bindings.
- Expose `OPENTHREAD_CONFIG_MLE_LINK_REQUEST_MARGIN_MIN` and
  `OPENTHREAD_CONFIG_MLE_PARTITION_MERGE_MARGIN_MIN` via the new RPC.

Changes in config:
- Set `OPENTHREAD_CONFIG_MLE_LINK_REQUEST_MARGIN_MIN` and
  `OPENTHREAD_CONFIG_MLE_PARTITION_MERGE_MARGIN_MIN` to 5 dB in
  `openthread-core-nexus-config.h`.

This allows the frontend to calculate and render circles dynamically.
2026-04-27 22:27:36 -07:00
Abtin Keshavarzian 2d14e3ddab [array] add DoesArrayContain() helper function (#12985)
This commit introduces the `DoesArrayContain()` template function to
check if a given item is present in a fixed-size C array. The template
arguments are deduced by the compiler, allowing callers to simply use
`DoesArrayContain(aArray, aItem)`.

It also updates `Manager::CoapDtlsSession::ReadSteeringDataTlv()` and
`Ip6::HandleDatagram()` to use this new helper function instead of
using manual `for` loops to iterate over `kEnrollerValidSteeringDataLengths`
and `kForwardIcmpTypes` arrays respectively.
2026-04-27 21:24:25 -07:00
Abtin Keshavarzian 81d4fd23c9 [mle] use bit-utils in RouteTlv for route data manipulation (#12939)
This commit updates the `RouteTlv` implementation to use `ReadBits` and
`WriteBits` from `bit-utils` for reading and writing route data entries
(Link Quality In/Out and Route Cost). This simplifies the bitwise
operations and improves readability.
2026-04-27 21:23:52 -07:00
dependabot[bot] 928e37b504 Bump lxml from 5.3.0 to 6.1.0 in /tests/scripts/thread-cert (#12958)
Bumps [lxml](https://github.com/lxml/lxml) from 5.3.0 to 6.1.0.
- [Release notes](https://github.com/lxml/lxml/releases)
- [Changelog](https://github.com/lxml/lxml/blob/master/CHANGES.txt)
- [Commits](https://github.com/lxml/lxml/compare/lxml-5.3.0...lxml-6.1.0)

---
updated-dependencies:
- dependency-name: lxml
  dependency-version: 6.1.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-27 21:22:42 -07:00
Jonathan Hui e2e5cba98c [nexus] migrate test_dnssd.py to nexus (#12975)
This commit migrates the DNS-SD test from the thread-cert Python
framework to the Nexus C++ framework.

The new Nexus test 'test_dnssd.cpp' replicates the original test
scenario and functionality:
- Formation of a Thread network with multiple SRP clients and a
  server.
- Service registration with subtypes via SRP.
- DNS browsing for full service types and specific subtypes.
- DNS address (AAAA) and service (SRV/TXT/AAAA) resolution.
- Specific DNS record queries for SRV and KEY record types.
- Verification of DNS behavior for non-existent records.

The original Python script 'tests/scripts/thread-cert/test_dnssd.py'
is removed as its functionality is now fully covered by Nexus.

Nexus tests provide faster and more scalable network simulations
within a single process, improving CI efficiency and reliability.
2026-04-27 18:57:22 -07:00
Jonathan Hui fc4ebb1aaa [nexus] migrate test_service.py to nexus (#12974)
This commit migrates the test_service.py script from thread-cert to the
Nexus test framework.

The new test_service.cpp implements the same test logic:
- Forms a network with a Leader and two Routers.
- Adds and removes services on different nodes.
- Verifies that Service Anycast Locators (ALOCs) are correctly
  added to and removed from the nodes' unicast addresses.
- Confirms reachability of the ALOCs using ICMPv6 Echo Requests
  from all nodes in the network.
- Ensures ALOCs become unreachable after the service is removed
  from the network data.

Changes:
- Added tests/nexus/test_service.cpp
- Updated tests/nexus/CMakeLists.txt to include the new test.
- Removed tests/scripts/thread-cert/test_service.py.
2026-04-27 18:57:07 -07:00
Abtin Keshavarzian 1413778a09 [mle] restrict SetPreferredRouterId() API to REF_DEVICE (#12973)
This commit restricts the API to set a preferred router ID under
`OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE`. This feature is intended
for testing and therefore be excluded from standard builds to ensure
compliance with the Thread Specification.
2026-04-27 17:04:20 -07:00
Jonathan Hui 71d43b5cca [nexus] clear last parent ID on router/leader role change (#12986)
In `Nexus::Core::HandleStateChanged`, the `lastParentId` was not
cleared when a device transitioned to the Router or Leader role. This
could cause stale parent associations to persist, leading to incorrect
link state reporting in the visualizer during subsequent role
transitions (e.g., when a former Leader merges into a partition and
becomes a Child/REED).

This fix clears `lastParentId` (sets it to `0xffff`) when the device
becomes a Router or Leader, ensuring a fresh state for parent
tracking.
2026-04-27 17:21:17 -05:00
Jonathan Hui 0f66392f9c [nexus] migrate on-mesh prefix test to nexus (#12963)
This commit migrates 'test_on_mesh_prefix.py' from the thread-cert
functional tests to the Nexus simulation framework.

The new Nexus test 'test_on_mesh_prefix.cpp' covers:
- Propagation of stable and non-stable on-mesh prefixes.
- Different Network Data request behavior for MEDs and SEDs.
- MEDs receiving both stable and non-stable prefixes.
- SEDs receiving only stable prefixes.
- IPv6 address configuration (SLAAC) for all prefixes.
- Reachability verification via ICMPv6 Echo Request/Response.

Migrating to Nexus provides faster execution and improves the
reliability of the functional test suite.
2026-04-27 16:34:37 -05:00
Jonathan Hui bbb8e7ad15 [nexus] migrate router multicast link request test to nexus (#12966)
This commit migrates the router multicast link request test from the
thread-cert functional tests to the Nexus simulation framework.

The new Nexus test 'test_router_multicast_link_request.cpp' covers:
- Verification of a REED node becoming a router.
- Multicast Link Request transmission to neighboring routers.
- Quick link establishment with multiple neighbors after role upgrade.

The original Python test 'test_router_multicast_link_request.py' is
removed as its functionality is now fully covered by the Nexus test.
2026-04-27 13:02:40 -07:00
Jonathan Hui 8f5a9ff4b8 [nexus] migrate srp server anycast test to nexus (#12951)
This commit migrates the SRP server anycast mode test from the
thread-cert Python script to the Nexus test framework.

The new Nexus test `test_srp_server_anycast_mode.cpp` covers:
- SRP Server configuration in both Anycast and Unicast modes.
- Proper publication of SRP Server information in Network Data.
- SRP Client auto-start and server selection logic.
- Service registration and verification in both address modes.
- DNS browsing for registered SRP services.

Nexus tests allow for faster and more scalable network simulations
within a single process, improving CI efficiency.

Removed:
- tests/scripts/thread-cert/test_srp_server_anycast_mode.py
2026-04-27 13:02:17 -07:00
Jonathan Hui 419decf91e [nexus] migrate test_reset to Nexus (#12971)
Migrate legacy Python test `test_reset.py` to Nexus C++ test
`test_reset.cpp`.

The test verifies that OpenThread correctly recovers network state,
specifically frame counters and datasets, after sequential resets of
nodes in a multi-hop topology (Leader <-> Router <-> ED).

The test sequence:
- Establish multi-hop topology: Leader <-> Router <-> ED.
- Send 1010 pings from ED to Leader to advance the frame counter
  beyond the default storage threshold (1000).
- Reset Leader, Router, and ED sequentially.
- Verify end-to-end connectivity after resets, confirming that frame
  counters were correctly recovered from non-volatile storage.

Legacy `tests/scripts/thread-cert/test_reset.py` is removed as its
functionality is now fully covered by the Nexus test.
2026-04-27 13:00:34 -05:00
Jonathan Hui e74aebb2bd [nexus] migrate router and leader reboot tests to Nexus (#12970)
This commit migrates the following tests from thread-cert to Nexus:
- test_router_reboot_multiple_link_request.py
- test_leader_reboot_multiple_link_request.py

New Nexus tests cover:
- Router rebooting and sending multiple Link Requests when isolated.
- Leader rebooting and sending multiple Link Requests when isolated.

The original Python cert tests are removed as they are now fully
covered by the Nexus framework.
2026-04-27 13:00:17 -05:00
dependabot[bot] b72272fcb1 github-actions: bump actions/upload-artifact from 7.0.0 to 7.0.1 (#12984)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 7.0.0 to 7.0.1.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/bbbca2ddaa5d8feaa63e36b76fdaad77386f024f...043fb46d1a93c77aae656e7c1c64a875d1fc6a0a)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: 7.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-27 07:17:57 -07:00
Jonathan Hui d1da39b8b9 [nexus] fix occasional failure in anycast test (#12982) 2026-04-25 18:50:07 -07:00
Abtin Keshavarzian f4f13b6d5b [nexus] add test for OT_MLE_LONG_ROUTES feature (#12956)
This commit adds a new Nexus test to verify the functionality of the
MLE long routes experimental feature, which allows path costs to
exceed the standard limit of 15.

The new test `TestLongRoutes` in `test_long_routes.cpp` forms a
topology consisting of a leader and a chain of 25 routers. It then
validates that the path cost from the last router in the chain to the
leader is correctly reported as 25 using `GetPathCostToLeader()`.

Supporting changes include:
- Updating `build.sh` to support a `long_routes` build target that
  enables `OT_MLE_LONG_ROUTES`.
- Adding the `long_routes` test to `CMakeLists.txt` with the
  appropriate labels.
- Introducing a new GitHub workflow job `nexus-long-routes-tests` in
  `nexus.yml` to automate the execution of this test.
2026-04-25 10:22:06 -07:00
Jonathan Hui 5340cfabc3 [nexus] migrate test_router_reattach.py to nexus (#12967)
This commit migrates the router reattach test from the thread-cert
Python framework to the Nexus C++ framework.

The new Nexus test 'test_router_reattach.cpp' replicates the
original test scenario:
- A full 32-node router network is formed.
- Router upgrade/downgrade thresholds are set to 32.
- A router is reset and verified to re-attach and reclaim its
  router role.
- The test ensures the router does not downgrade after the router
  selection jitter interval.

The original Python script 'tests/scripts/thread-cert/
test_router_reattach.py' is removed as its functionality is now
fully covered by Nexus.

Nexus tests provide faster and more scalable network simulations
within a single process, improving CI efficiency.
2026-04-23 02:47:41 -05:00
Jonathan Hui 33e47882d8 [nexus] migrate anycast test to nexus (#12964)
This commit migrates the anycast routing test from the thread-cert
functional tests to the Nexus simulation framework.

The new Nexus test 'test_anycast.cpp' replicates the linear topology
(R1-R2-R3-R4-R5) and verifies:
- Anycast routing for DHCPv6 Agent (ds/cs) ALOCs.
- Dynamic routing updates when multiple anycast servers are present.
- Traffic routing to the nearest anycast destination.

The original Python test 'test_anycast.py' is removed as its
functionality is now fully covered by the Nexus test.
2026-04-23 02:36:39 -05:00
Jonathan Hui 297fb501a0 [nexus] migrate anycast locator test to Nexus (#12962)
This commit migrates the anycast locator test from the thread-cert
functional tests to the Nexus simulation framework.

The new Nexus test 'test_anycast_locator.cpp' covers:
- Anycast Locator (ALOC) resolution for the Leader from all nodes.
- Custom service ALOC resolution when only one node provides it.
- Closest-node ALOC resolution when multiple nodes provide the same
  service in a line topology (LEADER-R1-R2-R3-R4).
- Verification that nodes resolve to the nearest service instance.

The original Python test 'test_anycast_locator.py' is removed as its
functionality is now fully covered by the Nexus test.
2026-04-23 01:02:33 -05:00
Abtin Keshavarzian db7fd231f0 [thread-tlv] simplify Ip6AddressesTlv implementation (#12965)
This commit simplifies the `Ip6AddressesTlv` by removing the dedicated
class definition and instead defining it as a `TlvInfo` for the
`ThreadTlv::kIp6Addresses` type.

The usage of `Ip6AddressesTlv` is updated in `BbrManager`,
`MlrManager`, and related tests to use `Tlv::StartTlv()` and
`Tlv::EndTlv()` when appending the TLV to messages.
2026-04-23 01:02:05 -05:00
Abtin Keshavarzian b7df29080d [mle] use entry count instead of byte length in RouteTlv (#12957)
This commit renames `GetRouteDataLength()` and `SetRouteDataLength()`
to `GetRouteDataEntryCount()` and `SetRouteDataEntryCount()` in the
`RouteTlv` class.

When `OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE` is enabled, the
route data entries use a packed format (12 bits or 1.5 bytes per
entry). Consequently, the byte length of the route data field in
the TLV is no longer equal to the number of route entries.

This change ensures that `GetRouteDataEntryCount()` correctly
calculates the number of entries from the TLV length and
`SetRouteDataEntryCount()` sets the TLV length correctly based on
the entry count.
2026-04-23 01:01:44 -05:00
Jonathan Hui 8fbe09e2b5 [nexus] migrate test_srp_ttl.py to nexus (#12960)
This commit migrates the SRP TTL test from the thread-cert Python
framework to the Nexus C++ framework.

The new Nexus test `test_srp_ttl.cpp` covers all four TTL clamping
cases originally implemented in `test_srp_ttl.py`:
1. CLIENT_TTL < TTL_MIN < LEASE_MAX => Clamped to TTL_MIN.
2. TTL_MIN < CLIENT_TTL < TTL_MAX < LEASE_MAX => Used CLIENT_TTL.
3. TTL_MAX < LEASE_MAX < CLIENT_TTL => Clamped to TTL_MAX.
4. LEASE_MAX < TTL_MAX < CLIENT_TTL => Clamped to LEASE_MAX.

Nexus tests provide faster and more scalable network simulations
within a single process, improving CI efficiency.

The original Python script `tests/scripts/thread-cert/test_srp_ttl.py`
is removed as its functionality is now fully covered by Nexus.
2026-04-22 04:18:34 -05:00
Jonathan Hui 706e93f017 [nexus] fix flaky nexus test router_downgrade_on_sec_policy_change (#12959)
The test was failing occasionally due to the unpredictable timing of
tick-aligned timers and dataset propagation in simulations.

Specifically:
1) The router's jittered timeout (minimum 1 second) could expire
   in as little as 1ms if an MLE TimeTick occurred immediately
   after the security policy update.
2) Dataset propagation via MLE Advertisements could take up to
   32 seconds, making immediate checks on the router's role
   unreliable.

This commit fixes the flakiness by:
- Replacing flaky router role checks with `IsRouterRoleAllowed()`
  assertions. This verifies that the security policy has been
  successfully propagated and applied, regardless of whether the
  actual role transition has completed.
- Increasing the propagation wait time to 5 seconds. This provides
  a safe margin for simulated radio propagation while remaining
  well within the leader's 10-second downgrade delay.
- Ensuring both the leader and router are verified for policy
  application in both phases of the test.
- Maintaining the final checks to ensure both nodes eventually
  become detached after the full downgrade delay (150 seconds).

The fix was verified with 1000 consecutive successful iterations.
2026-04-22 02:56:07 -05:00
Jonathan Hui 0a97d566de [nexus] migrate srp server reboot port test to nexus (#12952)
This commit migrates the SRP server reboot port test from the
thread-cert functional tests to the Nexus simulation framework.

The new Nexus test 'test_srp_server_reboot_port.cpp' covers:
- SRP server address mode configuration (Unicast).
- SRP client auto-start discovery of the server.
- SRP server reboot (disable/enable) without node reboot.
- Verification that the server selects a new port after each reboot.
- Robustness of service re-registration over 25 reboot iterations.

The original Python test 'test_srp_server_reboot_port.py' is removed
as its functionality is now fully covered by the Nexus test.
2026-04-22 02:27:17 -05:00
Jonathan Hui 0cf450af44 [nexus] migrate SRP diff lease test to Nexus (#12950)
This commit migrates the SRP register services with different
lease test from the thread-cert Python framework to the Nexus
test framework.

The new Nexus test (test_srp_register_services_diff_lease.cpp)
reproduces the functionality of the original Python test:
- Registration of multiple services with different lease/key-lease
  intervals.
- Verification of per-service lease values on the SRP server.
- Ensuring key-lease is always at least as long as the lease.
- Validating lease renewal and expiry behaviors.
- Testing dynamic changes to default client lease and TTL.

Migrating to Nexus allows for faster and more scalable network
simulations within a single process.
2026-04-21 09:31:49 -05:00
Jonathan Hui 33e163424e [nexus] migrate srp_client_save_server_info to nexus (#12947)
This commit migrates the srp_client_save_server_info test from the
thread-cert Python-based test framework to the Nexus C++ simulation
framework.

The new Nexus test (test_srp_client_save_server_info.cpp) verifies:
- SRP client selects an SRP server when auto-start is enabled.
- SRP client sticks to the current server even if other SRP servers
  become available.
- SRP client saves and reuses the selected server info across SRP
  client stops and restarts.
- SRP client selects a new server if the current one becomes
  unavailable.
- SRP client sticks to the new server even if the old one returns.

The original Python test script is removed as its functionality is
now fully covered by the new Nexus test.
2026-04-21 08:59:07 -05:00
Jonathan Hui a51677de94 [nexus] migrate srp scale test to nexus (#12949)
This commit migrates the test_srp_register_500_services.py test from
the thread-cert test suite to the Nexus platform.

The new C++ test (tests/nexus/test_srp_scale.cpp) implements the same
functionality: it verifies that 25 SRP clients (13 routers and 12
FEDs) can successfully register a total of 500 services (20 services
per client) with a single SRP server (the leader).

The commit includes:
- Removal of the original Python test file.
- Addition of the new Nexus C++ test file.
- Integration of the new test into CMakeLists.txt and
  run_nexus_tests.sh.
2026-04-21 07:42:46 -05:00
Jonathan Hui acef2288ca [nexus] migrate test_srp_client_remove_host to Nexus (#12946)
This commit migrates the SRP client host removal test from the
thread-cert Python-based framework to the Nexus framework.

The new C++ implementation in tests/nexus/test_srp_client_remove_host.cpp
covers the same scenarios as the original Python script:
- Successful registration of SRP host and services.
- Verification that ClearHostAndServices() does not immediately remove
  server-side state.
- Verification that RemoveHostAndServices(removeKey=False,
  sendUnregToServer=True) marks the host and services as deleted on the
  SRP server.
- Verification that RemoveHostAndServices(removeKey=True,
  sendUnregToServer=True) fully removes the host and service entries
  from the SRP server.

The original Python script test_srp_client_remove_host.py is removed
as its functionality is now fully covered by the Nexus test.
2026-04-21 06:33:39 -05:00
Jonathan Hui 828ffefb21 [nexus] migrate SRP many services MTU test to Nexus (#12948)
This commit migrates the test_srp_many_services_mtu_check.py from
tests/scripts/thread-cert to the Nexus test framework.

The new test, tests/nexus/test_srp_many_services_mtu_check.cpp,
verifies that the SRP client correctly handles and splits SRP Update
messages when registering a large number of services that exceed
the IPv6 MTU size (1280 bytes).

Changes:
- Added tests/nexus/test_srp_many_services_mtu_check.cpp.
- Updated tests/nexus/CMakeLists.txt to include the new test.
- Removed tests/scripts/thread-cert/test_srp_many_services_mtu_check.py.
2026-04-21 05:20:38 -05:00
Jonathan Hui 2f7ccf5d3e [nexus] stabilize reed_address_solicit_rejected test (#12955)
This commit stabilizes the Nexus reed_address_solicit_rejected test by
increasing the wait time for network data synchronization from 5 seconds
to 15 seconds.

The test was occasionally failing because the 5-second wait was
sometimes insufficient for the REED's service registration to reach the
leader and for the updated network data to be broadcast back to the
REED. Increasing the delay to 15 seconds provides more robust buffer for
these network events.

Verified by running the test 50 times in a loop without failures.
2026-04-21 05:04:00 -05:00
Jonathan Hui a5908e5858 [nexus] migrate mle_msg_key_seq_jump test to nexus (#12933)
This commit migrates the `test_mle_msg_key_seq_jump.py` cert test to the
Nexus simulation framework.

The new Nexus test `test_mle_msg_key_seq_jump.cpp` verifies that nodes
can correctly handle jumps in the MLE key sequence and stay attached to
the network. It covers scenarios like child triggering key sequence
updates via Child Update Request and routers propagating key sequence
updates.

The original Python test script is removed as its functionality is now
fully covered by the new Nexus test.
2026-04-21 04:43:19 -05:00
Jonathan Hui 005297b301 [nexus] migrate srp client lease change test to nexus (#12945)
This commit migrates the 'test_srp_client_change_lease.py' cert test
to the Nexus simulation framework.

The new Nexus test ('test_srp_client_change_lease.cpp') verifies:
- SRP registration with default lease and TTL.
- Updating the lease interval and ensuring it is reflected in SRP
  Update messages.
- Updating the TTL and ensuring it is reflected in SRP Update
  messages.
- Setting the TTL to 0 and ensuring the lease interval is used as
  the TTL in SRP Update messages.

The original Python test script is removed as its functionality is
now fully covered by the new Nexus test.
2026-04-21 04:34:43 -05:00
Jonathan Hui 4b4caf3485 [nexus] stabilize srp_auto_start test (#12954)
This commit stabilizes the Nexus SRP auto-start test by increasing
the synchronization wait time from 20 seconds to 30 seconds.

The test was occasionally failing in the Nexus environment because
the 20-second wait was sometimes insufficient for the SRP server
registration to fully propagate through the network data and for
the SRP client to process the update and complete its server
selection. Increasing the wait time to 30 seconds provides a more
robust buffer for these network synchronization events.

Verified by running the test 100 times in a loop without failures.
2026-04-21 02:39:10 -05:00
Jonathan Hui 39b982c8d6 [nexus] migrate ipv6 fragmentation test (#12932)
This commit migrates the `test_ipv6_fragmentation.py` cert test to the
Nexus simulation framework.

To support this migration, the Nexus core configuration was updated to
enable IPv6 fragmentation (`OPENTHREAD_CONFIG_IP6_FRAGMENTATION_ENABLE`).

The new Nexus test `test_ipv6_fragmentation.cpp` covers the validation
of IPv6 fragmentation and reassembly. It sends large ICMPv6 Echo
Requests exceeding the 1280-byte MTU between a Leader and a Router:
- 1952 bytes payload from Leader to Router
- 1831 bytes payload from Router to Leader

The original Python test script is removed as its functionality is now
fully covered by the new Nexus test.
2026-04-20 23:26:02 -05:00
Abtin Keshavarzian cd8e6776e8 [mle] encapsulate router ID sequence and mask in RouterIdMask (#12922)
This commit updates the `RouterIdSet` class, renaming it to
`RouterIdMask` and expanding it to encapsulate both the router ID
sequence number and the bitmask. This allows simplifying the
definition of `ThreadRouterMaskTlv` and `RouteTlv`.
2026-04-20 23:25:30 -05:00
dependabot[bot] b03df41b62 github-actions: bump github/codeql-action from 4.31.10 to 4.35.2 (#12943)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.31.10 to 4.35.2.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/cdefb33c0f6224e58673d9004f47f7cb3e328b89...95e58e9a2cdfd71adc6e0353d5c52f41a045d225)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.35.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-20 16:50:27 -05:00
Abtin Keshavarzian 1d6aa9c6d7 [mle] simplify TimeParameterTlv (#12923)
This commit simplifies the `TimeParameterTlv` implementation by
defining a `TimeParameterTlvValue` and using the `SimpleTlvInfo`
template to define `TimeParameterTlv`.
2026-04-20 16:50:01 -05:00
Jonathan Hui e88998abc3 [nexus] migrate test_srp_auto_start_mode to Nexus (#12944)
This commit migrates the SRP auto-start test from the Python-based
thread-cert test suite to the Nexus C++ test framework.

The new Nexus test replicates the logic of the original Python test:
- Forms a network with four router nodes.
- Verifies SRP client auto-start upon server discovery in netdata.
- Tests selection priority between multiple unicast and anycast
  SRP servers.
- Verifies selection based on anycast sequence numbers.
- Tests selection of specific unicast addresses published in
  Service Data.
- Confirms automatic failover and client stop/restart.

The original Python test file is removed as it is now covered by
the Nexus test suite.
2026-04-20 16:47:24 -05:00
Jonathan Hui 41979b593d [nexus] migrate test_netdata_publisher to Nexus (#12931)
This commit migrates the functionality of
tests/scripts/thread-cert/test_netdata_publisher.py to a new Nexus
test tests/nexus/test_netdata_publisher.cpp.

The new Nexus test covers:
- DNS/SRP Anycast entries (equal and different version numbers).
- DNS/SRP Unicast entries (service data and server data).
- Displacement of server data unicast by anycast entries.
- Publisher preference logic for DNS/SRP services.
- On-mesh prefix publisher preference and replacement.
- External route publisher preference and replacement.

Other changes:
- Add netdata_publisher to tests/nexus/CMakeLists.txt.
- Add netdata_publisher to default tests in tests/nexus/run_nexus_tests.sh.
- Remove the old tests/scripts/thread-cert/test_netdata_publisher.py.
2026-04-20 16:47:09 -05:00
Jonathan Hui 516472c1b5 [nexus] migrate key rotation and guard time test to nexus (#12937)
This commit migrates the cert test script to the Nexus simulation
framework.

The new Nexus test  covers:
- Initial key sequence counter and default key switch guard time.
- Dynamic updates of the key rotation time via Operational Dataset
  and verification of the 93% guard time calculation rule.
- Automatic key rotation after the rotation time interval expires.
- Verification that the key switch guard time correctly prevents
  nodes from updating their key sequence counter prematurely when
  receiving MLE messages with a higher sequence.
- Continued communication (ICMP Echo) between nodes even when key
  sequences are temporarily mismatched due to the guard timer.

The original Python test script is removed as its functionality is
now fully covered by the new Nexus test.
2026-04-20 09:26:18 -05:00
Jonathan Hui 2ed544115b [nexus] fix intermittent failure in dns_client_config_auto_start test (#12940)
This commit fixes an intermittent failure in the Nexus test
'dns_client_config_auto_start'. The test was occasionally failing
because the REED node was not upgrading to the Router role within
the previous 15-second stabilization period.

The Router role transition can take up to 120 seconds due to the
default 'ROUTER_SELECTION_JITTER' parameter. This commit increases
'kStabilizationTime' to 200 seconds to ensure the node has ample
time to become a router before the test proceeds to verify its
DNS configuration.
2026-04-20 08:59:21 -05:00
Suvesh Pratapa 9bff14609d [cli] make otPlatLogOutput weak to allow application override (#12888)
Make `otPlatLogOutput()` `OT_TOOL_WEAK` in `cli_logging.cpp` so that
applications can provide their own strong definition to customize
instance-aware log output behaviour.
2026-04-20 08:34:32 -05:00
Jonathan Hui 4e216d0d88 [nexus] migrate MAC scan test to nexus (#12938)
This commit migrates the 'test_mac_scan.py' cert test to the Nexus
simulation framework.

The new Nexus test 'test_mac_scan.cpp' verifies the IEEE 802.15.4
Active Scan (MAC scan) functionality. It forms a simple network
consisting of a Leader and a Router and performs an active scan
from the Leader to ensure it correctly discovers the Router's
beacon.

The original Python test script is removed as its functionality is
now fully covered by the new Nexus test.
2026-04-20 02:09:53 -05:00
Jonathan Hui 524240fdb0 [nexus] migrate dns_client_config_auto_start to nexus (#12936)
This commit migrates the dns_client_config_auto_start test from the
thread-cert Python-based test framework to the Nexus C++ simulation
framework.

The new Nexus test (test_dns_client_config_auto_start.cpp) verifies:
- DNS client uses the SRP server address automatically when no
  explicit config is set.
- Explicitly set DNS config takes precedence over auto-discovered
  SRP server address.
- Clearing an explicit DNS config allows the client to fall back to
  the auto-discovered SRP server address.
- DNS client updates its default config when the SRP server changes.

Changes:
- Added tests/nexus/test_dns_client_config_auto_start.cpp
- Updated tests/nexus/CMakeLists.txt to build the new test
- Updated tests/nexus/run_nexus_tests.sh to include it in default
- Removed tests/scripts/thread-cert/test_dns_client_config_auto_start.py
2026-04-20 02:09:35 -05:00
Jonathan Hui a07c892270 [nexus] migrate child supervision test to nexus (#12935)
This commit migrates the functional test for child supervision from
the thread-cert Python-based framework to the Nexus framework.

The original test in 'tests/scripts/thread-cert/test_child_supervision.py'
has been removed and replaced with a C++ implementation in
'tests/nexus/test_child_supervision.cpp'.

The new Nexus test covers:
- Verification of initial child supervision interval on parent and child.
- Dynamically updating the supervision interval and check timeout.
- Behavior when supervision messages are blocked (child detaching).
- Verification of connectivity when child supervision is disabled.
- Handling of zero supervision interval.

'tests/nexus/CMakeLists.txt' is updated to include the new test.
2026-04-20 02:09:19 -05:00
Jonathan Hui 2145cda437 [nexus] migrate REED address solicit rejected test to nexus (#12934)
This commit migrates the 'test_reed_address_solicit_rejected.py' test
from the thread-cert suite to the Nexus test framework.

The new Nexus test 'test_reed_address_solicit_rejected.cpp' covers:
- Verification that a REED node can successfully register a service and
  receive the corresponding Service ALOC (0xfc10).
- Verification that when a REED node's attempt to upgrade to a router
  is rejected by the Leader, it correctly remains a child while
  maintaining its Service ALOC.

The original Python script is removed as its functionality is now
fully covered by the Nexus implementation.
2026-04-20 02:09:01 -05:00
Jonathan Hui a5a5bc622a [nexus] migrate test_br_upgrade_router_role to nexus (#12921)
This commit migrates the functionality of the Python-based certification
test 'test_br_upgrade_router_role.py' to a new Nexus-based C++ test
'test_br_upgrade_router_role.cpp'.

The test verifies that Border Routers (BRs) providing IP connectivity
are eligible to request a router role upgrade even when the active
router count already meets the 'router_upgrade_threshold'.

Key test steps:
- Set router upgrade threshold to 2.
- Ensure three BRs remain in child role when 2 routers already exist.
- Verify BRs upgrade to router role when they provide external routes
  or prefixes, up to the limit of 2 BR routers.
- Verify that a third BR providing external routes remains a child.
- Verify that removing a route from one BR router triggers the child BR
  to upgrade to a router.

The Python test is removed as it is now covered by the Nexus test.
2026-04-20 02:08:28 -05:00
Jonathan Hui d8da3c3ae9 [nexus] set RSSI in simulated ACK frames (#12929)
Set the RSSI field in simulated MAC ACK frames in nexus_core.cpp.

Previously, the simulator did not populate the mRssi field in the
mInfo.mRxInfo structure of simulated ACK frames passed to
otPlatRadioTxDone. This caused OpenThread to ignore the RSSI of ACKs,
preventing the parentRss average from updating on successful data polls
from Sleepy End Devices (SEDs).

Now, the RSSI from the parent to the child is calculated using the radio
model and clamped to int8_t before being assigned to the ACK frame.
2026-04-19 16:43:34 -05:00
Jonathan Hui fba018f36e [nexus] migrate zero_len_external_route to nexus (#12930)
This commit migrates the test for zero-length external routes from a
Python script to the Nexus test framework. The original test was
test_zero_len_external_route.py in tests/scripts/thread-cert.

The new Nexus test test_zero_len_external_route.cpp replicates the
original test scenario:
- Forms a network with a Leader and two Routers.
- Verifies that adding a zero-length external route "::/0" on a Router
  allows routing to a manually added IPv6 address on that Router.
- Verifies that explicit external routes are preferred over on-mesh
  prefixes that have the default route flag set.
- Verifies that removing the external route causes traffic to be
  re-routed (and in this case, fail as intended when the destination
  is moved).
- Verifies that moving the address to another Router with a default
  route flag allows successful routing.

This commit also fixes a bug in Core::SendAndVerifyEchoRequest in
nexus_core.cpp where the ICMP handler was not always unregistered,
especially when failures occurred. This fix ensures that subsequent
handler registrations in the same process do not fail with
kErrorAlready.

Migrating to Nexus provides faster execution and better integration with
the core OpenThread codebase.
2026-04-19 16:40:44 -05:00
Jonathan Hui cea7e325b0 [nexus] migrate ipv6 source selection test to nexus (#12924)
This commit migrates the `test_ipv6_source_selection.py` cert test to
the Nexus simulation framework.

To support this migration, the Nexus framework was extended to allow
verifying the local (source) address on which an ICMP Echo Reply is
received. This is achieved by adding an overload to
`SendAndVerifyEchoRequest` that accepts an expected source address.

The new Nexus test `test_ipv6_source_selection.cpp` covers the
following scenarios:
- RLOC source for RLOC destination
- ML-EID source for ALOC destination
- ML-EID source for ML-EID destination
- Link-local source for Link-local destination
- ML-EID source for Realm-local multicast destination (ff03::1)
- GUA source for GUA destination
- GUA source for external address (via default route)

The original Python test script is removed as its functionality is now
fully covered by the new Nexus test.
2026-04-18 23:37:35 -05:00
Jonathan Hui 5b301fcb72 [nexus] refine CHILD_REMOVED event suppression (#12928)
Refine the event suppression logic in nexus_core.cpp when handling
NeighborTable::kChildRemoved events.

Previously, any valid neighbor found would suppress the event. Now, it
only suppresses the event if the node is found in the Router table.
This ensures that removal events for Sleepy End Devices (SEDs) are not
suppressed, allowing the link to disappear in the visualizer as
expected.
2026-04-18 21:59:02 -05:00
Jonathan Hui 87e9a39eb3 [nexus] fix unused variable warning in otPlatRadioTransmit (#12927)
This commit fixes a compiler warning in nexus_radio.cpp where the
aFrame parameter in otPlatRadioTransmit was considered unused in
non-debug builds. The variable is only used within an OT_ASSERT.

Using OT_UNUSED_VARIABLE is the standard OpenThread pattern to
address unused parameters and ensure clean builds across different
compilers and build configurations.
2026-04-18 21:55:25 -05:00
Jonathan Hui 932e00e12d [nexus] migrate router_downgrade_on_sec_policy_change to nexus (#12926)
This commit migrates the certification test for router downgrade on
security policy change from a Python script to the Nexus test framework.
The original test was test_router_downgrade_on_sec_policy_change.py in
tests/scripts/thread-cert.

The new Nexus test test_router_downgrade_on_sec_policy_change.cpp
replicates the original test scenario:
- Forms a network with a Leader and a Router.
- Verifies that both nodes are in the expected router/leader roles.
- Changes the security policy to disable 'R' bit (routers) and sets the
  version threshold to 7.
- Verifies that the Leader and Router do not immediately downgrade,
  respecting the mandatory 10-second delay.
- Verifies that restoring the original security policy before the
  timeout cancels the pending downgrade.
- Verifies that re-applying the security policy change leads to both
  nodes eventually downgrading to the detached state once the version
  threshold and router disable flags are propagated and the timer
  expires.

Migrating to Nexus provides faster execution using virtual time and a
more integrated environment for debugging core Thread logic.
2026-04-18 21:55:13 -05:00
Jonathan Hui d92a77c1b9 [nexus] fix intermittent failures in 1.4 DNS and PIC tests (#12925)
This commit addresses intermittent failures in Nexus tests 1_4_DNS_TC_1,
1_4_DNS_TC_5, 1_4_PIC_TC_1, 1_4_PIC_TC_3, and 1_4_PIC_TC_4.

The issue was caused by the 'ed1' node occasionally upgrading its role
from an End Device to a Router. When 'ed1' became a router, it would
sometimes use its Routing Locator (RLOC) as the source address for DNS
queries, whereas the verification scripts expected its Mesh Local
Endpoint Identifier (MLEID), leading to packet verification failures.

To resolve this, 'ed1' is now explicitly joined as a Full End Device
(FED) using 'Node::kAsFed' instead of the default Full Thread Device
(FTD) mode. This prevents 'ed1' from becoming a router and ensures it
maintains its End Device role throughout the test, providing stable
addressing for verification.
2026-04-18 21:54:43 -05:00
Jonathan Hui e01eea5c7e [nexus] migrate dataset_updater test to nexus (#12920)
This commit migrates the dataset_updater functional test from the
Python-based thread-cert framework to the Nexus simulation framework.

Nexus provides faster and more scalable network simulations within a
single process using virtual time.

The new test_dataset_updater.cpp covers:
- Network formation and child joining (MED and SED).
- Channel updates initiated by Leader and Router using DatasetUpdater.
- Dataset update overrides between nodes.

The legacy tests/scripts/thread-cert/test_dataset_updater.py is removed
as it is now redundant.
2026-04-18 21:54:17 -05:00
Jonathan Hui f76b876f22 [nexus] add test for informing previous parent on reattach (#12919)
This commit adds a new Nexus test to verify that a Sleepy End Device
(SED) correctly informs its previous parent after reattaching to a new
parent. This replicates the functionality of the now-deleted
test_inform_previous_parent_on_reattach.py script.

The test scenario involves:
- Forming a network with a Leader and a Router.
- Attaching a SED to the Leader.
- Simulating a link failure between the SED and Leader while allowing
  communication between the SED and Router.
- Verifying that the SED reattaches to the Router.
- Confirming that the SED sends an empty IPv6 message (Next Header 59)
  to the Leader's RLOC to inform it of the change.
- Ensuring the SED is successfully removed from the Leader's child
  table.

Migrating this test to Nexus allows for faster execution using virtual
time and single-process simulation.
2026-04-18 10:52:25 -05:00
Jonathan Hui 88f364af1b [tests] remove redundant SRP certification tests (#12910)
The following SRP test scripts in tests/scripts/thread-cert are
redundant as their functionality is now covered by the Nexus test
framework certification suite (test_1_3_SRP_TC_*):

- test_srp_register_single_service.py: Covered by Nexus
  test_1_3_SRP_TC_1.
- test_srp_lease.py: Covered by Nexus test_1_3_SRP_TC_3 (service
  lease) and test_1_3_SRP_TC_4 (key lease).
- test_srp_name_conflicts.py: Covered by Nexus test_1_3_SRP_TC_2.
- test_srp_auto_host_address.py: Covered by Nexus test_1_3_SRP_TC_13.
- test_srp_sub_type.py: Covered by Nexus test_1_3_SRP_TC_15.

Nexus tests are preferred as they run in a single process using
virtual time, making them faster and more reliable than the
multi-process simulation scripts.
2026-04-18 10:52:12 -05:00
Jonathan Hui 27321a2110 [nexus] add WebAssembly support using Emscripten (#12904)
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.
2026-04-17 15:25:28 -05:00
Abtin Keshavarzian c10b4e1da4 [logging] introduce log level override feature (#12903)
This commit introduces a mechanism to temporarily override the log
level. The `Instance` class now provides `OverrideLogLevel()` and
`RestoreLogLevel()` methods. When an override is active, the
effective log level is the maximum of the original user-set level and
the override level. If `SetLogLevel()` is called while an override is
active, it updates the original level and the effective level is
recomputed.

This ensures that log messages are generated only when needed,
without permanently losing the user's original log level
configuration.

The feature is controlled by the new configuration macro
`OPENTHREAD_CONFIG_LOG_LEVEL_OVERRIDE_ENABLE`.

A new Nexus unit test `test_log_override.cpp` is added to validate
the behavior of these new feature.
2026-04-17 13:23:14 -05:00
Jonathan Hui 5fad120d9b [tests] remove redundant MLE and connectivity tests (#12909)
The following test scripts in tests/scripts/thread-cert are now
redundant as their functionality is sufficiently covered by the Nexus
test framework:

- test_detach.py: Covered by Nexus MLE synchronization and parent
  selection tests.
- test_router_upgrade.py: Covered by 5.1.x Nexus router attachment
  tests.

Nexus tests are preferred for these scenarios as they execute in a
single process using virtual time, providing faster and more reliable
verification than the traditional multi-process simulation scripts.
2026-04-17 13:22:46 -05:00
Abtin Keshavarzian 064529cbfc [nexus] add helper to allow link between nodes in nexus (#12906)
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.
2026-04-17 13:22:27 -05:00
Abtin Keshavarzian 7eb59f71da [network-diag] introduce AnswerBuilder to manage answer messages (#12887)
This commit introduces `AnswerBuilder` class to track and manage
Network Diagnostic answer messages. This class is used when the
response to a query requires multiple CoAP answer messages. It
automatically manages the inclusion of the Query ID and the Answer
TLVs(providing message indexing and "more-to-follow" flags) in each
allocated answer message, while maintaining all answer messages in a
queue. The `NetworkDiagnostic::Server` is updated to use the
`AnswerBuilder`, simplifying the logic for preparing and sending
answers.

The `AnswerBuilder` class is added in a new header file
`network_diagnostic_types.hpp` to allow for its reuse by other
modules in the future.
2026-04-17 13:21:59 -05:00
Jonathan Hui 254043deec [nexus] add gRPC support and live demo (#12898)
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.
2026-04-16 22:05:19 -05:00
Abtin Keshavarzian e536562296 [mle] simplify CslClockAccuracyTlv (#12905)
This commit updates `CslClockAccuracyTlv` to use the `SimpleTlvInfo`
and a separate `CslClockAccuracyTlvValue` class. This change
simplifies how the TLV is appended to and read from messages
by leveraging the `Tlv::Append<TlvType>` and `Tlv::Find<TlvType>`
helper methods (avoiding the use of `FindTlv()`).
2026-04-16 10:27:08 -05:00
Jonathan Hui e43df01933 [github-actions] remove multiple-instance job from simulation-1.1.yml (#12897)
This commit removes the redundant `multiple-instance` job from the
`simulation-1.1.yml` workflow. This job was used to run Thread 1.1
certification tests with `OT_MULTIPLE_INSTANCE=ON`.

The job is being removed to streamline the CI process and reduce
redundant test coverage, as multiple-instance configurations are
sufficiently covered in other workflow files. The dependency list
for the coverage collection job is also updated to reflect this
removal.
2026-04-15 16:20:45 -05:00
Jonathan Hui e8a52ab654 [nexus] fix false suppression of CHILD_REMOVED events (#12902)
The previous logic for suppressing CHILD_REMOVED events was flawed. It
checked if the neighbor was not in the child table. However, since the
callback is triggered after the child is removed, it was always false,
leading to false suppression for all removed children.

This caused the parent node to never emit "link removed" events to the
UI when children detached, leading to inconsistent link states (dashed
lines) when only one direction was active.

This fix updates the logic to check if a neighbor entry exists in the
neighbor table with an established link (kStateValid). This ensures we
only suppress the event when the child has successfully transitioned to
a router role and established a valid link.
2026-04-15 15:56:01 -05:00
Abtin Keshavarzian 8a032575da [mle] check router role allowed before sending multicast adv (#12876)
This commit updates `Mle::SendMulticastAdvertisement()` to verify
that the router role is allowed by calling `IsRouterRoleAllowed()`
before proceeding to send the multicast MLE advertisement.
2026-04-14 23:38:56 -05:00
Jonathan Hui e2d07be235 [nexus] introduce simulation observer interface and hooks (#12894)
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.
2026-04-14 23:26:09 -05:00
Jonathan Hui 7829782b06 [ip6] enforce single Hop-by-Hop Options header rule (#12896)
RFC 8200 states that the Hop-by-Hop Options header MUST be the first
extension header and can only occur once in a packet. This commit
updates HandleExtensionHeaders to enforce this rule.

This fix prevents a potential infinite loop or exponential growth of
messages when multiple Hop-by-Hop headers (each containing an MPL
option) are processed. Previously, each MPL option could trigger its
own retransmission, and if these options were evicted from the MPL
SeedSet, they would be re-processed as new messages upon loopback,
leading to exponential growth and eventually a timeout.
2026-04-14 23:25:42 -05:00
Jonathan Hui 0a38d5f97b [nexus] introduce radio model for RSSI calculation (#12892)
This commit adds a new RadioModel class to simulate wireless propagation
characteristics between Nexus nodes. It implements a simple path-loss
model based on node distance to calculate RSSI.

Key changes include:
- Added RadioModel with CalculateRssi and ShouldDropPacket methods.
- Integrated RSSI calculation into the Core radio processing logic.
- Implemented packet dropping for signals below -100 dBm sensitivity.
- Added nexus_radio_model.cpp to the build system.
2026-04-14 16:35:28 -05:00
Abtin Keshavarzian 221a9cbbb0 [mle] track "router role allowed" state in a new variable (#12854)
This commit introduces a new member variable `mRouterRoleAllowed` in
the `Mle` class to cache the evaluation of whether the device is
currently permitted to operate as a router.

Previously, the `IsRouterEligible()` method evaluated several
conditions (e.g., `IsFullThreadDevice()`, `mRouterEligible` config,
and various fields in `SecurityPolicy`) every time it was called.
Since this method is invoked frequently across different `Mle`
operations, re-evaluating these conditions repeatedly was
inefficient.

The new `mRouterRoleAllowed` variable caches the final computed
result. It is updated via the `UpdateRouterRoleAllowed()` method
whenever any underlying input changes, such as:
- `Mle` starting.
- Configuration parameter updates (e.g., `SetRouterEligible()`).
- Security policy changes from the `KeyManager`.

This change centralizes the logic for handling role permission updates
into a single location (`UpdateRouterRoleAllowed()`). By
consolidating the actions taken when the allowed state changes, the
codebase is cleaner and easier to maintain and update.

It also provides a clearer conceptual distinction between the user's
router configuration (`mRouterEligible`) and the effective state
used by the device.
2026-04-14 14:15:22 -05:00
Jonathan Hui 582dc1cd67 [nexus] move TREL configuration to nexus-config header (#12891)
This commit moves the TREL configuration from the build script to the
nexus-config header file. This ensures that TREL is consistently enabled
for all nexus builds and simplifies the build script.

Specifically:
- Added OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE to
  tests/nexus/openthread-core-nexus-config.h.
- Removed OT_TREL from tests/nexus/build.sh and simplified the build
  options.
2026-04-14 13:13:39 -05:00
Jonathan Hui 47860a4eb4 [nexus] move multiple instance config to nexus config header (#12890)
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."
2026-04-14 13:12:29 -05:00
Esko Dijk 5c90231e48 [tcat] fix unit tests (#12875)
Due to a state retention issue in the unit test platform, TCAT tests were passing in ways they should not.
Now with the new settings/flash clearing per #12875 applied, these tests were failing.

This fixes TCAT unit tests to pass again and better express the expected behavior also.
2026-04-14 08:44:27 -07:00
Esko Dijk 68ab3a55a1 [tests] prevent settings/flash retaining between unit tests (#12875)
Issue: state was retained between OT instances in the unit test platform, across tests.
This commit adds settings and flash clearing as part of testInitInstance().
2026-04-14 08:44:27 -07:00
Jonathan Hui e336e7a86c [github-actions] simplify simulation-1.4 workflow (#12886)
This commit simplifies the Simulation 1.4 workflow by removing the
compiler and architecture matrix. Run-time issues due to compiler
differences or architecture have not been an issue, so testing a single
configuration is sufficient to reduce CI resource usage.

The workflow now uses the default environment instead of explicitly
testing both gcc/clang and m32/m64 architectures.
2026-04-13 23:39:16 -05:00
dependabot[bot] 20a83e1116 github-actions: bump docker/build-push-action from 7.0.0 to 7.1.0 (#12882)
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 7.0.0 to 7.1.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/d08e5c354a6adb9ed34480a06d141179aa583294...bcafcacb16a39f128d818304e6c9c0c18556b85f)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: 7.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-13 23:38:46 -05:00
Abtin Keshavarzian 40976e772d [time-sync] add compile-time check for TREL incompatibility (#12880)
This commit adds a compile-time check in `time_sync_service.hpp` to
ensure that `OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE` is not
enabled alongside `OPENTHREAD_CONFIG_TIME_SYNC_ENABLE`. The time
synchronization feature is experimental and currently only supports
IEEE 802.15.4 radio links. Attempting to use it over TREL is
unsupported and will now result in a build failure.
2026-04-13 22:49:34 -05:00
Abtin Keshavarzian 06ed4dce4e [crypto] add ContextWith template to simplify context allocation (#12885)
This commit introduces the `Context` and `ContextWith<kContextSize>`
helper classes in the `Crypto` namespace to wrap `otCryptoContext`
and manage its storage allocation. `ContextWith<kContextSize>`
handles the buffer allocation based on the configuration
`OPENTHREAD_CONFIG_CRYPTO_PLATFORM_ALLOCS_CONTEXT`, automatically
clearing and setting the buffer.

The `AesEcb`, `HkdfSha256`, `HmacSha256`, and `Sha256` classes are
updated to use the new `ContextWith` template for their `mContext`
members. This simplifies their initialization sequences and
constructors.
2026-04-13 22:48:35 -05:00
Abtin Keshavarzian 028f137367 [cli] add support to configure prompt output (#12884)
This commit introduces the ability to configure whether the CLI
interpreter outputs the prompt string (`> `) at runtime.

- Adds `mPromptEnabled` boolean flag (enabled by default) under the
  `OPENTHREAD_CONFIG_CLI_PROMPT_ENABLE` configuration.
- Adds the `Interpreter::SetPromptConfig()` method to toggle this
  behavior.
- Updates `Interpreter::OutputPrompt()` to check `mPromptEnabled`
  before emitting the prompt string.
2026-04-13 22:47:17 -05:00
Jonathan Hui 23e9cc98b8 [tests] remove redundant 1.2 certification tests and CI job (#12883)
This commit removes the following legacy 1.2 certification test scripts:
- tests/scripts/thread-cert/v1_2_router_5_1_1.py
- tests/scripts/thread-cert/v1_2_test_parent_selection.py

It also removes the 'packet-verification-1-1-on-1-4' job from the
Simulation 1.4 workflow as it is no longer required.
2026-04-13 17:16:36 -05:00
Esko Dijk ea56e75ffe [tcat] fix CommCert4 to be signed by the correct CA (#12874)
Now signed by the correct 'Thread Certification DeviceCA'. A 'test'
target is added in the Makefile to test chaining.  The Thread
certification CA certificate is also added in the 'CA' directory,
which was missing.  Documentation is updated to clarify that the
'TcatCertCa' private key is not included in this repo; and other
clarifications.
2026-04-12 21:51:10 -05:00
Abtin Keshavarzian b5d0ea36be [test] add testResetInstance() to simulate device reset (#12878)
This commit introduces `testResetInstance()` in the unit test platform
layer to finalize an existing `ot::Instance` and re-initialize it
using the same underlying memory buffer, simulating a device reset.

This commit also updates `test_routing_manager.cpp` to use this new
function to streamline the test implementation.
2026-04-12 21:49:28 -05:00
Abtin Keshavarzian dea5c4559d [meshcop] add FindIn() and AppendTo() for SteeringDataTlv (#12871)
This commit introduces static helper methods `SteeringDataTlv::FindIn()`
and `SteeringDataTlv::AppendTo()` to simplify the handling of steering
data in `Message` objects.

`SteeringDataTlv::FindIn()` encapsulates the pattern of searching for a
`SteeringDataTlv` in a `Message` and reading its value into a
`SteeringData` object. `SteeringDataTlv::AppendTo()` provides a unified
way to append steering data to a `Message`, including a validity check.

These helpers are adopted across core modules (MeshCoP, MLE, Discovery)
and various Nexus tests, replacing manual TLV manipulation with a
cleaner and safer helper methods.
2026-04-12 21:40:47 -05:00
Abtin Keshavarzian 1ddfe45402 [cli] update SNTP and Diagnostic CLI commands (#12870)
This commit fixes the CLI implementation of `sntp` and `diagnostic`
commands by ensuring they use the public `otMessageInfo` type instead
of the internal `ot::Ip6::MessageInfo` class.
2026-04-12 21:39:55 -05:00
Jonathan Hui 32ade1684b [nexus] add test 1_4_PIC_TC_4 for NAT64 connectivity (#12862)
This commit implements the Nexus test specification 1_4_PIC_TC_4
to verify the Border Router (BR) built-in NAT64 translator.

The test verifies that the BR DUT:
- Automatically configures an IPv4 address and NAT64 prefix.
- Offers IPv4 internet connectivity to Thread devices using NAT64.
- Offers IPv4 local network connectivity to Thread devices.
- Operates a DNS recursive resolver to look up IPv4 server addresses.

New files added:
- tests/nexus/test_1_4_PIC_TC_4.cpp: C++ test execution script
- tests/nexus/verify_1_4_PIC_TC_4.py: Python pcap verification script

Integration:
- Updated tests/nexus/CMakeLists.txt to compile the test.
- Added test to default array in tests/nexus/run_nexus_tests.sh.
2026-04-10 21:40:06 -05:00
Abtin Keshavarzian 0d740686f3 [config] default enable "key references" with PSA crypto (#12877)
This commit updates the default value of the
`OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` configuration
to be enabled automatically when `OPENTHREAD_CONFIG_CRYPTO_LIB` is
set to `OPENTHREAD_CONFIG_CRYPTO_LIB_PSA`. Additionally, it adds a
compile-time check in `crypto_platform_psa.cpp` to enforce this
requirement. This ensures that the platform key references support is
always enabled when the PSA crypto library is selected.
2026-04-10 21:39:12 -05:00
Abtin Keshavarzian 581221eedb [instance] introduce ActiveInstanceTracker for context-aware logging (#12869)
This commit introduces `ActiveInstanceTracker` as the first member
variable of the `Instance` class to manage the global `gActiveInstance`
pointer (when `OPENTHREAD_CONFIG_LOG_INSTANCE_AWARE_API_ENABLE` is
enabled).

By placing it as the very first member, we ensure its constructor
is called before any other member and its destructor is called after
all others. The `Instance` destructor body also explicitly sets
`gActiveInstance = this` at its start to "claim" the context during its
own destruction. This guarantees that logs emitted during both the
initialization and destruction of an `Instance` are always correctly
associated with that instance. Finally, the `ActiveInstanceTracker`
destructor sets `gActiveInstance` to `nullptr` at the very end to
prevent any potential use of a dangling pointer.
2026-04-10 21:38:35 -05:00
Abtin Keshavarzian 21181644aa [mle] add parameter-less AppendModeTlv() helper (#12868)
This commit introduces an overloaded version of `AppendModeTlv()`
that automatically uses the device's own `GetDeviceMode()`.
The new parameter-less version simplifies the common case where a
node reports its own mode. The parameterized version is
preserved for cases where a specific mode must be provided (e.g.,
parent reporting one of its children's mode).
2026-04-10 21:37:55 -05:00
Abtin Keshavarzian 9feec93a20 [mle] add AppendSourceAddressAndLeaderDataTlvs() helper (#12867)
This commit introduces `TxMessage::AppendSourceAddressAndLeaderDataTlvs()`
to consolidate the appending of `Source Address` and `Leader Data` TLVs.

This combination is frequently used together across various MLE messages
to provide the sender's identity and leader data. Centralizing this
into a single helper method improves code consistency.

Additionally, the `TxMessage` methods in `mle.hpp` and `mle.cpp` are
organized into "Appending single TLV" and "Appending multiple TLVs"
sections for better clarity and maintainability. Existing multi-TLV
methods like `AppendLinkAndMleFrameCounterTlvs()` and
`AppendActiveAndPendingTimestampTlvs()` are moved to the new section.
2026-04-10 21:37:24 -05:00
Abtin Keshavarzian a98813b30a [nexus] use Ip6::SetReceiveCallback() directly (#12865)
This commit updates the Nexus platform to use the internal core C++
API `Ip6::SetReceiveCallback()` instead of the public C API
`otIp6SetReceiveCallback()`.
2026-04-09 17:55:04 -05:00
Abtin Keshavarzian 7210dd212b [mle] centralize and unify address registration logic (#12864)
This commit introduces `Mle::ShouldRegisterUnicastAddrWithParent()` to
centralize the logic for determining which unicast addresses should be
registered with the parent.

Previously, the filtering logic for unicast addresses was duplicated
in `HasUnregisteredAddress()` and `AppendAddressRegistrationTlv()`. By
unifying this in a single helper method, the code ensures consistent
behavior between checking for unregistered addresses and actually
appending them to the MLE messages.

Additionally, this change:
- Marks `Mle::HasUnregisteredAddress()` as `const`.
- Updates `Mle::ShouldRegisterMulticastAddrsWithParent()` to improve
  readability and follow common coding patterns in the codebase.
2026-04-09 17:54:54 -05:00
Abtin Keshavarzian f2c081b5ae [mle] improve address registration in SendChildUpdateResponse() (#12863)
This commit improves the address registration behavior in
`Mle::SendChildUpdateResponse()` for non-FTD devices.

Previously, the device would always append only the mesh-local address
and then unconditionally attempt to send a follow-up Child Update
Request. The updated logic now checks if the parent's request
included a Challenge TLV. If not, all addresses are appended directly
to the response, eliminating the extra message exchange. If a
Challenge is present (indicating the parent is restoring its link),
only the mesh-local address is included to prevent message
fragmentation. In this case, if the device is attached and has
unregistered addresses, a follow-up Child Update Request is scheduled
via `mDelayedSender`.

The previous implementation indirectly assumed the parent would only
request the `Address Registration` TLV when restoring its link (the
current behavior of OpenThread parents). However, such behavior on the
parent is not strictly required and could change. This update on the
child side ensures robust address registration regardless of the
parent's specific behavior.
2026-04-09 17:54:31 -05:00
Jonathan Hui fc3ffa7a69 [nexus] fix segmentation fault during Core destruction (#12866)
When the Nexus test finishes, it automatically destructs all its allocated
Nodes sequentially. During this destruction phase, the OpenThread instance
attempts to destruct objects like `Nat64::Translator`, which might in turn
call logging mechanisms like `Mapping::Free()` that rely on the static
`Instance::GetActiveInstance()` pointer.

Because `Core::~Core()` did not maintain or update `gActiveInstance` while
iterating through node destructors, this pointer was left dangling, causing
segmentation faults when dereferenced by `ot::Instance::GetLogLevel()`.

This commit fixes `Core::~Core()` to manually loop through and destruct the
`mNodes` list, calling `UpdateActiveInstance(&node->GetInstance())` right
before destroying each node. This ensures that `gActiveInstance` points to
the correct context while node destruction logic runs.
2026-04-09 17:52:29 -05:00
Jonathan Hui dbbadb4021 [nexus] add test for IPv6 default route advertisement (PIC-TC-3) (#12860)
This commit adds a Nexus test case 1_4_PIC_TC_3 to verify the IPv6
default route advertisement behavior of a Border Router (BR) in a
Thread 1.4 network.

The test verifies that:
- The BR correctly advertises a default route (::/0) in Thread Network
  Data when it discovers a default route on the infrastructure link.
- The BR maintains the default route advertisement even if the
  infrastructure default route is withdrawn, provided a non-ULA prefix
  remains active on the infrastructure link.
- The default route advertisement is correctly restored or updated when
  the infrastructure default route is re-enabled.

The test implementation includes:
- test_1_4_PIC_TC_3.cpp: C++ test logic using the Nexus simulation
  framework, simulating BR, Router, End Device, and Infrastructure
  nodes (Eth_1, Eth_2). It uses a custom ICMPv6 receive callback to
  simulate "no route to host" conditions.
- verify_1_4_PIC_TC_3.py: Python verification script that analyzes
  the captured packets to ensure MLE Data Responses and ICMPv6 traffic
  match the expected behavior for each test step.

Integration:
- Updated tests/nexus/CMakeLists.txt and tests/nexus/run_nexus_tests.sh
  to include the new test in the automated test suite.
2026-04-09 17:18:28 -05:00
Jonathan Hui 05ad9803d8 [nexus] add 1.4 PIC-TC-1 test for DHCPv6-PD and DNS (#12859)
This commit adds a new Nexus test that implements the test
specification in test-1-4-PIC-TC-1.md. The test verifies Border
Router functionality including:
- DHCPv6-PD client to obtain OMR prefix
- Advertising route to OMR prefix on AIL (Stub Router)
- DNS recursive resolver for public internet addresses
- Connectivity (ICMPv6, UDP, TCP/HTTP) to internet and local servers

New files:
- tests/nexus/test_1_4_PIC_TC_1.cpp: C++ test execution
- tests/nexus/verify_1_4_PIC_TC_1.py: Python pcap verification

Nexus platform enhancements:
- Enabled DHCPv6-PD client in openthread-core-nexus-config.h
- Implemented DHCPv6-PD platform APIs in nexus_infra_if.cpp
- Added RDNSS option to RA in nexus_infra_if.cpp
- Improved packet delivery on infrastructure interface in nexus_core.cpp
- Fixed upstream DNS query matching in nexus_dns.cpp
2026-04-09 15:29:35 -05:00
Zhangwx b3ab4df0e8 [mbedtls] fix version check to correctly handle mbedtls v3.x and v4.0 (#12861)
Previously, version checks used `<= 0x03060500` to guard mbedtls v3.x
APIs, incorrectly treating any version above 3.6.5 (e.g. 3.6.6+) as
v4.0. Replace these checks with `< 0x04000000` to properly cover all
v3.x releases.
2026-04-09 15:18:26 -05:00
Abtin Keshavarzian 51353c41d5 [border-agent] add support for vo key in TXT data parser (#12858)
This commit adds support for the Vendor OUI (`vo`) key in the Border
Agent MeshCoP service TXT data parser.

The `otBorderAgentTxtDataInfo` structure and its internal counterpart
`TxtData::Info` are updated to include a boolean flag `mHasVendorOui`
and a 3-byte array `mVendorOui` to store the 24-bit vendor OUI.

The parsing logic in `TxtData::Info::ProcessTxtEntry()` is updated to
recognize the `vo` key and extract its value. Additionally, the CLI
`Interpreter` is updated to output the vendor OUI in hexadecimal
format when it is present in the parsed information.
2026-04-09 01:40:23 -05:00
Abtin Keshavarzian 0e8bb15545 [nexus] use InstanceLocator in InfraIf (#12856)
This commit updates the Nexus platform `InfraIf` class to inherit from
`InstanceLocator`, aligning it with the standard OpenThread architectural
patterns.

The `mNode` and `mNodeId` member variables are removed as they are now
redundant. Access to the associated `Instance` and other platform-level
components is now managed through `GetInstance()` and the newly added
`Instance::Get<T>` template specializations for `Node`, `InfraIf`,
`Udp`, `Trel`, and `Mdns`.

The `InfraIf::Init()` method is renamed to `AfterInit()` to better
reflect its role in the node initialization lifecycle. All call sites in
`nexus_infra_if.cpp` are updated to use the locator-based accessors.
2026-04-09 01:39:54 -05:00
Jonathan Hui 635d2ffaca [nexus] implement test 1_4_DNS_TC_5 for DNS record types (#12836)
This commit implements the Nexus test specification 1_4_DNS_TC_5 for
DNS record types and special cases in OpenThread 1.4.

The test verifies that the Border Router:
- Can resolve A and AAAA records from upstream DNS servers.
- Does not perform IPv6 AAAA synthesis from A records when not
  specifically requested or configured.
- Can resolve mDNS records on the Adjacent Infrastructure Link (AIL).
- Supports non-typical record types (RRTypes) and "Private Use"
  ranges (0xFF00-0xFFFE).
- Correctly blocks and responds with NXDomain for "ipv4only.arpa"
  queries, ensuring they are not forwarded upstream.

Test Implementation:
- Created test_1_4_DNS_TC_5.cpp to simulate the network topology and
  DNS query/response sequences.
- Created verify_1_4_DNS_TC_5.py to perform packet-level verification
  of the DNS interactions and BR behavior.
- Integrated the new test into the Nexus build and test execution
  scripts.
2026-04-08 20:01:15 -05:00
Jonathan Hui 3b84b4c5cb [nexus] implement test 1_4_DNS_TC_3 for upstream DNS resolver selection (#12835)
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.
2026-04-08 17:01:03 -05:00
Abtin Keshavarzian 2b3b56def7 [mle] separate role transition and leader age checks (#12853)
This commit updates `Mle::HandleTimeTick()` to separate the processing
of role transitions and the checking of the leader's age into two
distinct `switch` statements.

Previously, these two checks were combined in a single `switch`
statement with complex fall-through logic. This structure contained
two issues:

1. For a device in the `kRoleChild` state, if the role transition
   timeout expired, the code would execute `ExitNow()`. This
   unintentionally skipped the leader age check and the rest of the
   operations in `Mle::HandleTimeTick()`, such as updating the
   `ChildTable` and `RouterTable`.
2. A non-router-eligible child would incorrectly fall through and
   perform the leader age check. The new logic adds an explicit check
   using `IsRouterEligible()` to ensure only router-eligible children
   monitor the leader's age.

By separating the logic into two blocks, the code is simplified and
we avoid the brittle fall-through behavior and ensure that all time
tick operations are consistently executed regardless of the device's
role or role transition state.
2026-04-08 16:13:09 -05:00
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
Yang Song d42343caa8 [cli] refine debug command list for better diagnostic output (#12799)
Removed redundant channel, panid, and extpanid commands. Their
information is now more comprehensively provided by the dataset active
-ns output.

Removed partitionid from the debug command list as it was redundant
with leaderdata.
2026-04-08 01:24:32 -05:00
Jonathan Hui 87d39dbf5e [nexus] increase kAttachToRouterTime in 1_4_TREL_TC_4 (#12852)
Nexus test 1_4_TREL_TC_4 occasionally fails during topology formation
because the router promotion timeout (kAttachToRouterTime) was set to
120 seconds.

The MLE router selection jitter (OPENTHREAD_CONFIG_MLE_ROUTER_SELECTION
_JITTER) defaults to 120 seconds. Since the jitter timer starts after
successful attachment as a child, 120 seconds is insufficient when the
maximum jitter is selected, leading to a race condition.

This commit increases kAttachToRouterTime to 200 seconds, matching the
value used in most other Nexus tests and providing sufficient time for
router promotion to complete reliably.
2026-04-07 16:20:18 -05:00
Abtin Keshavarzian d2aba43057 [nexus] remove mSrpHostAddresses from Node class (#12850)
This commit removes the `mSrpHostAddresses` array from the `Node`
class in the Nexus platform. The array was specific to SRP client
testing and was occupying unnecessary memory for every simulated
node instance.

Instead of keeping this state inside the `Node` abstraction, a local
`hostAddrs` array is now declared within the `Test_1_3_SRP_TC_1()` test
function. This local array safely persists for the duration of the
test, allowing `Srp::Client::SetHostAddresses()` to use the
provided pointer without relying on a global or node-level member.
2026-04-07 14:21:32 -05:00
silabs-HarshaK bb31558fac [crypto] avoid direct access to crypto context structs members (#12700)
This commit improves robustness and forward compatibility of Secure
Transport with newer MbedTLS/PSA configurations. There are places
where mbedtls structures are accessed directly , which can be fragile
when internal struct layouts change across Mbed TLS configurations or
versions.

To address this, this commit makes the following changes:

1. Replace direct TLS struct member access in secure transport with
mbedtls_ssl_get_peer_cert(), and tighten state/null checks to improve
robustness and forward compatibility with newer MbedTLS/PSA
configurations.
2026-04-07 14:07:02 -05:00
Abtin Keshavarzian a44970bdb4 [nexus] simplify node lookup using LinkedList matching methods (#12849)
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.
2026-04-07 13:23:25 -05:00
Abtin Keshavarzian a24e841ad2 [nexus] optimize HandleIp6Receive and SendIp6 to use OwnedPtr (#12846)
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.
2026-04-07 13:22:55 -05:00
Abtin Keshavarzian 641e84aed4 [meshcop] consolidate Open() and Bind() in SecureTransport (#12826)
This commit simplifies the `SecureTransport` API by consolidating the
previous `Open()` and `Bind()` methods into two specialized `Open()`
flavors.

The first flavor, `Open(uint16_t aPort, ...)`, creates and binds a UDP
socket to a specific port and network interface. If the port is zero,
an ephemeral port is automatically selected.

The second flavor, `Open(TransportCallback aCallback, ...)`, enables
callback-based transmission, where outgoing messages are sent via the
provided callback and received messages are passed in through
`HandleReceive()`.

This consolidation ensures that the transport is fully initialized and
ready for traffic in a single method call. It also prevents the
creation of unused UDP sockets when a `TransportCallback` is
employed, avoiding unnecessary overhead in the `Udp` class.

All core components (`BorderAgent`, `Commissioner`, `Joiner`, and
`BleSecure`) and related tests are updated to utilize the new
patterns.
2026-04-07 01:30:39 -05:00
dependabot[bot] 9c6ddb75c9 github-actions: bump actions/setup-go from 6.2.0 to 6.4.0 (#12837)
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 6.2.0 to 6.4.0.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5...4a3601121dd01d1626a1e23e37211e3254c1c06c)

---
updated-dependencies:
- dependency-name: actions/setup-go
  dependency-version: 6.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-07 01:30:15 -05:00
Abtin Keshavarzian 1e79496c57 [border-agent] handle mDNS service name conflict by renaming (#12790)
This commit adds support for handling mDNS service name conflicts by
automatically renaming the service when a collision is detected during
registration.

The new naming scheme appends a suffix based on the last two bytes of
the device's Extended Address (e.g., " #AB1E"). If this name also
conflicts, an additional index is appended (e.g., " #AB1E (1)").

Changes:
- Added `mServiceRenameIndex` to `Manager` and `EphemeralKeyManager`
  to track re-naming attempts.
- Updated `otBorderAgentSetMeshCoPServiceBaseName()` and CLI documentation
  to reflect the new naming and conflict resolution logic.
- Updated `OT_BORDER_AGENT_MESHCOP_SERVICE_BASE_NAME_MAX_LENGTH` to
  ensure the full name fits within the 63-character DNS label limit.
- Added Nexus tests to verify the renaming logic under conflict.
2026-04-06 23:47:39 -05:00
Abtin Keshavarzian 68ddd042ab [mle] enhance logs for scheduled delayed message transmissions (#12848)
This commit updates the logging in `Mle::DelayedSender` to provide
clearer information about delayed message transmissions.

The `MessageAction` enum values `kMessageDelay` and
`kMessageRemoveDelayed` are renamed to `kMessageScheduleDelayedSend`
and `kMessageRemoveDelayedSend` to better reflect their purpose. The
corresponding string mappings are also updated to "Schedule tx of"
and "Remove scheduled tx of".

Additionally, a new log entry is added to `AddSchedule()` to explicitly
record the delay duration in milliseconds, making it easier to track
when the scheduled message is expected to be sent.
2026-04-06 23:47:03 -05:00
Abtin Keshavarzian 754eefabb6 [nexus] fix IPv6 receive callback setup in node reset (#12845)
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.
2026-04-06 23:46:21 -05:00
Abtin Keshavarzian 5735726616 [nexus-test] reuse foundService bool in tests (#12844)
This commit replaces local `found` boolean variable with the shared
`foundService` variable.
2026-04-06 23:45:59 -05:00
Abtin Keshavarzian 8985f29e8e [udp] change Ip6::Udp::GetUdpSockets() to return LinkedList (#12843)
This change updates `Ip6::Udp::GetUdpSockets()` to return a reference
to the `LinkedList<SocketHandle>` instead of a pointer to the head of
the list. This allows for cleaner iteration using range-based for
loops and provides a more idiomatic C++ interface.

Call sites are updated accordingly. Specifically, the Nexus UDP
platform  code now uses a range-based for loop to iterate through the
sockets.
2026-04-06 23:45:32 -05:00
Jonathan Hui ac01d4b132 [tests] initialize DNS browser and resolver in nexus tests (#12847)
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.
2026-04-06 23:44:20 -05:00
Abtin Keshavarzian f8af79817b [uptime] enhance UptimeToString() and add flags (#12841)
This commit enhances the `UptimeToString()` function by introducing
`UptimeStringFlags` to allow customization of the output string.
Specifically, it adds the following flags:

- `kUptimeStringIncludeMsec`: Includes milliseconds in the string.
- `kUptimeStringSkipHoursIfZero`: Omits the `<hh>:` part when hours
  and days are zero.

The commit also adds a new `UptimeToString()` overload that returns
an `UptimeString` (a `String` object), simplifying usage in logging
and other areas. All existing call sites are updated to use the new
flags and the new overload where appropriate.
2026-04-06 19:13:32 -05:00
Jonathan Hui 7aa9d92600 [mac] fix nullptr-with-nonzero-offset in ProcessEnhAckProbing (#12842)
This commit fixes a nullptr-with-nonzero-offset runtime error in
Mac::ProcessEnhAckProbing. The error occurred because pointer
arithmetic was performed on the enhAckProbingIe pointer before
verifying if it was null.

The fix moves the pointer calculation after the null check to
ensure that it is only performed when a valid IE is present.

This was discovered by ASAN/UBSAN when processing frames without
the Enhancement ACK Probing IE.
2026-04-06 19:10:00 -05:00
Jonathan Hui f0cc2809cc [nexus] implement 1.4 Thread Administration Sharing test (1_4_CS_TC_3) (#12832)
This commit implements the Thread 1.4 Credential Sharing (CS) TC-3
Nexus test, focusing on Thread Administration Sharing using ePSKc.
The test case covers mDNS discovery, ePSKc generation/validation,
and DTLS secure transport for TMF message exchange.

Detailed changes:
- Implement full 26-step Nexus test in tests/nexus/test_1_4_CS_TC_3.cpp
  covering the following procedures:
  - mDNS discovery of meshcop and meshcop-e service instances.
  - Validation of State Bitmap (sb) and other TXT record fields.
  - Generation and Verhoeff-based validation of One-Time Passcodes.
  - DTLS handshakes using correct and incorrect ePSKc values.
  - MGMT_ACTIVE_GET and MGMT_PENDING_GET request/response exchanges
    over the secure DTLS session.
  - Testing of ephemeral key expiration and max connection attempts.
- Add Python-based packet verification script in
  tests/nexus/verify_1_4_CS_TC_3.py using pktverify to ensure
  protocol compliance.
- Register the 1_4_CS_TC_3 test in tests/nexus/CMakeLists.txt.
- Add 1_4_CS_TC_3 to the default test list in run_nexus_tests.sh.
2026-04-06 17:39:31 -05:00
Jonathan Hui 5439f80c7b [nexus] implement platform UDP support (#12822)
This commit implements the otPlatUdp API for the Nexus simulation
environment and updates core UDP logic to facilitate it.

Changes in src/core:
- Initialize mHandle in Udp::Open with the current Instance pointer
  when Nexus platform UDP is enabled. This allows the platform UDP
  implementation to retrieve the instance context directly from the
  otUdpSocket handle.

Changes in Nexus platform:
- Implement otPlatUdp API in nexus_udp.cpp/hpp. The implementation
  routes UDP traffic through the simulated infrastructure interface
  (InfraIf).
- Integrate Udp class into Nexus::Node and Nexus::Platform.
- Update InfraIf::Receive to dispatch incoming UDP packets to the
  new platform UDP implementation.
- Enable OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE and related configs
  in Nexus.

Changes in Nexus tests:
- Update test_border_admitter, test_border_agent, test_dtls, and
  test_1_4_DNS_TC_1 to align with the new platform UDP and address/
  netif usage.
- Add nexus_udp.cpp to CMakeLists.txt.
2026-04-06 15:11:58 -05:00
Abtin Keshavarzian bf6da19fbe [border-admitter] include admitter state in all enroller responses (#12830)
This commit updates `Manager::CoapDtlsSession::SendEnrollerResponse()`
to always include the Admitter info TLVs in responses sent to
enrollers. Previously, these TLVs were only included in responses to
registration and keep-alive requests.

This change ensures that enrollers receive consistent state updates
from the `Admitter` during all interactions, such as joiner
acceptance or release.

The test case `TestBorderAdmitterJoinerEnrollerInteraction` is
updated to validate the new behavior.
2026-04-04 01:18:52 -05:00
Abtin Keshavarzian 5889e428ce [border-admitter] enhance forwarding of joiner relay to enrollers (#12829)
This commit enhances the `Admitter` logic for forwarding `RelayRx`
messages to connected enrollers.

If an enroller has explicitly accepted a specific joiner IID, the
`Admitter` will now always forward that joiner's relay traffic to the
owning enroller, regardless of its current `kForwardJoinerRelayRx`
flag in its registered enroller mode. The flag now strictly controls
whether the enroller receives general "multicast" forwarding for
joiners that have not yet been accepted by any enroller.

This enhancement adds a new capability to the interactions between the
`Admitter` and enrollers. Previously, if an enroller accepted a joiner
but also cleared its `kForwardJoinerRelayRx` flag, it could be
considered a misbehavior by the enroller, as it would effectively
block that joiner's traffic from reaching any other enrollers without
receiving the traffic itself. This scenario is no longer possible, and
this configuration now supports a new behavior: allowing an enroller
to accept certain joiners and receive relay traffic only from those it
has explicitly accepted.

The `test_border_admitter` is updated to validate this behavior in
detail.
2026-04-04 01:18:34 -05:00
Abtin Keshavarzian 9f28df1e30 [network-diag] introduce RouterNeighborTlv (#12827)
This commit updates `RouterNeighborTlv` to follow the `SimpleTlvInfo`
pattern, separating the TLV value structure from its type/length
header.

Specifically, it defines `RouterNeighborTlvValue` to hold the data
fields for a router neighbor's diagnostic information, while
`RouterNeighborTlv` is redefined as a `SimpleTlvInfo` using the value
structure and the `kRouterNeighbor` type.

This allows the use of generic `Tlv::Append<RouterNeighborTlv>()` and
`tlvInfo.Read<RouterNeighborTlv>()` methods,  which are generally
safer and allow value type reuse.

The `NetworkDiagnostic`  and `MeshDiag` module are updated to
utilize these new methods.
2026-04-04 01:17:03 -05:00
Abtin Keshavarzian aec6b5d795 [border-router] introduce LinkLayerAddress in InfraIf (#12819)
This commit introduces the `LinkLayerAddress` class as a nested type
within `InfraIf`. The new class inherits from the
`otPlatInfraIfLinkLayerAddress`  and provides utility methods to
simplify address manipulation and logging.

Specifically, the following capabilities are added:
- `ConvertToIid()` converts the link-layer address into an IPv6
  `InterfaceIdentifier`.
- `ToString()` formats the address into a human-readable string.
- Getters like `GetLength()` and `GetBytes()` for accessing the
  underlying address data.

The `nexus` platform tests are updated to leverage the newly added
`LinkLayerAddress` methods, simplifying the handling of MAC addresses
and the derivation of IPv6 interface identifiers.
2026-04-04 01:16:37 -05:00
Abtin Keshavarzian 3c406866fa [infra-if] fix documentation group order (#12823)
This commit moves the `@addtogroup plat-infra-if` Doxygen block to the
top of the `infra_if.h` header file. Previously, it was defined
after `otPlatInfraIfLinkLayerAddress`, causing that structure and
the `OT_PLAT_INFRA_IF_MAX_LINK_LAYER_ADDR_LENGTH` macro to be excluded
from the `plat-infra-if` module in the generated documentation.
2026-04-03 11:21:46 -05:00
Abtin Keshavarzian 7533e43ee7 [network-diag] introduce ChildTlvValue (#12820)
This commit updates `ChildTlv` to follow the `SimpleTlvInfo` pattern,
separating the TLV value structure from its type/length header.

Specifically, it defines `ChildTlvValue` to hold the data fields for
a child's diagnostic information, while `ChildTlv` is redefined as
a `SimpleTlvInfo` using the value structure and the `kChild` type.

This allows the use of generic `Tlv::Append<ChildTlv>()` and
`tlvInfo.Read<ChildTlv>()` methods, which are generally safer and
allow value type reuse.

The `NetworkDiagnostics` and `MeshDiag` are updated to utilize
these new definitions.
2026-04-03 11:20:57 -05:00
Oblivionsage c7b922cd99 [heap-data] use allocate-first pattern in UpdateBuffer() (#12794)
Heap::Data::UpdateBuffer() freed the existing buffer before
attempting to allocate a new one. If the allocation failed,
mData retained a dangling pointer to the already-freed buffer.
A subsequent Free() call (from the destructor or an error path)
would then free the same pointer again, causing a double-free.

This changes UpdateBuffer() to use the allocate-first pattern
(consistent with Heap::String::Set): the new buffer is allocated
first, and the old buffer is freed only after a successful
allocation. On allocation failure, the old buffer is preserved
and no dangling pointer is created.

Signed-off-by: Oblivionsage <cookieandcream560@gmail.com>
2026-04-03 11:17:54 -05:00
Li Cao dab83c966b [spinel] update log level for co-processor starting (#12786)
This commit changes the log level from CRIT to INFO for co-processor
restarting. This is a normal behavior so it shouldn't be CRIT.
2026-04-02 09:44:14 -05:00
Abtin Keshavarzian 42635a12b2 [test] enhance test-008-multicast-traffic.py (#12816)
This commit updates `test-008-multicast-traffic.py` to use a strict
equality check for the number of multicast `ping` responses when the
ping originates from an SED.

The test now also verifies the `RxSuccess` IP counter on the SED to
ensure it increases by exactly the number of expected replies. This
confirms that the parent correctly avoids forwarding the original
multicast echo request back to the originating SED, even if the SED
is subscribed to the multicast address. This validates the behavior
introduced in PR #12329.
2026-04-02 00:07:15 -05:00
Jonathan Hui 057937c31f [nexus] add 1_3_GEN_TC_2 for mDNS TXT record validation (#12811)
This commit adds Nexus test case 1_3_GEN_TC_2, which verifies mDNS TXT
record regeneration across factory resets in the Nexus simulation
environment.

The test ensures that key fields such as 'id' (Border Agent ID) and
'omr' (OMR prefix) are correctly updated in mDNS advertisements after
a settings wipe and network reset.

Key features of this implementation include:
- tests/nexus/test_1_3_GEN_TC_2.cpp: Sets up a Border Router, forms a
  network, and validates initial mDNS state. It then performs an
  otPlatSettingsWipe followed by a reset to trigger new configuration.
- tests/nexus/verify_1_3_GEN_TC_2.py: Implements robust packet
  verification using hex-based marker matching for OMR prefixes to
  accurately identify iteration-specific TXT records despite any
  interleaved or stale mDNS packets in the capture.
- Integrated the new test into tests/nexus/CMakeLists.txt and
  tests/nexus/run_nexus_tests.sh for automated build and execution.

This test validates that the Thread stack correctly manages persistent
state and re-generates unique identifiers upon a factory reset.
2026-04-01 23:38:04 -05:00
Jonathan Hui 26a882dabc [nat64] handle IPv4 options and discard source route options (#12818)
OpenThread's NAT64 translator assumed a fixed IPv4 header length of 20
bytes, which caused incorrect parsing and translation of IPv4 packets
containing options (IHL > 5).

Specifically, if an IPv4 packet with options was received:
1. The transport header was read from a fixed 20-byte offset, leading
   to corruption of transport layer fields (e.g., UDP ports).
2. Only 20 bytes were removed from the message, leaving the IPv4
   options at the beginning of the translated IPv6 payload.
3. Mandatory security checks for source route options were bypassed.

This commit fixes these issues by:
- Updating Ip4::Header to validate IHL and provide the actual header
  length.
- Using the actual header length for transport header parsing and
  IPv4 header removal in the NAT64 translator.
- Implementing a check to discard packets with LSRR or SSRR options
  as required by RFC 7915.

A new Nexus regression test is added to verify the fix.
2026-04-01 20:24:42 -05:00
Jonathan Hui 42b653a18c [nexus] add 1_4_DNS_TC_1 for multi-question DNS queries (#12817)
This commit adds Nexus test case 1_4_DNS_TC_1, which verifies that the
Thread Border Router DUT can successfully handle DNS queries with
multiple questions (QDCOUNT > 1), per the Thread 1.4 specification.

The implementation includes:
- tests/nexus/test_1_4_dns_tc_1.cpp: C++ test logic that sets up a
  topology with Eth_1, BR_1 (DUT), Router_1, and ED_1. It registers
  services via mDNS on Eth_1 and SRP on Router_1, and then performs
  various DNS queries from ED_1, including multi-question queries.
- tests/nexus/verify_1_4_dns_tc_1.py: Python script that verifies
  the DNS packet exchange in the pcap, ensuring that multi-question
  queries are correctly received by the DUT and that valid responses
  are returned.
- Integration into tests/nexus/CMakeLists.txt and
  tests/nexus/run_nexus_tests.sh for automated building and execution.
2026-04-01 20:24:12 -05:00
Jonathan Hui 7bfb4226f0 [nexus] add 1_4_TREL_TC_6 for mDNS discovery of TREL service (#12809)
This commit adds Nexus test case 1_4_TREL_TC_6, which verifies mDNS
discovery of the TREL service on a Border Router (DUT), per the Thread
1.4 specification.

The implementation includes:
- tests/nexus/test_1_4_TREL_TC_6.cpp: C++ test logic that sets up a
  Border Router and a reference Ethernet device. It performs mDNS
  browsing to capture the TREL service instance name and then
  resolves that service.
- tests/nexus/verify_1_4_TREL_TC_6.py: Python script that verifies
  the mDNS packet exchange in the pcap, including PTR, SRV, TXT, and
  AAAA records, ensuring all DNS-SD parameters and fields are
  correctly advertised.
- Integration into tests/nexus/CMakeLists.txt and
  tests/nexus/run_nexus_tests.sh for automated building and execution.
2026-04-01 12:11:01 -05:00
Jonathan Hui 57539b0725 [nexus] add 1_4_TREL_TC_5 for multi-radio discovery scan (#12808)
This commit adds Nexus test case 1_4_TREL_TC_5, which verifies
MLE discovery scan behavior when nodes support different radio
links, per the Thread 1.4 specification.

The implementation includes:
- tests/nexus/test_1_4_TREL_TC_5.cpp: Sets up a topology with
  three nodes: Node_1 (DUT) and Node_2 support both 15.4 and
  TREL, while Node_3 supports 15.4 only. Each node forms its
  own network. The test performs Discovery Scans from Node_2
  and Node_3 and verifies that all expected peers are seen.
- tests/nexus/verify_1_4_TREL_TC_5.py: Verifies the exchange
  of MLE Discovery Request and Response packets in the pcap
  output, ensuring that nodes with different radio capabilities
  can discover each other correctly.
- Updated tests/nexus/CMakeLists.txt and
  tests/nexus/run_nexus_tests.sh to include the new test in the
  build and default test list.
2026-04-01 10:17:01 -05:00
Abtin Keshavarzian ad0d0fcb5e [nexus] use indexed SetName() in test cases (#12814)
This commit simplifies node naming in various Nexus test cases by
using the indexed `SetName(prefix, index)` flavor.

This replaces manual string formatting using `snprintf` or
`ot::String` buffers with the built-in indexed naming support.
2026-04-01 09:38:03 -05:00
Abtin Keshavarzian d9fc6c15dc [nexus] add AddTestVar flavor for uint values (#12813)
This commit adds a new `AddTestVar` overload that accepts a
`uint32_t` value, simplifying the addition of numeric test
variables in Nexus tests.

Previously, adding a numeric test variable required manual string
formatting using a local `String` object. The new flavor handles
the uint to string conversion internally.

The change also introduces a `NewTestVar` private helper method in
the `Core` class to consolidate the logic for creating and
initializing a new `TestVar` entry.

Various Nexus test cases are updated to use the new `AddTestVar`
flavor, removing redundant string formatting code.
2026-04-01 09:37:42 -05:00
Abtin Keshavarzian e3fa1ac524 [nexus] use Dataset::Info method to simplify test_1_2_BBR_TC_3 (#12812)
This commit updates `test_1_2_BBR_TC_3.cpp` to use the `Get<>()` method
when accessing the network name and extended PAN ID from the
`MeshCoP::Dataset::Info` instance.
2026-04-01 09:36:53 -05:00
Jonathan Hui 0f4fbabc13 [nexus] add 1_4_TREL_TC_4 for radio link (re)discovery (#12807)
This commit implements Thread 1.4 Test Case 8.4 (TREL-8.4), "Radio Link
(Re)discovery through Receive", using the Nexus simulation framework.

The test validates the multi-radio behavior of a Border Router (DUT)
and a Router neighbor, specifically focusing on TREL link state
transitions and rediscovery mechanisms.

Key test scenarios include:
- Initial topology formation with a multi-radio BR (DUT), a multi-radio
  Router, and a 15.4-only End Device (ED).
- Preference detection for TREL vs. 802.15.4 radio links.
- Detection of TREL link failure and fallback to 802.15.4.
- TREL radio link rediscovery triggered by receiving messages from a
  neighbor over the TREL interface.
- Continued reachability via TREL when the 802.15.4 radio link is
  explicitly disabled.

The implementation consists of:
- tests/nexus/test_1_4_TREL_TC_4.cpp: C++ test logic for node
  configuration, state transitions, and message exchange.
- tests/nexus/verify_1_4_TREL_TC_4.py: Python script for automated
  packet-level verification of radio link selection.
- Integration into the Nexus build system and test runner.
2026-03-31 23:14:46 -05:00
Jonathan Hui 1d1ea0890e [nexus] add 1_3_GEN_TC_1 to verify Thread Version TLV (#12810)
This commit adds Nexus test case 1_3_GEN_TC_1, which verifies that the
Thread Version TLV uses the value '4' or higher, as required by the
Thread 1.3.x and 1.4.x specifications.

The implementation includes:
- tests/nexus/test_1_3_GEN_TC_1.cpp: C++ test logic that sets up a
  topology with a Border Router, a Router, and an End Device. It
  triggers MLE attachment procedures and discovery scans to generate
  MLE packets containing the Version TLV. For 1.4 devices, it also
  sends TMF Get Diagnostic Requests to verify the Version TLV in
  DIAG_GET.rsp.
- tests/nexus/verify_1_3_GEN_TC_1.py: Python script that verifies
  the MLE Version TLV in Parent Request/Response, Child ID Request,
  and Discovery Response packets. It also verifies the Version TLV
  in Network Diagnostic responses for 1.4 devices.
- Integration into tests/nexus/CMakeLists.txt and
  tests/nexus/run_nexus_tests.sh for automated building and execution.
2026-03-31 20:20:10 -05:00
Jonathan Hui 181227afa7 [nexus] add 1_4_TREL_TC_3 for TREL radio link rediscovery (#12806)
This commit adds Nexus test case 1_4_TREL_TC_3, which verifies the
multi-radio probe mechanism and TREL radio link rediscovery after a
temporary disconnect, according to the Thread 1.4 specification.

The implementation includes:
- tests/nexus/test_1_4_TREL_TC_3.cpp: Sets up a topology with a
  multi-radio Border Router (DUT), a multi-radio Router, and a
  15.4-only End Device. It simulates a TREL disconnect by disabling
  the TREL interface on the Router, verifies that the DUT falls back
  to 15.4, and then re-enables TREL to trigger and verify the probe
  mechanism for link rediscovery.
- tests/nexus/verify_1_4_TREL_TC_3.py: Verifies the packet flow from
  the pcap output, ensuring that TREL is used when available, 15.4
  is used during the TREL disconnect, and TREL usage resumes after
  rediscovery.
- Updated tests/nexus/CMakeLists.txt and tests/nexus/run_nexus_tests.sh
  to include the new test in the build and default test list.

The test ensures that the Thread stack correctly manages link
preferences and successfully rediscovers more efficient radio links
using the multi-radio probe mechanism.
2026-03-31 20:15:31 -05:00
Jonathan Hui d0949e1e92 [nexus] add 1_4_TREL_TC_2 for TREL multi-hop routing (#12804)
This commit adds Nexus test case 1_4_TREL_TC_2, which verifies 6LoWPAN
mesh header forwarding and fragmentation over multi-hop paths involving
both 15.4 and TREL radio links, according to the Thread 1.4 spec.

The implementation includes:
- tests/nexus/test_1_4_TREL_TC_2.cpp: Sets up a complex topology with
  a multi-radio Border Router (DUT), a multi-radio Leader, and several
  Routers and End Devices with varying radio capabilities (15.4-only
  or multi-radio). It triggers pings with large payloads (500B) to
  verify fragmentation and multi-hop routing through the DUT.
- tests/nexus/verify_1_4_TREL_TC_2.py: Verifies that packets follow the
  expected multi-hop path, checking that TREL is used for infrastructure
  segments (UDP) and 15.4 is used for Thread-only segments. It also
  ensures that 6LoWPAN fragmentation and mesh headers are correctly
  handled by the DUT when forwarding between different radio types.
- Updated tests/nexus/CMakeLists.txt and tests/nexus/run_nexus_tests.sh
  to include the new test.

This test ensures that the Thread stack correctly handles multi-hop
routing and MTU differences across heterogeneous radio links.
2026-03-31 12:30:43 -05:00
Jonathan Hui 63ec21ea77 [nexus] add 1_4_TREL_TC_1 for Thread over Infrastructure (#12803)
This commit adds the Nexus test case 1_4_TREL_TC_1 which verifies
connectivity between multi-radio (15.4 and TREL) and single-radio
(15.4 only) devices, as per the Thread 1.4 test specification.

The implementation includes:
- tests/nexus/test_1_4_TREL_TC_1.cpp: Implements the test sequence.
  It sets up a topology with a Border Router (DUT) and two Routers.
  BR and Router_1 support both 15.4 and TREL, while Router_2 supports
  only 15.4. The test verifies that nodes can correctly detect
  neighbor radio capabilities and establishes connectivity using
  both radio types.
- tests/nexus/verify_1_4_TREL_TC_1.py: Performs automated packet
  verification. It ensures that traffic between multi-radio nodes
  preferentially uses TREL (simulated over the infrastructure link
  via UDP), while traffic involving the single-radio node uses 15.4.
  It also validates successful ping exchange across the mixed-radio
  topology.
- Integrated the new test into tests/nexus/CMakeLists.txt and
  tests/nexus/run_nexus_tests.sh.

The test validates that the Thread stack correctly manages multiple
radio links and ensures seamless connectivity across different
physical layers.
2026-03-31 09:39:13 -05:00
Jonathan Hui c3813d6253 [nexus] always enable TREL for Nexus tests (#12802)
This commit enables TREL by default for all Nexus tests to avoid
requiring multiple builds.

Key changes:
- Modified tests/nexus/build.sh to enable TREL (OT_TREL=ON) by default.
- Updated tests/nexus/test_border_admitter.cpp and
  tests/nexus/test_border_agent.cpp to handle multiple mDNS services
  in the platform layer, as TREL adds its own mDNS service.
- Refined tests/nexus/verify_1_2_BBR_TC_3.py to specifically filter
  for MeshCoP mDNS services and made OMR prefix verification more
  lenient to handle transitions in multi-radio environments.
- Updated .github/workflows/nexus.yml to use the default build for all
  Nexus jobs and merged TREL tests into the cert tests job.

All 133 cert tests, core tests, and TREL tests passed successfully with
these changes.
2026-03-30 22:46:53 -05:00
Jonathan Hui 7af59a1fef [nexus] route TREL traffic through simulated infrastructure link (#12801)
This commit updates the TREL traffic simulation in the Nexus platform
to flow through the simulated infrastructure link. This ensures that
TREL packets are captured in the pcap file generated by the
infrastructure link, matching the behavior of mDNS traffic.

Key changes:
- Updated Trel::Send to use InfraIf::SendUdp instead of direct
  delivery.
- Modified InfraIf::Receive to recognize TREL UDP packets and pass
  them to the TREL platform layer.
- Removed the manual mPendingTxList from the Trel struct as
  packets are now managed by the infrastructure interface's queue.
- Added initialization for the TREL platform layer in Core::CreateNode.
- Removed Core::ProcessTrel as TREL packets are now processed within
  Core::ProcessInfraIf.

This change improves the realism of the TREL simulation and simplifies
packet capture for TREL-related tests.
2026-03-30 20:56:38 -05:00
Jonathan Hui 59411c85f6 [nexus] add 1_3_DPR_TC_2 for Service Discovery - Multiple BRs (#12798)
This commit adds the Nexus test case 1_3_DPR_TC_2 which verifies
Service discovery of services on Thread and Infrastructure with
multiple Border Routers and multiple Thread networks, as per the
Thread 1.3 test specification.

The implementation includes:
- tests/nexus/test_1_3_DPR_TC_2.cpp: Implements the test sequence.
  It sets up two isolated Thread networks, each with its own Border
  Router (BR_1/DUT and BR_2) and End Device (ED_1 and ED_2),
  attached via a shared infrastructure link. It simulates SRP
  registration on both networks and verifies that services can be
  discovered across networks using the Discovery Proxy function.
- tests/nexus/verify_1_3_DPR_TC_2.py: Performs automated packet
  verification. It ensures both BRs correctly add SRP Server info
  to their respective Network Data, SRP updates are successful,
  and DNS queries (PTR and SRV) from one network successfully
  discover services in the other network through the Discovery
  Proxy and mDNS on the infrastructure link.
- Integrated the new test into tests/nexus/CMakeLists.txt and
  tests/nexus/run_nexus_tests.sh.

The test validates that the Border Router's Discovery Proxy can
successfully discover and report services advertised by another
Border Router's Advertising Proxy function across an adjacent
infrastructure link.
2026-03-30 18:18:13 -05:00
Jonathan Hui 1b78d18c13 [nexus] add 1_3_DPR_TC_1 for Service Discovery of services (#12793)
This commit adds the Nexus test case 1_3_DPR_TC_1 which verifies
Discovery Proxy functionality on a Border Router, as per the
Thread 1.3 test specification.

The implementation includes:
- tests/nexus/test_1_3_DPR_TC_1.cpp: Implements the test sequence.
  It sets up a topology with a Border Router (BR_1), a Thread End
  Device (ED_1), and an infrastructure node (Eth_1). It simulates
  Eth_1 advertising services via mDNS and ED_1 querying for those
  services through the BR's Discovery Proxy.
- tests/nexus/verify_1_3_DPR_TC_1.py: Performs automated packet
  verification. It ensures the BR correctly adds SRP Server info
  to Network Data, Eth_1 advertises services, and ED_1 receives
  a valid DNS response from the BR containing the discovered
  infrastructure services.
- tests/nexus/openthread-core-nexus-config.h: Enables the
  OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE configuration to
  support Discovery Proxy testing in the Nexus environment.
- Integrated the new test into tests/nexus/CMakeLists.txt and
  tests/nexus/run_nexus_tests.sh.

The test validates that the Border Router's Discovery Proxy can
successfully discover and report services from the infrastructure
link to Thread devices.
2026-03-30 16:23:21 -05:00
Jonathan Hui 0883176d31 [nexus] add 1_3_DIAG_TC_2 for Get Diagnostics - End Device (#12791)
This commit adds the Nexus test case 1_3_DIAG_TC_2 which verifies
that an End Device correctly reports its diagnostic information and
MLE counters via Network Diagnostic queries, as per the Thread 1.4
test specification.

The implementation includes:
- tests/nexus/test_1_3_DIAG_TC_2.cpp: Sets up a topology with a Leader,
  a Router, and a TD_1 (DUT) configured as a MED. It triggers Network
  Diagnostic Get queries from the Leader to the DUT for various TLVs
  including Max Child Timeout, EUI-64, Version, Vendor info, and MLE
  Counters.
- tests/nexus/verify_1_3_DIAG_TC_2.py: Performs automated verification
  of the captured traffic. It validates the presence and values of
  requested TLVs (Type 19, 23-28) and ensures that MLE Counters (Type
  34) reflect the expected role changes and tracking time.
- Integrated the new test into tests/nexus/CMakeLists.txt and
  tests/nexus/run_nexus_tests.sh.

The test ensures the correctness of Thread 1.4 End Device Diagnostic
and MLE Counter reporting, facilitating network health monitoring
and troubleshooting in a Thread network.
2026-03-30 14:24:45 -05:00
silabs-HarshaK ba33b6bf13 [crypto] update mbedtls psa crypto context structs (#12699)
This commit hardens OpenThread against Mbed TLS/PSA ABI variation
across customer configurations. Because Mbed TLS/PSA does not
guarantee a stable ABI across build-time option sets,
application-level config changes can alter crypto context struct
size/layout, causing precompiled stack libraries to assume
incompatible memory layouts and potentially fail at runtime.

To address this, this PR makes the following changes:
1. Add OPENTHREAD_CONFIG_PLATFORM_ALLOCS_CRYPTO_CONTEXTS to let
   platforms allocate/manage crypto contexts when required, while
   preserving existing static context storage as the default path.
2. Update AES/HKDF/HMAC/SHA256 context initialization to support both
   platform-managed and internally managed context memory models.
2026-03-30 13:26:07 -05:00
Jonathan Hui c6cf9b27ea [nexus] add 1_3_DIAG_TC_1 for Network Diagnostic and Child Info (#12789)
This commit adds the Nexus test case 1_3_DIAG_TC_1 which verifies
that a Thread Router correctly reports its child and neighbor
information via Network Diagnostic and MeshDiag queries, as per
the Thread 1.4 test specification.

The implementation includes:
- tests/nexus/test_1_3_DIAG_TC_1.cpp: Sets up a star topology with
  a Leader, Router_1 (DUT), and various child nodes (FED, MED, SED,
  REED). It triggers Network Diagnostic Get and MeshDiag queries
  (QueryChildTable, QueryChildrenIp6Addrs, QueryRouterNeighborTable)
  from the Leader to the DUT.
- tests/nexus/verify_1_3_DIAG_TC_1.py: Performs automated verification
  of the captured traffic. It implements a custom TLV parser for
  CoAP payloads to verify Max Child Timeout (19), Vendor/Stack info
  (23-28), MLE Counters (34), Child Table (29), Child IPv6 (30),
  and Router Neighbor (31) TLVs.
- Integrated the new test into tests/nexus/CMakeLists.txt and
  tests/nexus/run_nexus_tests.sh.

The test ensures the correctness of Thread 1.4 Router Diagnostic
and Child Information reporting, facilitating remote monitoring
and management of the Thread network.
2026-03-30 11:48:59 -05:00
dependabot[bot] 97da671da1 github-actions: bump actions/upload-artifact from 6.0.0 to 7.0.0 (#12800)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 6.0.0 to 7.0.0.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/b7c566a772e6b6bfb58ed0dc250532a479d7789f...bbbca2ddaa5d8feaa63e36b76fdaad77386f024f)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-30 11:45:07 -05:00
Abtin Keshavarzian 771c430df0 [netdiag] define AnswerTlvValue to allow reuse (#12792)
This commit defines `AnswerTlvValue` to represent the value of an
Answer TLV, allowing it to be reused across different modules,
specifically `NetworkDiagnostic` and `HistoryTracker`.

The `AnswerTlv` implementation is also updated to use the
template-based `SimpleTlvInfo` pattern. This enables the use of
generic `Tlv::Append<AnswerTlv>()` and `Tlv::Find<AnswerTlv>()`
methods, which improves type safety and reduces manual TLV handling.
2026-03-29 22:16:00 -05:00
Jonathan Hui 9bb7e37ff9 [nexus] add SRPC-TC-7 for SRP client key persistence (#12788)
This commit adds the Nexus test case 1_3_SRPC_TC_7 which verifies
that a Thread device re-registers its service with the same KEY
record after a reboot, as per the Thread 1.3 test specification.

The implementation includes:
- tests/nexus/test_1_3_SRPC_TC_7.cpp: Executes the test sequence
  by forming a Thread network with a Border Router (BR_1), a Router,
  and a DUT (TD_1). It registers a service on the DUT, simulates a
  reboot using Node::Reset(), and re-registers the same service.
- tests/nexus/verify_1_3_SRPC_TC_7.py: Performs automated verification
  of the captured traffic. It ensures that the SRP Update sent after
  reboot contains a KEY record identical to the one sent before
  reboot. It includes a monkey-patch to access the
  dns.key.public_key field in the packet verifier.
- Integrated the new test into tests/nexus/CMakeLists.txt and
  tests/nexus/run_nexus_tests.sh.

The test validates that the SRP client correctly persists its key
material across reboots, which is essential for maintaining service
registration continuity.
2026-03-29 22:14:56 -05:00
Jonathan Hui 1b20885508 [nexus] add SRPC-TC-5 for DNS-SD service discovery (#12787)
This commit adds the Nexus test case 1_3_SRPC_TC_5 which verifies
that a DNS-SD client can correctly discover multiple services
registered via SRP, as per the Thread 1.3 test specification.

The implementation includes:
- tests/nexus/test_1_3_SRPC_TC_5.cpp: Executes the test sequence
  by configuring a Border Router (BR_1), an End Device (ED_2)
  registering 5 services with various TXT records, and a DUT
  (TD_1). It instructs the DUT to browse for services, resolve
  them, and send UDP packets to each resolved service. It verifies
  the TXT record values and successful UDP transmissions.
- tests/nexus/verify_1_3_SRPC_TC_5.py: Performs automated
  verification of the captured traffic (PCAP). It validates the
  DNS query, the DNS response containing all 5 services, and the
  subsequent UDP packets sent to the resolved addresses and ports.
- Integrated the new test into tests/nexus/CMakeLists.txt and
  tests/nexus/run_nexus_tests.sh.

The test ensures the correctness of DNS-SD client discovery logic
and its ability to handle multiple service responses in a Thread
network.
2026-03-28 22:46:09 -05:00
Jonathan Hui dd855c3b3e [nexus] add SRPC-TC-4 for service removal by SRP client (#12780)
This commit adds the Nexus test case 1_3_SRPC_TC_4 which verifies
that an SRP client can correctly remove one service while leaving
other services registered, as per the Thread 1.3 test specification.

The implementation includes:
- tests/nexus/test_1_3_SRPC_TC_4.cpp: Executes the test sequence
  by configuring a Border Router (BR_1) and an End Device (TD_1
  as DUT). It instructs the DUT to register two services and then
  remove the first service. It verifies that the SRP server handles
  the removal correctly and only provides the remaining service in
  subsequent DNS PTR queries.
- tests/nexus/verify_1_3_SRPC_TC_4.py: Performs automated
  verification of the captured traffic (PCAP). It validates the
  SRP Update messages for service registration and removal, and
  checks that the DNS response from BR_1 only contains the
  expected service.
- Integrated the new test into tests/nexus/CMakeLists.txt and
  tests/nexus/run_nexus_tests.sh.

The test ensures the correctness of SRP client service removal
logic and SRP server state management.
2026-03-27 18:56:29 -05:00
Jonathan Hui 51353a9c9e [nexus] add SRPC-TC-1 for SRP client re-registration (#12779)
This commit adds the Nexus test case 1_3_SRPC_TC_1 which verifies
that the SRP client correctly handles re-registration with active
SRP servers, especially when multiple Border Routers are present,
as per the Thread 1.3 test specification.

The implementation includes:
- tests/nexus/test_1_3_SRPC_TC_1.cpp: Executes the test sequence
  by configuring two Border Routers (BR_1 and BR_2), a Router,
  and an End Device (ED_1 as DUT). It simulates BR_1 (the initial
  SRP server) becoming unresponsive and verifies that the DUT
  correctly switches to BR_2. It also verifies that the DUT
  stays with its current server (BR_2) even when a numerically
  lower server (BR_1) is re-enabled.
- tests/nexus/verify_1_3_SRPC_TC_1.py: Performs automated
  verification of the captured traffic (PCAP). It checks for
  correct SRP Update packets to the expected SRP servers and
  validates that the DUT behavior matches the specification
  criteria.
- Integrated the new test into tests/nexus/CMakeLists.txt and
  tests/nexus/run_nexus_tests.sh.

The test ensures robust SRP client behavior in dynamic networks
with multiple SRP servers.
2026-03-27 16:54:22 -05:00
Jonathan Hui c5108df3e3 [bbr] fix primary BBR registration flakiness on leader (#12783)
This commit fixes an intermittent failure in the Nexus test
1_2_BBR_TC_2 by ensuring that the Backbone Router (BBR) service
is registered immediately when a node assumes the Leader role and
no primary BBR is active.

Previously, BbrLeader only tracked network data changes, and
BbrLocal applied a mandatory jitter delay before registration.
This created a race condition where another node could register
its BBR service before the new Leader, causing the Leader to
incorrectly skip its own registration.

Changes:
- Update BbrLeader to monitor role changes (kEventThreadRoleChanged).
- Modify BbrLocal to bypass registration jitter if the node is
  the Leader and there is no existing primary BBR.
2026-03-27 16:42:01 -05:00
Jonathan Hui d630934857 [nexus] add SRP-TC-15 for validation of SRP subtypes (#12777)
This commit adds the Nexus test case 1_3_SRP_TC_15 which verifies
that the SRP server and Border Router correctly handle services
that include additional subtypes, as per the Thread 1.3 test
specification.

The implementation includes:
- tests/nexus/test_1_3_SRP_TC_15.cpp: Executes the test sequence
  by configuring a Border Router (BR_1 as DUT/Leader), an End
  Device (ED_1), and an Infrastructure node (Eth_1). It simulates
  adding, updating, and removing subtypes for a registered service
  and verifies that the BR responds correctly to DNS and mDNS
  queries for both basic types and subtypes.
- tests/nexus/verify_1_3_SRP_TC_15.py: Performs automated
  verification of the captured traffic (PCAP). It checks SRP
  updates, DNS resolutions, and mDNS responses to ensure that
  subtypes are properly registered and advertised.
- Integrated the new test into tests/nexus/CMakeLists.txt and
  tests/nexus/run_nexus_tests.sh.

The test ensures robust support for SRP service subtypes and
their discovery across both Thread and Infrastructure links.
2026-03-27 13:44:45 -05:00
Jonathan Hui 7f26ca3997 [nexus] add SRP-TC-13 for Thread Device address update (#12774)
This commit adds the Nexus test case 1_3_SRP_TC_13 which verifies that
the SRP server and BR correctly handle SRP updates when a Thread
Device's IPv6 addresses change, as per the Thread 1.3 test
specification.

The implementation includes:
- tests/nexus/test_1_3_SRP_TC_13.cpp: Executes the test sequence by
  configuring a Border Router (BR_1 as DUT/Leader), an End Device
  (ED_1), and an Infrastructure node (Eth_1). It simulates address
  updates on ED_1 and verifies that the BR updates its records and
  correctly responds to DNS/mDNS queries.
- tests/nexus/verify_1_3_SRP_TC_13.py: Performs automated verification
  of the captured traffic (PCAP). It checks SRP updates, DNS
  resolutions, and mDNS responses to ensure they only contain the
  updated addresses and not stale ones.
- Integrated the new test into tests/nexus/CMakeLists.txt and
  tests/nexus/run_nexus_tests.sh.

The test ensures that SRP and DNS discovery remain accurate when
device addresses are updated dynamically.
2026-03-27 11:08:50 -05:00
Jonathan Hui 96e8286b37 [nexus] use SetGlobalLogLevel in SRP-TC-11 and SRP-TC-12 (#12782)
This commit updates recently added Nexus tests to use the new
SetGlobalLogLevel() method instead of the deprecated instance-specific
SetLogLevel(). This aligns with the recent changes in the logging
API which introduced per-instance log levels and repurposed the
global log level management.

The following test files were updated:
- tests/nexus/test_1_3_SRP_TC_11.cpp
- tests/nexus/test_1_3_SRP_TC_12.cpp

The change also wraps the call in SuccessOrQuit() to ensure that any
errors during log level configuration are caught, matching the
pattern used in other Nexus tests.
2026-03-27 09:17:26 -05:00
Abtin Keshavarzian e2e36d61e7 [thread] simplify ThreadNetworkDataTlv definition (#12770)
This commit simplifies the definition of `ThreadNetworkDataTlv`.
Previously, `ThreadNetworkDataTlv` included a 255-byte array to store
the Network Data TLVs. The code now relies on standard TLV parsing
methods like `Tlv::FindTlvValueOffsetRange()` and `Message::ReadBytes()`
to access the Network Data directly from the message payload.
2026-03-27 00:48:05 -05:00
Abtin Keshavarzian cb4b28313b [logging] add support for per-instance log levels (#12740)
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.
2026-03-27 00:24:49 -05:00
Jonathan Hui 497e82ad5a [nexus] fix flakiness in 1_2_MATN_TC_9 test (#12781)
This commit fixes an intermittent failure in the Nexus test
1_2_MATN_TC_9 by ensuring that the packet verification for Step 4b
does not advance the packet cursor prematurely.

In Step 4b, the test verifies that BR_2 (DUT) becomes the leader and
distributes its BBR dataset. It checks for both an MLE Advertisement
and an MLE Data Response from BR_2. However, these packets may arrive
in either order.

Previously, the check for the MLE Advertisement used must_next(),
which advanced the packet cursor. If the MLE Data Response arrived
before the Advertisement, the subsequent check for the Data Response
would fail because it started searching from after the Advertisement.

By using copy() for the MLE Advertisement check, we ensure that both
checks search from the same point in the packet log, making the test
robust against packet reordering.
2026-03-26 23:11:07 -05:00
Jonathan Hui 112458b743 [nexus] add SRP-TC-12 for multiple BRs service advertisement (#12773)
This commit adds the Nexus test case 1_3_SRP_TC_12 which verifies
DNS/SRP service advertisement by all BRs in the Thread Network and
correct integration by the Leader, as per the Thread 1.3 test
specification.

The implementation includes:
- tests/nexus/test_1_3_SRP_TC_12.cpp: Executes the test sequence with
  three Border Routers (BR_1 as DUT/Leader, BR_2, and BR_3). It
  simulates adding faked high and low numerical addresses for Unicast
  Datasets and adding an additional Anycast Dataset from BR_2. It
  verifies the integration and withdrawal logic for SRP services.
- tests/nexus/verify_1_3_SRP_TC_12.py: Performs automated verification
  of the captured traffic (PCAP). It checks the Thread Network Data
  contained in MLE Data Responses for the presence of expected
  Anycast and Unicast Datasets and the withdrawal of the DUT's
  service when appropriate.
- Integrated the new test into tests/nexus/CMakeLists.txt and
  tests/nexus/run_nexus_tests.sh.

The test ensures that the DUT correctly manages multiple SRP server
entries in the network data based on their priority and numerical
address values.
2026-03-26 22:47:19 -05:00
Abtin Keshavarzian 697fb25bed [thread-tlvs] add missing packed macros to ThreadRouterMaskTlv (#12769)
This commit updates the `ThreadRouterMaskTlv` class definition to
include the `OT_TOOL_PACKED_BEGIN` and `OT_TOOL_PACKED_END` macros.
This class defines the structure of a TLV used in Thread messages
and directly maps to a memory buffer. Therefore, it must be properly
packed to ensure its memory footprint accurately reflects the wire
format and to prevent potential memory alignment padding.

Thankfully, this omission did not impact the format of this specific
TLV, as the alignment of its members natively matched the packed
layout.
2026-03-26 21:40:28 -05:00
Jonathan Hui 12f4b83195 [nexus] add SRP-TC-11 for recovery after reboot (#12772)
This commit adds the Nexus test case 1_3_SRP_TC_11 which verifies that
SRP registration and mDNS discovery are correctly recovered after
various device reboots, as per the Thread 1.3 test specification.

The implementation includes:
- tests/nexus/test_1_3_SRP_TC_11.cpp: Executes the test sequence by
  simulating reboots of a Thread End Device (ED_1), a Border Router
  (BR_1), and an Infrastructure node (Eth_1). It ensures consistent
  network datasets across reboots and uses direct method calls for
  configuration.
- tests/nexus/verify_1_3_SRP_TC_11.py: Performs automated verification
  of the captured traffic (PCAP). It uses specific MAC address filters
  to reliably identify mDNS queries and responses across multiple
  reboot scenarios where protocol exchanges may otherwise appear
  identical.
- Integrated the new test into tests/nexus/CMakeLists.txt and
  tests/nexus/run_nexus_tests.sh.

The test ensures that SRP clients automatically re-register after
device or server reboots and that the BR correctly continues to
respond to mDNS queries on the infrastructure interface.
2026-03-26 21:10:45 -05:00
Jonathan Hui 35512636b8 [nexus] add SRP-TC-8 for removing some published services (#12771)
This commit adds the Nexus test case 1_3_SRP_TC_8 which verifies that
the SRP server correctly removes only selected service instances while
keeping others registered, as per the Thread 1.3 test specification.

The implementation includes:
- tests/nexus/test_1_3_SRP_TC_8.cpp: Executes the test sequence by
  configuring a Thread Border Router (DUT), an End Device (ED), and
  an Infrastructure node (Eth). It registers multiple services and
  then removes one while verifying the remaining service.
- tests/nexus/verify_1_3_SRP_TC_8.py: Performs automated verification
  of the captured traffic (PCAP), ensuring that SRP Updates, DNS
  queries, and mDNS responses correctly reflect the removal of the
  selected service and the persistence of the other.
- Integrated the new test into tests/nexus/CMakeLists.txt and
  tests/nexus/run_nexus_tests.sh.

The test ensures that the SRP server properly handles service
deregistration according to the SRP draft and that DNS/mDNS discovery
responses are updated correctly.
2026-03-26 19:27:39 -05:00
Jonathan Hui 6dee5af2ae [nexus] add SRP-TC-6 for DNS name compression handling (#12765)
This commit adds the Nexus test case 1_3_SRP_TC_6 which verifies that
the SRP server correctly handles SRP Updates both with and without
DNS name compression, according to the Thread 1.3 test specification.

The implementation includes:
- tests/nexus/test_1_3_SRP_TC_6.cpp: Executes the test sequence by
  configuring a Thread Border Router (DUT), an End Device (ED), and
  an Infrastructure node (Eth). It uses SetDnsNameCompressionEnabled()
  to toggle name compression for SRP Updates.
- tests/nexus/verify_1_3_SRP_TC_6.py: Performs automated verification
  of the captured traffic (PCAP), ensuring that SRP Updates, DNS
  queries, and mDNS responses are correctly formatted and contain the
  expected resource records.
- Updating tests/nexus/CMakeLists.txt and tests/nexus/run_nexus_tests.sh
  to integrate the new test into the build and default test suite.

The test ensures that the SRP server can successfully parse uncompressed
names in SRP Updates and that subsequent DNS/mDNS discovery remains
functional for both compressed and uncompressed registration formats.
2026-03-26 17:49:34 -05:00
Abtin Keshavarzian e791557313 [routing-manager] decouple OmrPrefixManager to accelerate OMR publication (#12753)
This commit refactors the `OmrPrefixManager` to decouple it from the main
`RoutingManager` policy evaluation cycle. This allows the OMR prefix to
be managed independently and published faster into the Network Data.

Previously, `OmrPrefixManager` relied on its `Evaluate()` method being
called during the main `RoutingManager::EvaluateRoutingPolicy()` cycle.
This meant it had to wait for other components to be ready — such as
sending Router Solicitations to discover other routers on the Adjacent
Infrastructure Link (AIL)—before taking action.

With this change, `OmrPrefixManager` operates independently. It can
evaluate its state as soon as the Border Router function is enabled and
`Start()` is called.

Additional improvements supporting this independent operation include:
- Replaces the `mIsLocalAddedInNetData` boolean with a `LocalPrefixState`
  enum (`kNotAdded`, `kToAdd`, `kAdded`) to manage addition state and
  support delayed updates.
- Introduces a random delay (`kMinDelayToAdd` to `kMaxDelayToAdd`)
  before adding a self-generated OMR prefix to Network Data. This gives
  the network time to settle, allowing other BRs or the `PdPrefixManager`
  time to establish a prefix.
- Implements a retry mechanism with jitter for Network Data addition
  failures, rather than silently ignoring them.
- Refactors `PdPrefixManager` to batch state changes via an `mEvents`
  bitmask and process them through `mEventTask`. Changes are now handled
  explicitly by `OmrPrefixManager::HandlePdPrefixManagerEvent()`, further
  reducing unnecessary main routing policy evaluations.
2026-03-26 17:30:29 -05:00
Zhanglong Xia 789ad728fd [dataset] add API otDatasetIsValid support (#12757)
This commit adds an API otDatasetIsValid to check whether the given
Operational Dataset contains all the required TLVs (Active Timestamp,
Channel, Channel Mask, Extended PAN ID, Mesh-Local Prefix, Network
Key, Network Name, PAN ID, PSKc, and Security Policy). This API also
checks whether there are duplicated TLVs or the TLVs are not
well-formed.
2026-03-26 17:26:03 -05:00
Jonathan Hui f5b89b7384 [tests] remove v1.2 backbone and multicast scripts migrated to nexus (#12778)
This commit removes three Python-based thread-cert scripts for v1.2
backbone router and multicast registration testing:

- v1_2_test_backbone_router_service.py
- v1_2_test_multicast_listener_registration.py
- v1_2_test_multicast_registration.py

These tests have been fully migrated to the Nexus simulation
framework, providing equivalent verification in a more robust and
scalable environment.

The equivalent Nexus test cases are already part of the repository:
- 1_2_BBR_TC_1, 1_2_BBR_TC_2, 1_2_BBR_TC_3
- 1_2_MATN_TC_1, 1_2_MATN_TC_2, ..., 1_2_MATN_TC_26
2026-03-26 16:53:31 -05:00
Suvesh Pratapa cc31b64cc1 [build] fix -Wimplicit-int-conversion errors with Clang 21 (#12775)
C++ promotes narrow integer types to int before applying ~ or unary -,
so the result is always int even when the variable being assigned to is
narrower. Clang accepted this silently for years due to a bug in its
range tracking (LLVM #126846, fixed March 2025); Clang 21, now included
in the latest Mac OS for example, correctly flags these as errors.

Add <static_cast> to the destination type at each affected spot.
2026-03-26 16:32:55 -05:00
Jonathan Hui 274c47ab10 [nexus] add SRP_TC_5 for key record inclusion/omission (#12764)
This commit adds the Nexus test case 1_3_SRP_TC_5 which verifies SRP
KEY record inclusion and omission behavior according to the Thread 1.3
test specification (SRP TC-5).

The implementation includes:
- Adding mHostKeyRecordEnabled flag to Srp::Client to control host
  KEY record inclusion in SRP Updates. This is enabled only when
  OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE is defined.
- Implementing SetHostKeyRecordEnabled() and IsHostKeyRecordEnabled()
  methods in Srp::Client.
- Modifying AppendHostDescriptionInstruction() in srp_client.cpp
  to conditionally include the KEY record.
- Creating tests/nexus/test_1_3_SRP_TC_5.cpp to execute the test
  sequence across multiple simulated nodes (BR_1, ED_1, Eth_1).
- Creating tests/nexus/verify_1_3_SRP_TC_5.py to perform automated
  verification of the captured traffic.
- Updating tests/nexus/CMakeLists.txt and
  tests/nexus/run_nexus_tests.sh to include the new test.

The test ensures that the SRP server correctly handles updates with
and without service KEY records, omits KEY records in DNS/mDNS
responses, and rejects updates that omit all KEY records.
2026-03-26 15:12:24 -05:00
Jonathan Hui 94dca41a86 [nexus] add SRP-TC-4 for SRP key lease handling (#12760)
This commit adds a new Nexus test case 1_3_SRP_TC_4 which implements
the test specification for SRP key lease handling.

The test verifies that:
- A service instance name cannot be claimed even after the service
  instance lease has expired, as long as its key lease remains active.
- The SRP server correctly manages key leases and rejects registration
  updates for hosts or services that are still claimed by a previous
  registration during the key lease period.
- DNS and mDNS responses correctly reflect the state of registrations
  and their expirations.

Changes:
- Add tests/nexus/test_1_3_SRP_TC_4.cpp for test execution.
- Add tests/nexus/verify_1_3_SRP_TC_4.py for pcap verification.
- Update tests/nexus/CMakeLists.txt to include the new test.
- Update tests/nexus/run_nexus_tests.sh to add it to DEFAULT_TESTS.
2026-03-26 12:50:16 -05:00
Abtin Keshavarzian 02aaf7cb73 [tlv] remove Tlv::ReadTlvValue() (#12768)
This commit removes the `Tlv::ReadTlvValue()` method which is no
longer needed or used. The same functionality is provided through
the `Tlv::Info` class, specifically using its `ParseFrom()` and
`ReadValue()` methods. This approach is safer and provides more
comprehensive information about the parsed TLV.

The unit tests are also updated to replace the usage of the removed
method with the new `Tlv::Info` based approach.
2026-03-25 23:33:41 -05:00
Abtin Keshavarzian f1794af0a7 [nexus] support node-specific log files (#12767)
This commit introduces node-specific log files for Nexus tests. Each
created node can save its OpenThread logs into a separate file
`ot-logs<id>.log`.

The generation of log files is controlled by the environment variable
`OT_NEXUS_SAVE_LOGS`. By default, it is disabled, but it can be
activated by setting the environment variable to "1", "yes", "true",
"on", or "t".

This commit also refactors the Nexus platform logging logic into a new
`nexus_logging.cpp` file and improves the log message format in `stdout`
to include a standard timestamp using `UptimeToString()`.
2026-03-25 21:23:52 -05:00
Abtin Keshavarzian 1f218fd056 [nexus] use two host nodes in BBR_TC_3 for robust verification (#12766)
This commit updates the `BBR_TC_3` Nexus test to use two separate host
nodes, `HOST_1` and `HOST_2`, for sending mDNS queries.

By using distinct host nodes, the packet verification script can now
unambiguously identify and track queries from different test steps
based on their source Ethernet MAC address. This improves the
robustness of the test by reducing reliance on packet sequence
numbers for isolation which can be fragile due to possible multiple
transmission of mDNS query message.

Specifically, `HOST_1` is used for queries in steps 1, 5, and 12,
while `HOST_2` is dedicated to the query in step 9. Both the C++ test
logic in `test_1_2_BBR_TC_3.cpp` and the Python verification script in
`verify_1_2_BBR_TC_3.py` are updated to reflect this change.
2026-03-25 21:22:17 -05:00
Abtin Keshavarzian 9ca942c313 [mle] reduce log error spam when Mle::IsDisabled() (#12763)
This commit updates `Mle::HandleUdpReceive()` to avoid logging an error
when an MLE message is received while MLE is disabled.

When `IsDisabled()` is true, the `VerifyOrExit` macro now exits the
method without setting `error` to `kErrorInvalidState`. This ensures
that the `LogProcessError()` call at the `exit` label does not emit an
error log. This reduces log spam during testing/debugging.
2026-03-25 21:21:51 -05:00
Abtin Keshavarzian c923900de0 [platform] implement otPlatLogOutput platform API (#12762)
This commit provides the platform-level implementation for the
instance-aware logging API `otPlatLogOutput()`. This API is used when
`OPENTHREAD_CONFIG_LOG_INSTANCE_AWARE_API_ENABLE` is enabled, allowing
the platform to receive the `otInstance` pointer with each log line.

The new API is implemented across:
- The simulation platform logging.
- The POSIX platform using `syslog()`.
- The NCP base to route logs to the NCP host.
- The CLI logging module.
- Unit tests and mock platforms.

The `OPENTHREAD_CONFIG_LOG_INSTANCE_AWARE_API_ENABLE` configuration is
also enabled for Toranj simulations to support multi-instance log
testing.
2026-03-25 21:21:24 -05:00
Abtin Keshavarzian b5e2393c7d [logging] support uptime prepending in multi-instance builds (#12761)
This commit adds support for `OPENTHREAD_CONFIG_LOG_PREPEND_UPTIME` in
multi-instance builds.

When `OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE` is enabled, the uptime
is retrieved from the currently active `Instance` using
`Instance::GetActiveInstance()`. This requires
`OPENTHREAD_CONFIG_LOG_INSTANCE_AWARE_API_ENABLE` to be enabled so that
the `Logger` can identify the instance and access its `UptimeTracker`.

A compile-time check is added to ensure that
`OPENTHREAD_CONFIG_LOG_INSTANCE_AWARE_API_ENABLE` is set when
`OPENTHREAD_CONFIG_LOG_PREPEND_UPTIME` is used in a multi-instance
build.
2026-03-25 21:20:55 -05:00
Jonathan Hui 240acdffaa [nexus] add SRP-TC-3 for lease renewal and automatic removal (#12759)
This commit adds a new Nexus test case 1_3_SRP_TC_3 which implements
the test specification for service instance lease renewal and
automatic service/host removal.

The test covers:
- SRP service registration and discovery via DNS and mDNS.
- SRP lease renewal before expiration.
- Automatic removal of SRP services and hosts after lease expiration.
- Verification of DNS and mDNS responses after lease expiration,
  ensuring that expired records are no longer returned.

Changes:
- Add tests/nexus/test_1_3_SRP_TC_3.cpp for test execution.
- Add tests/nexus/verify_1_3_SRP_TC_3.py for pcap verification.
- Update tests/nexus/CMakeLists.txt to include the new test.
- Update tests/nexus/run_nexus_tests.sh to add it to DEFAULT_TESTS.
2026-03-25 21:17:08 -05:00
Jonathan Hui 4599d00462 [nexus] add SRP-TC-2 for SRP name conflict handling (#12758)
This commit adds a new Nexus test case 1_3_SRP_TC_2 which implements
the test specification for handling name conflicts in SRP host and
service registrations.

The test covers:
- Handling name conflicts in Host Description records.
- Handling name conflicts in Service Description records.
- Verifying that original services are discoverable on the AIL
  while conflicting services are correctly rejected and not seen.
- Validating mDNS discovery on the adjacent infrastructure link
  using direct method calls for SRP and DNS-SD operations.

Changes:
- Add tests/nexus/test_1_3_SRP_TC_2.cpp for test execution.
- Add tests/nexus/verify_1_3_SRP_TC_2.py for pcap verification.
- Update tests/nexus/CMakeLists.txt to include the new test.
- Update tests/nexus/run_nexus_tests.sh to add it to DEFAULT_TESTS.
2026-03-25 18:52:13 -05:00
Tom Rebbert 361f7311de [mle] add 2 additional retries on child ID request messages to improve attachment robustness (#12025)
In testing I have observed some failures to attach due to a `Child ID
Request` or `Child ID Response` getting lost in the air causing the
attaching device to start it's own new partition (assuming FTD).

When attaching, after selecting a parent candidate from the responses
to a multicast `Parent Request` message, devices only have one shot to
send and receive a response to a `Child ID Request`. There is a higher
rate of failure in this sequence during high traffic periods such as
formation and reset, which will cause more devices than desired to
fail the attachment process (and become their own leader if an FTD).

This commit aims to help address this by adding 2 additional retries
to `Child ID Request` messages, which gives devices a much better
chance of attaching the first time.
2026-03-25 16:47:51 -05:00
Jonathan Hui 07cb0ebd5b [nexus] add SRP-TC-1 for SRP registration and discovery (#12755)
This commit adds a new Nexus test case 1_3_SRP_TC_1 which verifies
SRP registration and discovery in a topology with a Border Router.

The test covers:
- SRP server registration in Thread Network Data.
- SRP service registration by a Thread End Device.
- Unicast DNS queries over the Thread interface.
- mDNS discovery over the Infrastructure interface.

Changes:
- Add tests/nexus/test_1_3_SRP_TC_1.cpp for test execution.
- Add tests/nexus/verify_1_3_SRP_TC_1.py for pcap verification.
- Update tests/nexus/CMakeLists.txt and run_nexus_tests.sh.
- Extend pktverify library (consts.py, layer_fields.py) to support
  DNS/mDNS and SRP-specific fields.
2026-03-25 16:14:23 -05:00
Abtin Keshavarzian 9b00c024a8 [mle] block router downgrade if triggered by child ID request (#12725)
This commit updates the `Mle` router role downgrade logic. When a
REED transitions to a router in response to a Child ID Request, it
indicates that the attaching child has no other viable parent options.
To ensure this child remains connected to the mesh, this commit
prevents the newly promoted router from downgrading back to a REED.

A new flag `mBlockDowngrade` is added to `Mle`, and a matching
property `mBlockParentDowngrade` is added to `Child` to track if it is
blocking its parent's downgrade. The downgrade restriction is lifted
under specific conditions: when the device detaches, when a new router
is added to the network (providing a potential alternative parent for
the child), or when all children blocking the downgrade are removed.

A new nexus test `test_mle_blocking_downgrade` is added to validate
the new behavior.
2026-03-25 12:47:36 -05:00
Abtin Keshavarzian a5593e7980 [nexus] remove active node tracking (#12754)
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()`.
2026-03-25 10:36:11 -05:00
Jonathan Hui 37f09fe97e [nexus] add test 1-3-DBR-TC-10 for OMR routing and default routes (#12752)
This commit adds a new Nexus test case 1_3_DBR_TC_10 which implements
the test specification for reachability, OMR address configuration,
and default route processing in a Thread network with a Border Router.

The test ensures that:
- End Devices correctly configure OMR addresses from OMR prefixes.
- Routers correctly process and route packets based on external
  (default) routes advertised by Border Routers.
- Border Routers can manage default routes using both external route
  TLVs (::/0) and the P_default flag in OMR prefixes.

Changes:
- Add tests/nexus/test_1_3_DBR_TC_10.cpp for test execution.
- Add tests/nexus/verify_1_3_DBR_TC_10.py for pcap verification.
- Update tests/nexus/CMakeLists.txt and tests/nexus/run_nexus_tests.sh
  to include the new test.
2026-03-25 10:03:37 -05:00
Jonathan Hui 84bce0f587 [nexus] add helper methods to verify_utils.py and update tests (#12756)
This commit adds several new helper methods to tests/nexus/verify_utils.py
to simplify common verification tasks in Nexus tests:
- check_ra_has_rio: verify presence and preference of RIO in RA.
- check_ra_has_pio: verify presence of PIO in RA.
- check_nwd_has_route: verify presence and preference of external
  route in Network Data.

Existing tests (1_3_DBR_TC_7A/B/C and 1_3_DBR_TC_8) are updated to use
these new helper methods, which improves code readability and
consistency across the Nexus test suite.
2026-03-25 00:49:52 -05:00
Jonathan Hui 81d49bf906 [nexus] add DBR-TC-8 test for bi-directional reachability (#12751)
This commit introduces the 1_3_DBR_TC_8 Nexus test case, which
verifies bi-directional reachability in a topology with multiple
Border Routers (BRs) and the presence of OMR prefixes with different
lifetimes.

Key features of this test:
- Simulates a network with two BRs and a Thread Router.
- Configures an infrastructure link with a GUA prefix.
- Configures an OMR prefix (OMR_4, P_preferred=false) in Network
  Data and ensures the DUT BR correctly generates its own OMR
  prefix when existing ones are not usable.
- Verifies that the DUT BR correctly multicasts Router
  Advertisements (RAs) on the infrastructure link containing OMR
  routes but excluding deprecated OMR_4 routes.
- Confirms bi-directional ICMPv6 connectivity between an
  infrastructure device and a Thread Router.
- Ensures the DUT BR continues to advertise OMR routes even after
  the originating BR (BR_2) is disabled.

The implementation includes:
- tests/nexus/test_1_3_DBR_TC_8.cpp: Test execution logic using
  direct method calls and Note-level logging.
- tests/nexus/verify_1_3_DBR_TC_8.py: PCAP-based verification script
  with robust Network Data and RA checking.
- Updates to tests/nexus/CMakeLists.txt and
  tests/nexus/run_nexus_tests.sh to register the new test case.
2026-03-24 21:56:43 -05:00
Jonathan Hui 6fd5c443de [nexus] add DBR-TC-7C test for bi-directional reachability (#12749)
This commit introduces the 1_3_DBR_TC_7C Nexus test case, which
verifies bi-directional reachability in a topology with multiple
Border Routers (BRs) and the presence of non-OMR prefixes.

Key features of this test:
- Simulates a network with two BRs and a Thread Router.
- Configures an infrastructure link with a GUA prefix.
- Configures a non-OMR prefix (PRE_1, P_on_mesh=false) in Network
  Data and ensures the DUT BR correctly generates its own OMR
  prefix when existing ones are not usable.
- Verifies that the DUT BR correctly multicasts Router
  Advertisements (RAs) on the infrastructure link containing OMR
  routes but excluding PRE_1 routes.
- Confirms bi-directional ICMPv6 connectivity between an
  infrastructure device and a Thread Router.
- Ensures the DUT BR continues to advertise OMR routes even after
  the originating BR (BR_2) is disabled.

The implementation includes:
- tests/nexus/test_1_3_DBR_TC_7C.cpp: Test execution logic using
  direct method calls and Note-level logging.
- tests/nexus/verify_1_3_DBR_TC_7C.py: PCAP-based verification script
  with robust Network Data and RA checking.
- Updates to tests/nexus/CMakeLists.txt and
  tests/nexus/run_nexus_tests.sh to register the new test case.
2026-03-24 19:41:52 -05:00
Abtin Keshavarzian b35cb137d5 [logging] introduce instance-aware platform logging API (#12737)
This commit adds `otPlatLogOutput()`, a new platform logging API that
provides the `otInstance` pointer along with a pre-formatted log
string. This addresses the limitation of the existing `otPlatLog()` in
multi-instance builds, where the function cannot reliably determine
which OpenThread instance generated the log.

`OPENTHREAD_CONFIG_LOG_INSTANCE_AWARE_API_ENABLE`, is introduced to
enable this behavior. When enabled, `Logger::Log()` resolves the
active instance (via a tracked global pointer `gActiveInstance`)
and passes it to `otPlatLogOutput()`.

To support tracking the active instance context,
`UpdateActiveInstance()` is added and called during standard
instance retrieval paths, such as `Locator::GetInstance()` and
`Message::GetInstance()`. The TCP endpoints and listeners are also
updated to track the active instance when their `GetInstance()` methods
are invoked.

The Nexus testing platform is updated to enable this configuration
and implement `otPlatLogOutput()` to print the instance ID alongside
the log line, simplifying log tracing in multi-node simulations.
2026-03-24 15:30:08 -05:00
Abtin Keshavarzian 52551d8ff0 [border-router] simplify local OMR prefix update logic (#12750)
This commit simplifies the logic for updating the local OMR prefix
within `RoutingManager::OmrPrefixManager`.

The process of updating the prefix in `UpdateLocalPrefix()` is
consolidated into a single flow. Instead of multiple paths clearing
the old prefix from `NetworkData` and logging changes, the method now
determines the appropriate `prefix`, `preference`, and `origin`
(`kSelfGenerated`, `kCustom`, `kDhcp6Pd`), and delegates the change
to a shared sequence at the end of the method.

It also adds a `Matches()` method to `OmrPrefix` to efficiently check
if a given `Ip6::Prefix` and `RoutePreference` match the current OMR
prefix, avoiding unnecessary copies during updates.

Additionally, this change standardizes the log output format for local
OMR prefix updates by utilizing `LocalToString()` and ensures
the prefix's route preference is consistently included.
2026-03-24 14:10:02 -05:00
Jonathan Hui 5b38208dbf [nexus] add DBR-TC-7B test for bi-directional reachability (#12748)
This commit introduces the 1_3_DBR_TC_7B Nexus test case, which
verifies bi-directional reachability in a topology with multiple
Border Routers (BRs) and the presence of deprecated prefixes.

Key features of this test:
- Simulates a network with two BRs and a Thread Router.
- Configures an infrastructure link with a GUA prefix.
- Configures a deprecated prefix (PRE_1, P_preferred=false) in
  Network Data and ensures the DUT BR correctly generates its own
  OMR prefix when existing ones are not usable.
- Verifies that the DUT BR correctly multicasts Router Advertisements
  (RAs) on the infrastructure link containing both OMR and PRE_1
  routes.
- Confirms bi-directional ICMPv6 connectivity between an
  infrastructure device and a Thread Router.
- Ensures the DUT BR continues to advertise PRE_1 routes even after
  the originating BR (BR_2) is disabled, as long as the prefix
  remains in Network Data.

The implementation includes:
- tests/nexus/test_1_3_DBR_TC_7B.cpp: Test execution logic using
  direct method calls and Note-level logging.
- tests/nexus/verify_1_3_DBR_TC_7B.py: PCAP-based verification script
  with robust Network Data flag checking.
- Updates to tests/nexus/CMakeLists.txt and
  tests/nexus/run_nexus_tests.sh to register the new test case.
2026-03-24 14:05:30 -05:00
Jonathan Hui 1cbfe480c3 [nexus] add DBR-TC-7A test for bi-directional reachability (#12747)
This commit introduces the 1_3_DBR_TC_7A Nexus test case, which verifies
bi-directional reachability in a topology with multiple Border Routers
(BRs) and the presence of non-OMR prefixes.

Key features of this test:
- Simulates a network with two BRs and a Thread Router.
- Configures an infrastructure link with a GUA prefix.
- Configures a non-OMR prefix (PRE_1) in Network Data and ensures the
  DUT BR correctly generates its own OMR prefix when existing ones are
  not usable (e.g., SLAAC disabled).
- Verifies that the DUT BR correctly multicasts Router Advertisements
  (RAs) on the infrastructure link containing both OMR and PRE_1 routes.
- Confirms bi-directional ICMPv6 connectivity between an infrastructure
  device and a Thread Router.
- Ensures the DUT BR continues to advertise PRE_1 routes even after the
  originating BR (BR_2) is disabled, as long as the prefix remains in
  Network Data.

The implementation includes:
- tests/nexus/test_1_3_DBR_TC_7A.cpp: Test execution logic using direct
  method calls and Note-level logging.
- tests/nexus/verify_1_3_DBR_TC_7A.py: PCAP-based verification script
  with robust Network Data flag checking.
- Updates to tests/nexus/CMakeLists.txt and tests/nexus/run_nexus_tests.sh
  to register the new test case.
2026-03-24 12:28:00 -05:00
Tom Rebbert 42ac624019 [mle] improve router and leader post reset link request timings and attempts (#12022)
In order to facilitate a well-staged post reset process for a larger
size link, it is important to consider the timing of devices returning
to the link.

With the changes in this PR, that timing will be as follows:
1. The leader and routers will begin sending link request messages in
   an attempt to reattach to the previous partition.
2. Both the leader and routers will have 4 attempts to reconnect,
   afterwords falling back to attach any.
3. The leader here is given a 2s retry window (jittered 10% either
   way), for a worst-case (tightest timing vs routers) of 4x2.2s =
   8.8s before starting attachment.
4. The routers here are given the normal 5s multicast retx delay with
   the same 10% jitter, resulting in a tightest timing (shortest) of
   4x4.5s = 18s
5. For this analysis, the jitter during the attach process is ignored
   because it will not be particularly significant, so we assume both
   flow through a nominal failed attachment of 2x0.75s (routers) +
   4x1.25s (reeds) = 6.5s
6. This means that the previous leader will start the new partition
   around 15.3s after starting.
7. The former routers would fall back to starting a new partition on
   their own at 24.5s after reset.

This timing leaves 9.2s of leeway (greater than the length of the full
attachment process) for the routers to get parent responses from the
old leader which has started the new partition and attach instead of
starting their own partitions.

This also leaves sufficient time between the router attachment and
children timing out of their role restoration process to attach to
their former parents.

Additionally, 4 attempts should be more than sufficient with this
timing to successfully reattach to a partition that did not also
reset. If a link request sent in this period is not accepted, then the
old partition can be safely assumed to be gone, or removed links to
the reset device.

Routers with children and the leader will also benefit in
single-device reset cases here because they are able to rejoin more
quickly. Only routers with very few/no children are slowed down in
re-attachment by 5s.
2026-03-24 11:57:33 -05:00
MaikVermeulen 683086776f [posix] add --settings-file option for fixed settings file name (#12719)
This adds a new --settings-file launch option that allows specifying
a fixed base name for the settings file, overriding the default
EUI64-based naming scheme.

When an RCP device is replaced, the new device has a different EUI64,
which causes the host to lose access to its previously stored dataset.
By using --settings-file, the settings file name remains stable across
RCP replacements, preserving the Thread network configuration.

Ref: https://github.com/orgs/openthread/discussions/12428
2026-03-24 09:38:47 -05:00
Jonathan Hui 37c6808380 [nexus] add DBR-TC-06 test and support for Router Advertisements (#12742)
This commit introduces the 1_3_DBR_TC_6 Nexus test case to verify
bi-directional reachability in a multi-BR topology with existing
IPv6 infrastructure.

Key changes:
- Implement tests/nexus/test_1_3_DBR_TC_6.cpp and its corresponding
  pcap-based verification script tests/nexus/verify_1_3_DBR_TC_6.py.
- Enhance the Nexus platform InfraIf class to support constructing
  and sending ICMPv6 Router Advertisements (RA) with PIO and RIO.
- Add RouterAdvertisementStart() and RouterAdvertisementStop() to
  InfraIf for managed periodic unsolicited RA transmissions.
- Update Core::Process() to drive the periodic RA logic in InfraIf.
- Implement response logic for ICMPv6 Router Solicitations in
  InfraIf when RA advertising is enabled.
- The 1_3_DBR_TC_6 test validates that the DUT BR correctly adopts
  existing OMR prefixes, advertises an external default route (::/0),
  and sends appropriate RAs on the infrastructure link.
- Register the new test case in tests/nexus/CMakeLists.txt and
  tests/nexus/run_nexus_tests.sh.
2026-03-23 17:21:52 -05:00
Abtin Keshavarzian d5bde0bc31 [instance] require MULTIPLE_INSTANCE_ENABLE for static instances (#12734)
This commit updates the conditional compilation for the multiple
static instances array in `Instance`. It adds a check for
`OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE` alongside
`OPENTHREAD_CONFIG_MULTIPLE_STATIC_INSTANCE_ENABLE`.
2026-03-23 15:42:47 -05:00
Abtin Keshavarzian 78ddbf7845 [message] add clone methods to MessageAllocator (#12704)
This commit adds `CloneMessage()`, `CloneMessageWithoutFooter()`,
and `CloneMessageWithout<Footer>()` methods to the `MessageAllocator`
class. These methods simplify creating copies of messages by
automatically applying the correct `kReservedHeader` size. It also
updates existing code in `CoapBase`, `Dns::Client`, `Sntp::Client`,
and `Mle` to utilize these new methods.

Additionally, this commit updates the `Clone()` method in `Message`
to be a template method, accepting a `CloneMode` to specify whether
the cloned message should retain the reserved header or have no
reserved header. The documentation for the clone methods has also
been updated to clarify which message fields are copied during the
cloning process.
2026-03-23 15:42:16 -05:00
Jonathan Hui bb06821cea [nexus] add DBR-TC-03 test for multi-Thread network reachability (#12735)
This commit introduces the 1_3_DBR_TC_3 nexus test case to verify
bi-directional reachability between multiple Thread networks connected
via a common infrastructure link.

The test verifies that independent Thread networks, each with its own
Border Router (BR) connected to the same infrastructure link, can
successfully route traffic to each other. This confirms reachability
in multi-Thread network environments where no existing IPv6
infrastructure is present.

Key changes:
- Implement test_1_3_DBR_TC_3.cpp to simulate a topology with two
  Thread networks (BR_1/ED_1 and BR_2/ED_2) and verify end-to-end
  ping success between End Devices.
- Implement verify_1_3_DBR_TC_3.py for pcap-based validation of:
    - Network Data registration of OMR and infrastructure prefixes.
    - RA multicasts on the infrastructure link with correct RIO/PIO.
    - Proper mapping of Extended PAN ID into the infrastructure ULA.
    - Bi-directional ICMPv6 connectivity between End Devices.
- Register the new test case in CMakeLists.txt and run_nexus_tests.sh.
2026-03-23 14:26:52 -05:00
Zhanglong Xia 366a021076 [dataset] add API otDatasetTlvsCompare (#12684)
Thread spec doesn't define the order of TLVs in the dataset, so that
we can't call `memcmp` to compare two dataset.  If we convert the
dataset to otOperationalDataset and then compare each value of
otOperationalDataset, we will met an issue if the new Thread spec
defines new TLVs in the dataset in the future.

This commit add a new dataset API `otDatasetTlvsCompare` to check
whether two dataset contain the exact same set of TLVs (same types and
values).
2026-03-23 13:04:05 -05:00
Abtin Keshavarzian 13776bc05c [router-table] introduce Event to track specific table changes (#12715)
This commit introduces a new `Event` enumeration in `RouterTable`
along with an `Events` bit-field to track and indicate specific changes
that occur within the table. The `SignalTableChanged()` method is
updated to accept these events, replacing the previous parameterless
version. A new `LogEvents()` method is also added to log a summary of
the changes whenever the table is updated, improving debugging and
visibility into the router table's state.
2026-03-23 12:49:12 -05:00
dependabot[bot] 6d5bd4157a github-actions: bump umbrelladocs/action-linkspector from 1.4.0 to 1.4.1 (#12745)
Bumps [umbrelladocs/action-linkspector](https://github.com/umbrelladocs/action-linkspector) from 1.4.0 to 1.4.1.
- [Release notes](https://github.com/umbrelladocs/action-linkspector/releases)
- [Commits](https://github.com/umbrelladocs/action-linkspector/compare/652f85bc57bb1e7d4327260decc10aa68f7694c3...37c85bcde51b30bf929936502bac6bfb7e8f0a4d)

---
updated-dependencies:
- dependency-name: umbrelladocs/action-linkspector
  dependency-version: 1.4.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-23 12:45:24 -05:00
Jonathan Hui c854c63126 [nexus] improve robustness of DBR verification in Nexus tests (#12741)
This commit refactors the verification logic for Distributed Border
Router (DBR) tests in the Nexus framework to enhance robustness and
reliability.

Key changes include:
- Introduced verify_utils.check_nwd_prefix_flags() to handle complex
  Thread Network Data structures, allowing for precise verification of
  Prefix TLV flags and Border Router sub-TLV flags even when multiple
  prefixes are present.
- Updated verify_1_3_DBR_TC_1.py and verify_1_3_DBR_TC_2.py to use
  the new helper and improved the identification of OMR and ULA
  prefixes in Network Data by iterating through TLV types.
- Added verification for Preferred and Valid Lifetimes in ICMPv6 Prefix
  Information Options (PIO) within Router Advertisements.
- Enhanced pktverify to support icmpv6.opt.pio_valid_lifetime and
  ensured proper mapping of PIO lifetime fields.
- Simplified MLE Data Response filtering in verify_1_3_DBR_TC_1.py
  for better maintainability.
2026-03-23 12:38:14 -05:00
Jonathan Hui a734539246 [nexus] add DBR-TC-02 test case for multiple BR reachability (#12732)
This commit introduces the 1_3_DBR_TC_2 nexus test case to verify
bi-directional reachability between Thread and infrastructure devices
in a topology with multiple Border Routers.

Key changes:
- Implement test_1_3_DBR_TC_2.cpp for step-by-step execution logic.
- Implement verify_1_3_DBR_TC_2.py for pcap-based verification.
- Enable OPENTHREAD_CONFIG_BORDER_ROUTING_TESTING_API_ENABLE in nexus
  platform configuration to support prefix manipulation.
- Add icmpv6.opt.pio_preferred_lifetime to pktverify layer fields.
- Register the new test case in CMakeLists.txt and the default nexus
  test run script.
- Refactor verify_1_3_DBR_TC_1.py and verify_1_3_DBR_TC_2.py to move
  nested helper functions to the top level for better modularity.
- Remove an unnecessary Deinit() call in test_1_3_DBR_TC_1.cpp and
  its definition in nexus_infra_if.hpp.

The test verifies:
- Border Router adoption of existing OMR prefixes in the network.
- Router Advertisement (RA) behavior on the infrastructure link,
  including correct RIO options and suppression of non-deprecating PIOs
  when another BR is present.
- Bi-directional reachability between Thread End Devices and Adjacent
  Infrastructure Link (AIL) hosts during BR transitions.
- Automatic election of a new Leader and promotion to Primary BR upon
  loss of the previous Leader.
- Correct derivation of BR ULA prefixes from the Extended PAN ID.
2026-03-22 23:34:39 -05:00
Jonathan Hui ea05e2fd0c [nexus] fix flaky BBR-TC-03 by filtering transient mDNS responses (#12736)
Nexus test 1_2_BBR_TC_3 occasionally fails during Step 6 after a
device reboot. The failure occurs because the Backbone Router (BBR)
is reported as active in the mDNS state bitmap ('sb' record), but
the mandatory 'omr' record is not yet present in the response.

This transient state happens because the BBR function is enabled
immediately upon attachment, whereas the Routing Manager requires
a brief period to establish and favor an OMR prefix.

This commit updates the Python verification script to filter for
mDNS responses that include the 'omr' record in Steps 6 and 13. This
allows the test to wait for the complete state to be published
naturally, rather than failing on the first transient packet
received.

Validated with 50 successful sequential executions of the test.
2026-03-22 23:34:11 -05:00
Jonathan Hui b70b3ccb6a [nexus] add DBR-TC-01 test case for single BR reachability (#12730)
This commit implements the 1_3_DBR_TC_1 nexus test case to verify
bi-directional reachability between Thread and infrastructure
devices with a single Border Router.

Key changes:
- Implement test_1_3_DBR_TC_1.cpp for step-by-step execution logic.
- Implement verify_1_3_DBR_TC_1.py for pcap-based verification.
- Enhance Nexus InfraIf platform to support Deinit() for AIL
  disconnection.
- Update InfraIf::Receive() to check initialization status and
  ignore kErrorDrop from SendRaw() to handle legitimate packet
  drops in the stack.
- Register the new test case in CMakeLists.txt and the default
  nexus test run script.

The test verifies:
- Automatic OMR and on-link prefix registration in Network Data.
- Periodic ND Router Advertisement multicast on the infrastructure
  link with correct PIO/RIO options and Extended PAN ID derivation.
- Bi-directional reachability between Thread End Devices (OMR) and
  Infrastructure Hosts (ULA).
- Strict enforcement of non-forwarding rules for link-local and
  Mesh-Local EID traffic between the Thread and infrastructure
  networks.
2026-03-21 20:37:13 -05:00
Jonathan Hui d64bdee1bb [nexus] fix intermittent failure in Test 1-2-BBR-TC-2 (#12738)
Nexus test 1_2_BBR_TC_2 was occasionally failing at Step 14.
In this step, the previous leader (Router_1) is disabled, and
the DUT (BR_1) is expected to become the new leader and the
Primary Backbone Router (BBR).

The original wait time was 200 seconds (kAttachToRouterTime).
However, analysis showed that routers wait for the MLE Router
ID Timeout (120 seconds) before initiating a new leader election.
Combined with election jitter and BBR registration time, this
sometimes exceeded the 200-second window.

This commit increases the wait time in Step 14 to 400 seconds
(kAttachToRouterTime * 2) to provide sufficient buffer for the
leader transition and BBR registration, effectively resolving
the flake.
2026-03-21 20:31:47 -05:00
Abtin Keshavarzian c66c6e41d4 [tlv] update Append<Tlv>() to use uint16_t for aLength (#12728)
This commit updates the `Tlv::Append()` method template to accept a
`uint16_t` for the `aLength` parameter instead of `uint8_t`. This
change aligns the template method with the underlying `AppendTlv()`
method, allowing it to correctly append both regular and extended
TLVs based on the provided length.

The Doxygen comments are also updated to clarify that the TLV is
appended as either a regular or an extended TLV depending on whether
the length is greater than `kBaseTlvMaxLength`.
2026-03-20 20:40:35 -05:00
Jonathan Hui 05e7eb7e7a [nexus] add BBR-TC-03 test case for mDNS discovery of BBR function (#12724)
This commit implements the BBR-TC-03 test case in the Nexus simulation
framework to verify that a Backbone Router (BBR) function can be
discovered using mDNS and that changes are correctly reflected.

Key implementation details include:
- Implementation of BBR-TC-03 in C++ simulating a topology with two
  Border Routers (BR_1 as initial Primary BBR, BR_2 as Secondary)
  and a non-Thread IPv6 Host used for mDNS queries.
- Use of direct method calls instead of OpenThread public APIs where
  appropriate, following Nexus test conventions.
- Configuration of the test environment including fixed Operational
  Datasets to ensure predictable verification.
- Simulation of various network states:
  - Initial Primary/Secondary BBR discovery.
  - BBR function persistence after device reboot.
  - Role transition (Secondary becoming Primary) when the original
    Primary BBR powers down.
  - Secondary BBR discovery when the original Primary BBR rejoins.
- Addition of a Python verification script to validate mDNS packets on
  the simulated infrastructure link, checking for:
  - Correct mDNS query/response exchanges between Host and BBRs.
  - Presence and format of mandatory TXT records (dn, bb, sq, rv, tv,
    sb, nn, xp, omr).
  - Proper state bitmap (sb) transitions reflecting Primary vs.
    Secondary status.
- Inclusion of the full test specification as inline comments in both
  C++ and Python files, adhering to strict formatting requirements.
- Registration of the new test case in tests/nexus/CMakeLists.txt and
  the default test list in tests/nexus/run_nexus_tests.sh.
- Setting log level to 'note' for improved visibility into state
  transitions.
2026-03-20 18:43:51 -05:00
Abtin Keshavarzian 7b5871913a [network-diag] simplify ChildTableTlv generation and parsing (#12712)
This commit updates `ChildTableTlvEntry` to better support the packing
and parsing of child entries in a `ChildTableTlv`. It introduces an
`InitFrom()` method to encode an entry directly from a `Child`
object, and a `Parse()` method to extract values into a `ParseInfo`
struct, improving modularity and simplifying usage.

Additionally, it consolidates the logic for calculating the timeout
exponent and decoding it back to a timeout value directly within the
`ChildTableTlvEntry` class. It also introduces `ParseChildTable()` in
`NetworkDiagnostic::Client` to clean up the child table parsing
loop.
2026-03-20 17:13:52 -05:00
Jonathan Hui 5e99ebaa51 [nexus] update mDNS traffic to flow through infrastructure link (#12720)
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'.
2026-03-20 17:05:32 -05:00
Abtin Keshavarzian fb216d335c [cmake] update CMake configurations for Apple platforms (#12729)
This commit updates various CMake configuration files to simplify
the check for Apple platforms. It replaces the `CMAKE_CXX_COMPILER_ID`
check for `AppleClang` with the built-in `APPLE` variable across
multiple targets (such as `ftd`, `mtd`, `cli`, and others). This
ensures that Apple-specific linker and compiler flags (like `-Wl,-map`
and `-Wimplicit-int-conversion`) are correctly applied when building
on macOS, regardless of the specific compiler used.

Additionally, this commit updates `CMakeLists.txt` to explicitly set
the `CMAKE_AR` and `CMAKE_RANLIB` paths to the default system
locations (`/usr/bin/ar` and `/usr/bin/ranlib`) when the `APPLE`
variable is set.
2026-03-20 13:19:29 -05:00
Jonathan Hui da7a103401 [nexus] add BBR-TC-02 test case for BBR role switch and dataset removal (#12718)
This commit implements the BBR-TC-02 test case in the Nexus simulation
framework to verify that if two BBR Datasets are present in a network,
the Backbone Router (BBR) that is not elected as Primary will delete
its own BBR Dataset from the Network Data.

Key implementation details include:
- Implementation of BBR-TC-02 in C++ simulating a topology with two
  Border Routers (BR_1 as DUT/initial Primary, BR_2) and a Thread
  Router as Leader.
- Verification of BR_1's role switch from Primary to Secondary when it
  detects a BBR Dataset with a higher sequence number (BR_2's dataset).
- Verification that BR_1 sends a Server Data notification to the Leader
  to remove its BBR Dataset upon switching to the Secondary role.
- Verification that BR_1 (as Secondary BBR) correctly rejects MLR.req
  messages with ST_MLR_BBR_NOT_PRIMARY.
- Verification that BR_1 automatically resumes the Primary BBR role
  and becomes Leader when Router_1 and BR_2 are removed from the
  network.
- Addition of a Python verification script to validate:
  - Correct sequence of SVR_DATA.ntf CoAP requests for BBR Dataset
    registration and removal.
  - Correct handling of MLR.req with ST_MLR_BBR_NOT_PRIMARY error.
  - Correct filtering of Thread Network Data TLVs in CoAP payloads.
- Inclusion of the full test specification as inline comments in both
  the C++ and Python files.
- Use of direct core method calls in C++ and adherence to strict
  formatting rules in both files.
- Registration of the new test case in tests/nexus/CMakeLists.txt and
  tests/nexus/run_nexus_tests.sh.
2026-03-18 21:38:56 -05:00
Michael Hopfengaertner a7a7fff00a [cli] remove duplicate and conflicting cli config (#12721)
The cli config `OPENTHREAD_CONFIG_CLI_BLE_SECURE_ENABLE` was
duplicated in `cli_config.h`.
Their default values were even conflicting.

Changes:
* Remove second define of `OPENTHREAD_CONFIG_CLI_BLE_SECURE_ENABLE`
  (default value 0) in `cli_config.h` since it would have never
  been reached.
2026-03-18 21:38:37 -05:00
Yang Song aa2437a313 [cli] prevent ot-ctl termination during debug command (#12600)
Under interactive mode, the `ot-ctl` client treats lines starting with
"Error" as fatal command failures. It exits immediately and stop
receiving CLI output. As the `debug` command runs a sequence of
sub-commands; if one fails , the entire debug session would stop.

This change modifies the error prefix to "ERROR" for internal debug
commands, allowing ot-ctl to continue processing subsequent output.
Also, it adds an explicit `OutputLine("Done")` at the end of the debug
command processing to ensure the CLI client correctly detects the end
of the command.
2026-03-18 19:51:40 -05:00
Jonathan Hui 23caf33af5 [nexus] implement BBR-TC-01 and add infra ICMPv6 echo reply support (#12717)
This commit implements the BBR-TC-01 test case in the Nexus simulation
framework to verify that a Backbone Router (BBR) device automatically
sends its BBR dataset to the Leader if none exists in the network.

To support the Host receiving echo replies on its infrastructure
interface, the Nexus InfraIf class is extended to support custom
ICMPv6 Echo Reply handlers.

Key changes:
- Implement BBR-TC-01 C++ test case and Python verification script.
- Add EchoReplyHandler callback and registration to Nexus InfraIf.
- Update InfraIf::Receive to handle and dispatch ICMPv6 Echo Replies.
- Register 1_2_BBR_TC_1 in CMake and the test runner script.
2026-03-18 19:47:30 -05:00
Abtin Keshavarzian 0db2bade37 [network-diag] simplify MacCountersTlv and its usage (#12711)
This commit simplifies `MacCountersTlv` by replacing its individual
getter and setter methods with bulk operations:
- Adds an `Init()` method that takes a `Mac::Counters` to directly
  populate the TLV fields from the MAC layer counters.
- Adds a `Read()` method to parse the TLV and populate a given
  `NetworkDiagnostic::MacCounters` structure.
- Updates `NetworkDiagnostic::Server` and `Client` to use these new
  methods, allowing the removal of their local helper methods
  `AppendMacCounters()` and `ParseMacCounters()`.
- Introduces `Counters` as an alias for `otMacCounters` within the
  `Mac` namespace.
2026-03-18 19:44:37 -05:00
Jonathan Hui 9e87d67405 [nexus] add MATN-TC-26 test case for mcast reg error handling (#12714)
This commit adds a new nexus test for MATN-TC-26: Multicast
registrations error handling by Thread Device.

The test verifies that a Thread Device correctly handles multicast
registration errors, such as when a Backbone Router (BBR) runs out of
resources or responds with a general failure.

Changes:
- Implemented test_1_2_MATN_TC_26.cpp to execute the test steps.
- Implemented verify_1_2_MATN_TC_26.py to verify pcap output.
- Updated CMakeLists.txt and run_nexus_tests.sh to include the
  new test.
- Modified bbr_manager.cpp to correctly include failed addresses in
  the MLR response when using configured error status for reference
  devices.

The test ensures the DUT retries registration within the
Reregistration Delay after receiving an error and does not retry
if registration was successful until necessary.
2026-03-18 17:54:08 -05:00
Jonathan Hui 8f980e8ba0 [nexus] add MATN-TC-23 test case for automatic MLR re-registration (#12713)
This commit adds a new Nexus test case MATN-TC-23 to verify that a
Thread Device (DUT) automatically re-registers its multicast addresses
before the Multicast Listener Registration (MLR) timeout expires.

The test simulates a topology with two Border Routers (BR_1 and BR_2)
and a Thread Device (TD as DUT). BR_1 acts as the Primary Backbone
Router (BBR) and distributes a BBR Dataset with a configured MLR
timeout. The TD registers a multicast address and then automatically
sends a subsequent MLR.req to renew the registration before the
timeout period ends.

Implementation details:
- Added test_1_2_MATN_TC_23.cpp to execute the simulation using direct
  method calls and 'note' log level.
- Added verify_1_2_MATN_TC_23.py to validate the MLR.req/rsp exchange
  in the pcap output.
- Included the full test specification as inline comments in both
  files, following strict indentation and formatting rules.
- Registered the new test in CMakeLists.txt and run_nexus_tests.sh.
2026-03-18 10:02:30 -05:00
Jonathan Hui 3f908aa5c3 [nexus] add MATN-TC-22 test case for low MLR timeout (#12710)
This commit adds a new Nexus test case MATN-TC-22 to verify that a
Primary Backbone Border Router (BBR) that is configured with a low
value of Multicast Listener Registration (MLR) timeout
(< MLR_TIMEOUT_MIN) is interpreted as using an MLR timeout of
MLR_TIMEOUT_MIN by Thread Devices (DUT).

The test performs the following steps:
- Configures the Primary BBR (BR_1) with an MLR timeout of
  MLR_TIMEOUT_MIN / 4.
- Verifies that the DUT registers a multicast address (MA1) at BR_1.
- Confirms that the DUT automatically re-registers for MA1 within
  MLR_TIMEOUT_MIN seconds of the initial registration.
- Ensures that no more than 2 re-registrations occur within this time
  period.

Included changes:
- New test implementation: test_1_2_MATN_TC_22.cpp.
- New verification script: verify_1_2_MATN_TC_22.py.
- Registration of the test in CMakeLists.txt and run_nexus_tests.sh.

The test implementation uses direct method calls in C++ and provides
step-by-step logging in both C++ and Python to match the test
specification.
2026-03-18 03:09:51 -05:00
Jonathan Hui 640fbc895a [nexus] add MATN-TC-21 test case for incorrect multicast registrations (#12709)
This commit implements the MATN-TC-21 test case in the Nexus
simulation framework to verify that a Primary BBR correctly handles
incorrect or invalid multicast registrations from a Thread device.

Key implementation details include:
- Implementation of MATN-TC-21 in C++ simulating a topology with two
  Border Routers (BR_1 as Primary/DUT, BR_2 as Secondary), a Thread
  Router, and a Host.
- Verification of BR_1's handling of various invalid MLR registrations:
  - Invalid unicast addresses (MAe1, MAe3) or unspecified address (MAe2).
  - Link-local (MA6) and mesh-local (MA5) multicast addresses.
  - Partial registration success when valid (MA1) and invalid (MA6)
    addresses are mixed.
  - Malformed IPv6 Addresses TLV with incorrect length (MAe4).
- Verification that only the Primary BBR (BR_1) accepts registrations,
  while the Secondary BBR (BR_2) returns ST_MLR_BBR_NOT_PRIMARY.
- Addition of a Python verification script to validate:
  - Correct error status codes in MLR responses (ST_MLR_INVALID,
    ST_MLR_BBR_NOT_PRIMARY).
  - Multicast forwarding from backbone to Thread for valid registrations.
  - Handling of malformed TLVs by checking raw CoAP payloads.
- 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.
2026-03-18 01:21:06 -05:00
Jonathan Hui 15c728ed21 [nexus] add MATN-TC-20 test case for automatic re-registration (#12708)
This commit implements the MATN-TC-20 test case in the Nexus
simulation framework to verify that a Parent Router handling a
multicast registration on behalf of an MTD re-registers the
multicast address on behalf of its child before the MLR timeout
expires.

Key implementation details include:
- Implementation of the MATN-TC-20 test scenario in C++ simulating
  a topology with a Router (DUT), a MED, and two Border Routers
  (BR_1 as initial Primary BBR, BR_2 as Secondary BBR).
- Addition of a Python verification script to validate MLE Child
  Update Request/Response exchanges and subsequent MLR.req CoAP
  requests from the DUT to the Primary BBR.
- Verification that the DUT automatically re-registers the multicast
  address when the MLR timeout is updated in the BBR Dataset.
- Inclusion of the full test specification as inline comments in
  both the C++ and Python files, following strict formatting rules.
- Registration of the new test case in tests/nexus/CMakeLists.txt
  and tests/nexus/run_nexus_tests.sh.
2026-03-17 19:44:45 -05:00
Abtin Keshavarzian a0c332b2a2 [ip6] add otIp6Init() to configure external address pools (#12603)
This commit introduces the `OPENTHREAD_CONFIG_IP6_INIT_EXT_ADDR_POOL_ENABLE`
configuration and the `otIp6Init()` API. When enabled, this feature
allows the OpenThread stack to use externally provided memory buffers for
its external unicast and multicast address pools.

By decoupling the pool sizes from build-time configurations
(`OPENTHREAD_CONFIG_IP6_MAX_EXT_UCAST_ADDRS` and
`OPENTHREAD_CONFIG_IP6_MAX_EXT_MCAST_ADDRS`), the OpenThread stack can be
compiled as a generic library without hardcoding the address pool sizes.
It delegates the memory allocation and configuration to the application
layer at run-time.

When the feature is enabled, `otIp6Init()` must be invoked to initialize
the `Netif` address pools before calling `otIp6SetEnabled()`.
2026-03-17 19:24:47 -05:00
Abtin Keshavarzian b28b4a6a5d [network-diag] simplify ChannelPagesTlv and diag data parsing (#12706)
This commit simplifies appending `ChannelPagesTlv` using the standard
`Tlv::Append<>()` with the the array of supported channel pages as
the TLV value.

In addition, a `ReadDiagData()` helper method is introduced in the
`NetworkDiagnostic::Client` to unify and simplify how `otNetworkDiagData`
arrays (e.g. `mNetworkData`, `mChannelPages`) are parsed and populated
from read TLVs.
2026-03-17 18:51:04 -05:00
Abtin Keshavarzian 44f5cddc2e [message] introduce MessageAllocator to unify allocation (#12702)
This commit introduces the `MessageAllocator` template class using the
CRTP pattern to provide a unified implementation of the `NewMessage()`
methods. It standardizes the reserved header sizes for different
message types within `ReservedHeaderSize`. This removes boilerplate
code and redundant `NewMessage()` method implementations across the
`Ip6`, `Icmp`, `Udp`, `Udp::Socket`, and `CoapBase` classes.
2026-03-17 18:50:39 -05:00
Jonathan Hui 422a649919 [nexus] add MATN-TC-19 test case for multicast registration by MTD (#12707)
This commit implements the Thread 1.2 test MATN-TC-19: Multicast
registration by MTD in the Nexus simulation framework. The test
verifies that an MTD can correctly register multicast addresses
through a parent Thread Router and receive multicast traffic from
the backbone.

Key implementation details:
- Created test_1_2_MATN_TC_19.cpp to simulate the network topology
  (BR_1, BR_2, Router, MTD, and Host) and execute the test steps
  using direct method calls.
- Implemented verify_1_2_MATN_TC_19.py for PCAP-based verification
  of MLE Child Update exchanges, MLR registrations, and multicast
  ICMPv6 Echo Request/Reply forwarding.
- Configured the test to use Note log level and included 1-line
  log output for each step to match existing Nexus tests.
- Integrated the new test into the Nexus build system via
  CMakeLists.txt and added it to the default test execution list
  in run_nexus_tests.sh.
2026-03-17 18:05:10 -05:00
Jonathan Hui 7353a38871 [nexus] add MATN-TC-16 test case for large multicast subscriptions (#12705)
This commit adds a new Nexus test case MATN-TC-16 to verify that the
Primary Backbone Border Router (BBR) can handle a large number of
multicast group subscriptions.

The test performs 75 multicast registrations in 5 batches of 15
addresses each. It verifies the following behavior:
- The BBR correctly processes Multicast Listener Registration (MLR)
  requests and returns a success status.
- Multicast packets sent to registered addresses on the backbone are
  successfully forwarded to the Thread network.
- Multicast packets sent to unregistered addresses are not forwarded.

To accommodate the requirements of this test, Nexus configuration
limits are increased:
- OPENTHREAD_CONFIG_IP6_MAX_EXT_MCAST_ADDRS is increased from 4 to 80.
- The mTestVars array in Nexus Core is increased from 16 to 128
  entries to support storing all multicast addresses for verification.

Included changes:
- New test files: test_1_2_MATN_TC_16.cpp and verify_1_2_MATN_TC_16.py.
- Registration of the test in CMakeLists.txt and run_nexus_tests.sh.
- Configuration updates in openthread-core-nexus-config.h and
  nexus_core.hpp.
2026-03-17 09:31:29 -05:00
Jonathan Hui 12aa812cf0 [nexus] add MATN-TC-15 test case for Primary BBR change (#12703)
This commit implements the MATN-TC-15 test case in the Nexus simulation
framework to verify that a Thread End Device detects a change of Primary
Backbone Router (BBR) and triggers a re-registration of its multicast
groups.

Key implementation details include:
- Implementation of MATN-TC-15 in C++ simulating a topology with two
  Border Routers (BR_1 and BR_2), a Thread Router, and a Thread End
  Device (TD as DUT).
- Simulation of Primary BBR failover by stopping BR_1 and waiting for
  BR_2 to become the new Primary BBR.
- Addition of a Python verification script to validate:
  - Detection of Primary BBR change by the DUT.
  - Multicast Listener Registration (MLR.req) sent by the DUT to BR_2.
  - Correct forwarding of MLR.req and MLR.rsp by the intermediate
    Thread Router.
  - Successful registration response (MLR.rsp) from BR_2 to the DUT.
- 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.
2026-03-17 05:09:59 -05:00
Jonathan Hui 244900a49a [nexus] add MATN-TC-12 test case for hop limit processing (#12701)
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.
2026-03-17 03:02:44 -05:00
Jonathan Hui 27d57f9925 [nexus] add MATN-TC-10 test case for BBR dataset distribution (#12697)
This commit implements the MATN-TC-10 test case in the Nexus
simulation framework to verify that a Secondary BBR correctly
takes over forwarding of outbound multicast transmissions when
the Primary BBR fails, specifically focusing on BBR Dataset
distribution and MLDv2/BMLR registration behavior.

Key implementation details include:
- Implementation of the MATN-TC-10 test scenario in C++ simulating
  a topology with two Border Routers (BR_1 as initial Primary,
  BR_2 as Secondary/DUT), a Router, and a Host.
- Verification that BR_2 takes over as the Primary BBR and Leader
  after BR_1 is stopped.
- Validation of BBR Dataset (PBBR) presence in Network Data.
- Addition of a Python verification script to validate:
  - Multicast ping reachability.
  - Correct BBR Dataset distribution.
  - Outbound multicast registration (BMLR/MLDv2) on the backbone.
- Use of explicit multicast re-subscription in Step 14 to ensure
  observable registration traffic within the simulation window.
- Robust packet filters for BMLR (port 61631) and MLDv2 to handle
  platform-specific dissection variances.
- 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.
2026-03-17 00:06:33 -05:00
Jonathan Hui c82664c48f [nexus] add MATN-TC-09 test case for Primary BBR failure (#12696)
This commit implements the MATN-TC-09 test case in the Nexus
simulation framework to verify that a Secondary BBR correctly
takes over forwarding of outbound multicast transmissions when
the Primary BBR fails.

Key implementation details include:
- Implementation of the MATN-TC-09 test scenario in C++ simulating
  a topology with two Border Routers (BR_1 as initial Primary,
  BR_2 as Secondary/DUT) and a Thread Router.
- Verification that BR_2 takes over as the Primary BBR and Leader
  after BR_1 is stopped.
- Addition of a Python verification script to validate that only
  the Primary BBR forwards outbound multicast packets to the
  backbone link.
- Use of distinct ICMPv6 identifiers to reliably distinguish
  between multicast pings sent before and after the Primary BBR
  failure.
- 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.
2026-03-16 22:27:55 -05:00
Jonathan Hui 0f44bd990e [nexus] add MATN-TC-07 test case for BBR multicast forwarding (#12694)
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.
2026-03-16 20:35:22 -05:00
Jonathan Hui 725b101150 [nexus] add MATN-TC-05 test case for multicast re-registration (#12693)
Implement Thread 1.2 test MATN-TC-05: Re-registration to same Multicast
Group. This test verifies that a Primary Backbone Router (BBR)
correctly manages multicast address re-registration and handles UDP
multicast traffic between the backbone and Thread network.

Key additions:
- Added SendUdp to Nexus InfraIf to support simulated UDP multicast
  traffic from backbone hosts.
- Implemented test_1_2_MATN_TC_5.cpp to simulate the network topology
  (DUT, BR_2, Router, and Host) and the test steps.
- Implemented verify_1_2_MATN_TC_5.py for pcap-based verification of
  multicast forwarding and BBR timeout behavior.
- Integrated the new test into the Nexus build system and the default
  test execution script.
2026-03-16 18:57:51 -05:00
Abtin Keshavarzian 0c2148e803 [sntp] simplify message allocation in Client::Query() (#12691)
This commit simplifies how the SNTP request message is allocated and
constructed in `Client::Query()`. It removes the `NewMessage()`
helper method, replacing its use with a direct message allocation from
the socket followed by `Append()` to add the header. It also updates
the error cleanup path to use the `FreeMessage()` macro.
2026-03-16 17:34:13 -05:00
Abtin Keshavarzian 27c6098c2b [locator] fix doc for GetProvider::Get() implementation location (#12690) 2026-03-16 17:33:34 -05:00
Abtin Keshavarzian 0231669620 [ip6] move transport and extension headers to ip6_headers.hpp (#12689)
This commit moves the definitions of `MplOption`, `UdpHeader`,
`TcpHeader`, and `Icmp6Header` from their module-specific headers into
`net/ip6_headers.hpp`. The original class definitions in `Ip6::Udp`,
`Ip6::Tcp`, and `Ip6::Icmp` are replaced with `typedef` aliases to
maintain internal compatibility.

This consolidation centralizes IPv6 protocol header definitions,
ensuring that all header sizes are available when allocating or
cloning messages. This allows for calculating the proper reserved
header length in `NewMessage()`.
2026-03-16 17:33:19 -05:00
Abtin Keshavarzian 3d4812d151 [tests] handle return error value in TCAT unit test (#12685)
This commit updates `tests/unit/test_tcat.cpp` to properly handle the
`Error` return value from `NetworkName::Set()`, resolving compiler
warnings about unhandled return types.

In `TestInitInstanceTcat()`, `IgnoreError()` is used when setting
default test values since `NetworkName::Set()` returns `kErrorNone`
or `kErrorAlready` when the same name is set again.
2026-03-16 17:31:56 -05:00
dependabot[bot] 99e12db7ea github-actions: bump docker/build-push-action from 6.18.0 to 7.0.0 (#12698)
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.18.0 to 7.0.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/263435318d21b8e681c14492fe198d362a7d2c83...d08e5c354a6adb9ed34480a06d141179aa583294)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-16 17:31:25 -05:00
Jonathan Hui 27c7a546d2 [nexus] add MATN-TC-04 test case for multicast listener timeout (#12692)
Add MATN-TC-04 test case to verify that a Primary BBR removes a
multicast listener entry when it expires by timeout.

- Add test_1_2_MATN_TC_4.cpp implementing the simulation of two
  Border Routers (BR_1 as Primary BBR, BR_2), a Router, and a Host.
- Verify that a registered multicast address expires after the
  configured MLR timeout and that the BBR stops forwarding traffic
  to the group.
- Verify that a new registration to the same group is accepted
  after the previous one has expired.
- Use direct method calls for BBR configuration and management.
- Add verify_1_2_MATN_TC_4.py for automated packet verification.
- Fix a loopback issue in nexus_core.cpp where infra-if packets
  were being delivered back to the sender.
- Register the new test case in tests/nexus/CMakeLists.txt and
  tests/nexus/run_nexus_tests.sh.
2026-03-16 16:27:50 -05:00
Jonathan Hui 0d4a43ab8d [nexus] add MATN-TC-03 test case for multicast registration (#12688)
Add MATN-TC-03 test case to verify that a Primary Backbone Router
(BBR) correctly handles Multicast Listener Registration (MLR)
requests and ignores a Timeout TLV when it is not sent by a
Commissioner.

- Add test_1_2_MATN_TC_3.cpp implementing the simulation of two
  Border Routers (BR_1 as Primary BBR, BR_2), a Router, and an
  external Host on the backbone.
- Verify that a Router can successfully register a multicast address.
- Verify that a Router attempting to deregister a multicast address
  by sending an MLR.req with a Timeout TLV of 0 (without a
  Commissioner Session ID) is handled correctly by the PBBR.
- Verify that the PBBR responds with Success and continues to
  forward multicast traffic to the registered address, effectively
  ignoring the invalid Timeout TLV.
- Add verify_1_2_MATN_TC_3.py for automated packet verification of
  the test scenario.
- Register the new test case in tests/nexus/CMakeLists.txt and
  tests/nexus/run_nexus_tests.sh.
2026-03-15 23:24:34 -05:00
Jonathan Hui a904b66b70 [nexus] add MATN-TC-02 test case for multicast registration (#12686)
Add MATN-TC-02 test case to verify Multicast Listener Registration
(MLR) and multicast traffic forwarding between a Thread network and
an infrastructure link (backbone).

- Add test_1_2_MATN_TC_2.cpp implementing the simulation of two
  Border Routers (BR_1 as Primary BBR, BR_2), a Thread Device (TD),
  and an external host on the backbone.
- Verify TD registration of multicast addresses at BR_1 via MLR.req.
- Verify BR_1 responses and backbone notifications (BMLR.ntf).
- Verify successful forwarding of multicast ICMPv6 Echo Requests
  from the backbone to the Thread network by the Primary BBR.
- Verify that non-Primary BBRs and BBRs without active registrations
  do not forward multicast traffic.
- Add verify_1_2_MATN_TC_2.py for automated packet verification of
  the test scenario.
- Register the new test case in tests/nexus/CMakeLists.txt and
  tests/nexus/run_nexus_tests.sh.
2026-03-15 21:42:39 -05:00
Jonathan Hui 4b57531dea [nexus] add MATN-TC-01 test case for multicast blocking (#12687)
Add MATN-TC-01 test case to verify that a Primary BBR by default
blocks IPv6 multicast traffic from the backbone to the Thread
network when no devices have registered for the multicast groups.

- Add test_1_2_MATN_TC_1.cpp implementing the simulation of a
  Border Router (BR_1 as Primary BBR), a Thread Router, and an
  external host on the backbone.
- Send ICMPv6 Echo Requests from the backbone host to various
  multicast addresses (admin-local, site-local, global, and
  link-local).
- Add verify_1_2_MATN_TC_1.py for automated packet verification
  to ensure the DUT (BR_1) does not forward these multicast
  packets to its Thread Network.
- Register the new test case in tests/nexus/CMakeLists.txt and
  tests/nexus/run_nexus_tests.sh.
2026-03-15 19:49:42 -05:00
Jonathan Hui 5df29f74e1 [nexus] implement infra interface for backbone simulation (#12683)
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.
2026-03-15 02:39:57 -05:00
Abtin Keshavarzian 0b7427884e [coap] add SendAckResponseIfUnicastRequest() (#12673)
This commit introduces `CoapBase::SendAckResponseIfUnicastRequest()`,
which sends an ACK response with a CoAP Code mapped from an `Error`
value, provided the original request was confirmable and not sent to
a multicast address. It also adds `Message::MapErrorToCoapCode()` to
handle the translation of common `Error` types into their appropriate
CoAP Code equivalents (e.g., `kErrorBusy` to `kCodeServiceUnavailable`,
or `kErrorParse` to `kCodeBadRequest`).

The TMF handlers in `AnnounceBeginServer`, `EnergyScanServer`, and
`PanIdQueryServer` are updated to use this new method. Additionally,
all three servers now explicitly reject new requests with `kErrorBusy`
if they are already running an active scan or announce operation. The
state tracking in `PanIdQueryServer` (`mIsRunning`) is also added
to correctly check its running state when starting a query.
2026-03-14 07:33:32 -05:00
Abtin Keshavarzian 3d975f7f9d [coap] encapsulate Request state and hide its Metadata (#12675)
This commit updates the `CoapBase::Request` class to encapsulate its
internal state. The `mMessage` pointer and `mMetadata` struct are
now private, and their properties are accessed and modified through
explicit getter and setter methods (e.g., `GetMessage()`,
`IsConfirmable()`, `MarkAsAcknowledged()`).

By doing so, the code that manages pending requests no longer directly
manipulates the internal metadata fields, improving code structure and
maintainability.
2026-03-12 22:50:43 -05:00
Jonathan Hui 6ba23210af [pktverify] add support for raw IPv6 and CoAP TLV parsing (#12678)
Extend the pktverify framework to handle Raw IPv6 packets and parse CoAP
TLVs:

- Add support for verifying Raw IPv6 packets (DLT_RAW) captured on the
  infrastructure link.
- Implement parsing for CoAP TLVs used in Multicast Listener
  Registration (MLR) and Backbone MLR (BMLR) messages.
- Clean up magic numbers and improve summary output for better
  traceability in test reports.
2026-03-12 22:36:57 -05:00
Jonathan Hui 5e6d1af48f [nexus] enhance pcap to support pcapng and multiple interfaces (#12677)
Enhance the Nexus Pcap class to support the pcapng format and logging from
multiple interfaces:

- Transition from pcap to pcapng format to support multiple interface
  descriptions in a single capture file.
- Add support for logging both IEEE 802.15.4 (Thread) and Raw IPv6
  (Backbone) traffic.
- Implement Interface Description Blocks (IDB) and Enhanced Packet
  Blocks (EPB) for pcapng compliance.
2026-03-12 22:36:46 -05:00
Abtin Keshavarzian cf733a331e [infra-if] add missing otInstance parameter to otPlatInfraIf APIs (#12662)
This commit updates the following `otPlatInfraIf` platform APIs to
include an `otInstance *` as their first parameter:

- `otPlatInfraIfHasAddress()`
- `otPlatInfraIfSendIcmp6Nd()`
- `otPlatInfraIfDiscoverNat64Prefix()`

Other APIs under `otPlatInfraIf` already follow this pattern. Passing
the `otInstance` pointer is the required standard for all platform
and public APIs; however, it was missed during the initial design of
these specific APIs.

While missing this parameter is often not a blocker on platforms using
a single OpenThread instance, it has become a blocker for simulations,
especially when multiple Border Routers are emulated in the same
simulation setup.

This change introduces a compatibility break for existing platform
implementations, however, it is necessary to support new use cases
(simulation of BRs). It also helps ensure consistent API design
across the stack.
2026-03-12 10:10:08 -05:00
Abtin Keshavarzian a03011cf73 [tmf] simplify URI paths array using X-Macro (#12674)
This commit simplfies `thread/uri_paths.cpp` by introducing the
`UriEntryMapList` X-Macro. This macro centralizes the mapping
between the URI path string, its `kUri*` enum value and its string
name representation used in `UriToString()`.

By using this macro, we avoid redundant lists and manual template
specializations. The `kEntries[]` array, the compile-time assertions
validating the sorting of the array, and the `UriToString<>()`
template specializations are now all automatically generated from
this single list, improving maintainability and reducing the chance
of mismatches.
2026-03-11 19:37:11 -05:00
Abtin Keshavarzian 7696e38945 [mle] use increasing timeout for child role restoration (#11895)
This change updates the `PrevRoleRestorer` logic to use an increasing
timeout when a non-sleepy device sends `Child Update Request`
messages to restore its previous child role.

The timeout starts at 4 seconds and doubles with each subsequent
retransmission. This strategy is designed to handle scenarios where
the parent may also be restarting, such as after a network-wide power
outage, by allowing more time for the parent to recover. Over four
attempts, the device waits a total of 29 seconds (4 + 8 + 16 + 1)
before abandoning the restoration process.

Sleepy devices continue to use a short and fixed 1-second timeout
between retransmissions.

Additionally, if the restoring child receives a Child Update Request
from its former parent, it switches back to the shorter 1-second
timeout to expedite the restoration process and allow at least
two more Child Update attempts.
2026-03-11 16:21:44 -05:00
Jonathan Hui 69d4282a3f [nexus] update packet capture to pcapng format (#12660)
This commit updates the Nexus test framework to use the pcapng format
for packet capture instead of the legacy pcap format.

The pcapng format provides several advantages over legacy pcap,
most importantly the ability to support multiple interface captures
within a single file. This change prepares the Nexus framework for
more comprehensive border router testing, where capturing traffic
from both the Thread (802.15.4) and infrastructure (Ethernet)
interfaces simultaneously is required.

Changes:
- Implemented Section Header Block (SHB) and Interface Description
  Block (IDB) in Pcap::Open.
- Updated Pcap::WriteFrame to use Enhanced Packet Block (EPB).
- Added proper 32-bit alignment padding for EPB records as required
  by the pcapng specification.
- Updated the test runner script to use the .pcapng extension.
2026-03-11 16:01:32 -05:00
Abtin Keshavarzian b6beeef5b1 [energy-scan] use Tlv::StartTlv() and Tlv::EndTlv() (#12665)
This commit updates `EnergyScanServer` to use `Tlv::StartTlv()` and
`Tlv::EndTlv()` when constructing the Energy List TLV for the report
message. By leveraging a `Tlv::Bookmark` (`mEnergyListTlvBookmark`),
the server no longer needs to manually track the number of scan
results (`mNumScanResults`) and calculate the exact offset to update
the TLV length.

Furthermore, `Tlv::EndTlv()` automatically manages the conversion to
an Extended TLV if the payload size exceeds the maximum length of a
standard TLV (255 bytes).
2026-03-11 15:41:00 -05:00
Abtin Keshavarzian 34856e4d67 [commissioner] simplify energy list parsing in report handler (#12666)
This commit updates `Commissioner::HandleTmf<kUriEnergyReport>()` to
read the energy list data directly into a local array instead of
using a dedicated TLV class.

The report handler now uses `Tlv::FindTlvValueOffsetRange()` to locate
the TLV value, which works correctly whether the TLV is encoded as a
standard or extended TLV. With this change, the `EnergyListTlv` class
definition is replaced with a simple typedef to `TlvInfo`.
2026-03-11 15:36:30 -05:00
Abtin Keshavarzian ea94a2edf6 [network-diag] introduce TlvTypeListIterator (#12672)
This commit introduces a new `TlvTypeListIterator` helper class in
the network diagnostic `Server` to simplify the parsing of Type List
TLVs. This iterator handles deduplication of requested TLV types
using a `BitSet` and centralizes the offset management and iteration
logic.

The iterator is now used in `AppendRequestedTlvs()`,
`AppendRequestedTlvsForTcat()`, `PrepareAndSendAnswers()`, and
`HandleTmf<kUriDiagnosticReset>()`, replacing redundant manual
iteration and deduplication code.

Additionally, the `TypeListTlv` definition is simplified to a
`typedef` of `TlvInfo`, as the dedicated class structure is no
longer needed.
2026-03-11 14:19:41 -05:00
Jonathan Hui e3d03f4f14 [tcplp] fix boundary check in cbuf_reass_write (#12671)
This commit fixes a logic error in the TCP receive buffer reassembly
logic. The issue occurred when an out-of-order segment was exactly
the size of the circular buffer and the write index was non-zero.

The original logic incorrectly used modulo-wrapped indices to check
if a write should be contiguous or split:
start_index + numbytes % size. When numbytes == size, end_index ==
start_index, which evaluates to true, leading to an incorrect memory
write if start_index > 0.

This commit updates the check to use the absolute write boundary:
if (start_index + numbytes <= chdr->size). This ensures that any
write spanning the buffer boundary is correctly split.

A regression test test_cbuf_reass_boundary is added to test_all.c
to verify the fix and prevent future regressions. The test Makefile
is also updated to use $(CC) for better portability.
2026-03-11 14:04:02 -05:00
Jonathan Hui edd387d04e [coap] enhance CoAP option parsing validation and robustness (#12670)
This commit improves the robustness of CoAP option parsing by adding
rigorous validation checks to prevent potential overflows and null
pointer dereferences.

Summary of changes:
1. In 'ReadExtendedOptionField()', added an overflow check when
   calculating extended lengths for 2-byte extensions. It now returns
   'kErrorParse' if the value would exceed the 16-bit range.
2. In 'ReadBlockOptionValues()', added a check to ensure the block
   option exists before accessing it. This prevents a crash when
   'GetOption()' returns null.
3. In 'ReadBlockOptionValues()', added length validation to ensure the
   option value does not exceed the local buffer size (5 bytes) before
   copying.
4. Added a new unit test 'test_coap_overflow' to verify these validation
   checks and ensure they correctly handle malformed or missing options.
2026-03-11 14:03:42 -05:00
Jonathan Hui 3390085720 [lowpan] limit recursion depth in 6LoWPAN decompression (#12669)
This commit introduces a maximum recursion depth limit for 6LoWPAN
decompression to prevent potential stack exhaustion from maliciously
crafted frames with deep IPv6-in-IPv6 encapsulation.

- Added a private constant kMaxRecursionDepth in the Lowpan
  class to define the maximum allowed recursion depth.
- Updated Lowpan::Decompress() to track and validate the current
  recursion depth, returning kErrorParse if the limit is exceeded.
- Added a new unit test TestLowpanDecompressRecursion in
  tests/unit/test_lowpan.cpp to verify the recursion limit and
  ensure it correctly handles both excessive and legitimate
  encapsulation levels.
2026-03-11 14:03:29 -05:00
Abtin Keshavarzian 3e3690a068 [ip6] simplify multicast forwarding logic in DetermineAction() (#12653)
This commit simplifies and updates `Ip6::DetermineAction()` regarding
how the `aForwardThread` flag is determined for multicast messages
with a scope larger than realm-local.

Such messages are sent using IP-in-IP encapsulation destined to the
`RealmLocalAllMplForwarders` address. Both the encapsulated
(outer) and embedded (inner) messages are processed. When processing
the embedded IPv6 message, regardless of its origin, we only need to
forward it to the Thread mesh if the device has a sleepy child
subscribed to the multicast address. `MeshForwarder::SendMessage()`
on an FTD will then check for these subscriptions and schedule
indirect transmissions to those children.

The behavior for FTDs remains functionally the same as before, though
the code has been refactored to be clearer and easier to follow.

The primary change applies to MTDs: if the multicast destination scope
is larger than realm-local, the message is no longer forwarded to
Thread, as an MTD cannot have any children to support.
2026-03-11 13:10:45 -05:00
Abtin Keshavarzian b988a07525 [commissioner] clean up member variable and type formatting (#12667)
This commit reorganizes the member variables in the `Commissioner`
class, ordering them to optimize memory packing. Additionally, it
shortens the local typedef names for callback function pointers, such
as renaming `otCommissionerEnergyReportCallback` to the more concise
`EnergyReportCallback`, improving overall readability. Finally, it
aligns parameter formatting in method signatures like
`SendEnergyScanQuery()` and `SendPanIdQuery()`.
2026-03-11 13:09:34 -05:00
Abtin Keshavarzian dad25dc5b5 [energy-scan] protect server state on allocation failure (#12664)
This commit updates `EnergyScanServer::HandleTmf<kUriEnergyScan>()`
to use a local `OwnedPtr<Coap::Message>` when allocating and preparing
the initial energy report message. Previously, the method directly
modified `mReportMessage`, potentially leaving the object in an
inconsistent state or leaking memory if subsequent `Append()` operations
failed and exited early.

By building the message in a local `newMessage` first and only taking
ownership using `PassOwnership()` after all operations succeed, we
ensure the server's internal state remains consistent.
2026-03-11 13:08:49 -05:00
Abtin Keshavarzian 039819699a [coap] flatten Receive() and ProcessReceivedResponse() (#12663)
This commit updates the `CoapBase::Receive()` and
`CoapBase::ProcessReceivedResponse()` methods to utilize early returns
via `ExitNow()` and `VerifyOrExit()`. By doing so, it flattens the
nested conditional logic and improves the overall readability of the
code.

As a result of this change in `CoapBase::Receive()`, an invalid
message that fails CoAP header parsing will exit early, correctly
skipping the `Utils::Otns::EmitCoapReceive()` signal.
2026-03-10 22:12:36 -05:00
Abtin Keshavarzian 3559cbd55a [tmf] validate method as POST centrally in resource handlers (#12661)
This commit updates the central CoAP resource handlers in TMF agents
(`Agent::HandleResource`, `BackboneTmfAgent::HandleResource`, and
`Manager::CoapDtlsSession::HandleResource`) to verify that the
incoming request method is a POST request. If the URI is recognized
but the method is not POST, a `kCodeMethodNotAllowed` response is
now sent.

Since all TMF requests are now guaranteed to be POST requests before
reaching their specific handlers, the `IsPostRequest()` checks in
individual handlers are removed. Additionally, the
`IsConfirmablePostRequest()` and `IsNonConfirmablePostRequest()`
helper methods in `Coap::Message` are removed and their usages are
simplified to `IsConfirmable()` and `IsNonConfirmable()` in the
respective handlers.
2026-03-10 22:07:43 -05:00
Jonathan Hui d9fce062c7 [tests] remove Cert_8_1, Cert_8_2, and Cert_8_3 thread-cert tests (#12659)
This commit removes several thread-cert Python tests that are now
covered by the Nexus test framework. Nexus provides more efficient
and reliable testing for these scenarios.

The following tests are removed:
- Cert_8_1_01_Commissioning.py
- Cert_8_1_02_Commissioning.py
- Cert_8_1_06_Commissioning.py
- Cert_8_2_01_JoinerRouter.py
- Cert_8_2_02_JoinerRouter.py
- Cert_8_2_05_JoinerRouter.py
- Cert_8_3_01_CommissionerPetition.py
2026-03-10 16:58:42 -05:00
Yang Song 2af789cafa [border-agent] fix the ConstructServiceName function name typo (#12655) 2026-03-10 11:34:17 -05:00
Jonathan Hui cf9bfb9df9 [nexus] add test 1.1.8.2.2 for on-mesh commissioner joining (#12652)
This commit adds Nexus test 1.1.8.2.2, "On Mesh Commissioner Joining
with JR, any commissioner, single (incorrect)". This test verifies
that the Commissioner correctly handles a relayed DTLS handshake
from a Joiner using an incorrect PSKd.

The test verifies that:
- The Joiner, Joiner Router, and Commissioner correctly exchange
  relayed DTLS handshake records (ClientHello, HelloVerifyRequest,
  ServerHello, etc.) via RLY_RX.ntf and RLY_TX.ntf messages.
- The Commissioner detects the incorrect PSKd after receiving the
  Client Finished message.
- The Commissioner responds with a DTLS-Alert (handshake failure
  or bad record MAC) relayed through the Joiner Router via a
  RLY_TX.ntf message.
- The session is correctly terminated without fatal alerts before
  the expected handshake failure.

Changes:
- Added tests/nexus/test_1_1_8_2_2.cpp to implement the test logic,
  using direct internal method calls and note-level logging.
- Added tests/nexus/verify_1_1_8_2_2.py to verify the captured
  pcap traffic, adhering to specified formatting and fail conditions.
- Updated tests/nexus/CMakeLists.txt and tests/nexus/run_nexus_tests.sh
  to include the new test.
2026-03-10 10:35:52 -05:00
Jonathan Hui e9d3acbac8 [nexus] add test 1.1.8.3.1 for commissioner petitioning and keep-alive (#12648)
This commit adds Nexus test 1.1.8.3.1, "On Mesh Commissioner -
Commissioner Petitioning, Commissioner Keep-alive messaging, Steering
Data Updating and Commissioner Resigning". This test verifies that
a Commissioner Candidate can register itself to the network, send
periodic keep-alive messages, update steering data, and unregister
itself.

The test verifies that:
- The Commissioner correctly sends a LEAD_PET.req to the Leader.
- The Leader responds with a LEAD_PET.rsp and propagates
  Commissioning Data in its Network Data.
- The Commissioner sends periodic LEAD_KA.req messages to maintain
  its active state.
- The Commissioner can update Steering Data via a
  MGMT_COMMISSIONER_SET.req message, and the Leader correctly
  propagates this update in the Network Data.
- The Commissioner can unregister itself by sending a LEAD_KA.req
  with a Reject state, which the Leader accepts.
- The Leader increments the Commissioner Session ID when a new
  Commissioner session is started.

Changes:
- Added tests/nexus/test_1_1_8_3_1.cpp to implement the test logic,
  using direct internal method calls and note-level logging.
- Added tests/nexus/verify_1_1_8_3_1.py to verify the captured
  pcap traffic, following specified formatting and verification rules.
- Updated tests/nexus/CMakeLists.txt and tests/nexus/run_nexus_tests.sh
  to include the new test.
2026-03-09 20:04:59 -05:00
Jonathan Hui 8b9d39cdbf [github-actions] remove android-ndk platform and CI job (#12654)
This commit removes the `android-ndk` platform support from the
`script/cmake-build` script and deletes the associated CI job from
the GitHub Actions workflow.

The `android-ndk` build was used to verify OpenThread compatibility
with the Android NDK. However, since OpenThread is now officially
included in the Android platform, maintaining a separate NDK-based
build in this repository is no longer necessary.

Changes:
- Remove `android-ndk` from `OT_PLATFORMS` in `script/cmake-build`.
- Remove NDK-specific configuration logic in `script/cmake-build`.
- Remove the `android-ndk` job from `.github/workflows/build.yml`.
2026-03-09 20:04:35 -05:00
dependabot[bot] 95e8ae0bdf github-actions: bump docker/login-action from 3.7.0 to 4.0.0 (#12657)
Bumps [docker/login-action](https://github.com/docker/login-action) from 3.7.0 to 4.0.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/c94ce9fb468520275223c153574b00df6fe4bcc9...b45d80f862d83dbcd57f89517bcf500b2ab88fb2)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: 4.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-09 19:57:58 -05:00
Abtin Keshavarzian 47c633516b [coap] simplify CoapBase::SendMessage() (#12650)
This commit simplifies `CoapBase::SendMessage()` by updating how
outgoing requests are processed and added to the pending request
queue.

The logic to determine the clone length (full message for
confirmable, header only for non-confirmable), initialize request
metadata, and process observe options is moved from `SendMessage()`
into the updated `PendingRequests::Add()` method (previously
`AddClone()`). This encapsulates the request preparation logic
closer to where the request is queued.
2026-03-09 19:49:55 -05:00
Abtin Keshavarzian a663a1c192 [coap] update GetType() to return Type enum instead of uint8_t (#12649)
Update the `GetType()` methods to return the `Type` enumeration
instead of a raw `uint8_t`. This improves type safety and clarifies
the return type for callers. The `mType` member variable is also
updated from `uint8_t` to `Type`.

Generally, when parsing header fields, we do not map the value directly
to an `enum` since the enum may not cover all possible values present in
a received header. However, in this case, the `Type` field in the CoAP
header is a 2-bit value, and all four possible values are explicitly
defined and accounted for in the `Type` enumeration. Therefore, we can
safely cast the read bits to the `Type` enum.
2026-03-09 19:49:29 -05:00
Abtin Keshavarzian b79a6cfc8b [coap] rename and clarify response sending methods (#12647)
This commit updates several method names in `CoapBase` to better align
with RFC 7252 terminology and clarify their behavior.

Previously, the term "empty" was used ambiguously to mean either a
message with Code 0.00 (`kCodeEmpty`) or a message that lacked a
payload but contained a response code. For example, `SendEmptyAck()`
sent an ACK (`kTypeAck`) message that actually contained a non-zero
response code (e.g., `kCodeChanged`), which is a "response" message
per the RFC, not an "empty" message.

To address this:

- `SendReset()` and `SendAck()` are removed in favor of using
  `SendEmptyMessage()` directly with `kTypeReset` or `kTypeAck`.
  This restricts the use of "Empty" strictly to Code 0.00 messages.
- `SendHeaderResponse()` is renamed to `SendResponse()` to clarify
  that it dynamically sends a response without a payload.
- `SendEmptyAck()` is renamed to `SendAckResponse()` to indicate it
  sends a piggybacked ACK `kTypeAck` response without a payload.
- `SendNotFound()` is replaced with a direct call to `SendResponse()`
  using `kCodeNotFound`.
- Documentation comments for these methods are updated to explain
  their purpose and requirements clearly.
- Callers across the core modules are updated to use the new method
  names.
2026-03-09 19:49:05 -05:00
Jonathan Hui 86bc9435ba [nexus] add test 1.1.8.2.1 for on-mesh commissioner joining (#12645)
This commit adds Nexus test 1.1.8.2.1, "On Mesh Commissioner Joining
with JR, any commissioner, single (correct)". This test verifies that
the Joiner Router (DUT) correctly relays DTLS traffic between a Joiner
and an on-mesh Commissioner via RLY_RX.ntf and RLY_TX.ntf messages. It
also verifies that the JOIN_ENT.ntf message is encrypted with the KEK.

Changes:
- Added tests/nexus/test_1_1_8_2_1.cpp to implement the test logic,
  including DTLS key exporting for traffic decryption.
- Added tests/nexus/verify_1_1_8_2_1.py to verify the captured traffic
  using pktverify, ensuring correct relaying and encryption.
- Updated tests/nexus/verify_utils.py to support parsing Joiner-related
  CoAP TLVs (DTLS Encap, UDP Port, IID, Locator, KEK) and to handle
  16-bit TLV lengths.
- Integrated the test into the build system and test runner via
  tests/nexus/CMakeLists.txt and tests/nexus/run_nexus_tests.sh.
2026-03-08 15:39:28 -05:00
Jonathan Hui 1b43fe6694 [nexus] add test 1.1.8.1.6 for On-Mesh Commissioner Joining (Reject) (#12643)
This commit adds Nexus test 1.1.8.1.6, "On-Mesh Commissioner Joining,
no JR, wrong Commissioner". This test verifies that an on-mesh
Commissioner correctly rejects a Joiner when the Provisioning URL in
the JOIN_FIN.req message is not recognized.

The test verifies the following sequence:
- Successful MLE Discovery and DTLS handshake between Joiner and
  Commissioner.
- Joiner sends a JOIN_FIN.req containing an unrecognized
  Provisioning URL.
- Commissioner responds with a JOIN_FIN.rsp with Reject state.
- Commissioner sends an encrypted JOIN_ENT.ntf message.
- Joiner responds with an encrypted JOIN_ENT.ntf dummy response.
- Joiner terminates the DTLS session with a close_notify alert.

Changes include:
- Implemented C++ test logic in tests/nexus/test_1_1_8_1_6.cpp.
- Implemented Python verification logic in tests/nexus/verify_1_1_8_1_6.py.
- Configured DTLS key exporting in the test to allow decryption and
  verification of CoAP messages in tshark.
- Updated tests/nexus/CMakeLists.txt and tests/nexus/run_nexus_tests.sh
  to include the new test.
2026-03-07 19:11:02 -06:00
Jonathan Hui f2c98f46f7 [nexus] add test 1.1.8.1.2 for On-Mesh Commissioner Joining (incorrect) (#12642)
This commit adds Nexus test 1.1.8.1.2, "On-Mesh Commissioner Joining,
no JR, any commissioner, single (incorrect)". This test verifies that
the DUT (on-mesh Commissioner) correctly detects and handles a Joiner
using an incorrect PSKd.

The test verifies that:
- The Commissioner and Joiner correctly perform the initial DTLS
  handshake up to the Client Finished message.
- The Commissioner detects the incorrect PSKd used by the Joiner.
- The Commissioner responds with a DTLS Alert (handshake failure or
  bad record MAC) and terminates the session.

Changes include:
- Implemented C++ test logic in tests/nexus/test_1_1_8_1_2.cpp.
- Implemented Python verification logic in tests/nexus/verify_1_1_8_1_2.py,
  which uses exported DTLS keys to decrypt and verify the handshake.
- Added code to export DTLS session keys from the Joiner node to
  facilitate decryption of the Finished record in tshark.
- Added the new test to tests/nexus/CMakeLists.txt and
  tests/nexus/run_nexus_tests.sh.
2026-03-06 19:10:57 -06:00
Abtin Keshavarzian c62646fc0d [coap] rename low-level Send() to Transmit() in CoapBase (#12635)
This commit renames the low-level `Send()` method in `CoapBase` to
`Transmit()` to clearly differentiate it from the higher-level message
construction and scheduling logic of `SendMessage()`. The `Sender`
function pointer type and member have also been renamed to
`Transmitter` and `mTransmitter`, respectively, to align with the new
terminology.

Using `Transmit()` clearly communicates the action of handing off a
fully prepared CoAP datagram to the underlying transport layer for
transmission, resolving the naming ambiguity with `SendMessage()`.
This establishes a symmetric "Transmit/Receive" boundary between the
CoAP layer and the transport layer.
2026-03-06 17:27:00 -06:00
Jonathan Hui 74d28d7e61 [nexus] fix flakiness in test 1.1.8.1.1 (#12646)
This commit addresses occasional failures in Nexus Test 1.1.8.1.1 by
improving simulation timing and packet verification robustness.

Changes:
- Increased kJoiningProcessTime from 30s to 60s in the C++ test to
  provide a larger buffer for the joiner process to complete.
- Added a 1s delay after calling AddJoinerAny() to ensure the leader
  processes the steering data update before discovery starts.
- Refactored the Python verification script to use pkts.copy() for
  independent message exchanges (JOIN_ENT and DTLS Alert). This
  allows the script to handle timing variations and out-of-order
  packets in the simulated capture.
- Corrected the NM_PROVISIONING_URL_TLV constant to 32.
- Added dtls.alert_message.level to the pktverify library to enable
  verification of DTLS alert severity levels.
2026-03-06 17:19:30 -06:00
Jonathan Hui 4d959556e3 [nexus] fix intermittent failure in test 1.2.LP.5.3.2 (#12644)
This test was occasionally failing due to tight timing constraints.
The wait times after SSED-initiated messages were too short, causing
the CSL timer age verification to fail if the message delivery took
longer than expected.

This commit increases the wait times from 500ms to 1000ms and relaxes
the allowed CSL timer age in the verification helper to match.
2026-03-06 15:29:20 -06:00
Jonathan Hui 2a41d7de40 [nexus] add test 1.1.8.1.1 for On-Mesh Commissioner Joining (#12637)
This commit adds Nexus test 1.1.8.1.1, "On-Mesh Commissioner Joining, no
JR, any commissioner, single (correct)". This test verifies the MLE
discovery, DTLS handshake, and CoAP message exchange between an on-mesh
Commissioner and a Joiner.

Changes include:
- Enhanced MeshCoP::SecureTransport to support DTLS key exporting by
  adding a KeylogCallback and SetKeylogCallback method.
- Exposed HandleMbedtlsExportKeys as a public method in
  SecureTransport to facilitate key logging.
- Refactored SecureTransport to use named constants for internal
  buffer sizes and avoid magic numbers.
- Implemented C++ test logic in tests/nexus/test_1_1_8_1_1.cpp which
  uses the new key logging callback to save DTLS keys to a file.
- Implemented Python verification logic in
  tests/nexus/verify_1_1_8_1_1.py which uses the exported keys to
  decrypt and verify the captured network traffic.
- Used named constants and helper classes (e.g. Time) in the test
  implementation and verification script to improve readability and
  maintainability.
- Added the new test to tests/nexus/CMakeLists.txt and
  tests/nexus/run_nexus_tests.sh.
2026-03-06 14:36:14 -06:00
Jonathan Hui 0740bff909 [tests] migrate low power and 1.2 tests to nexus (#12641)
This commit removes several legacy Python-based certification tests for
Low Power (CSL) and Thread 1.2 features, as they have been migrated to
the Nexus test framework.

Specifically, the following tests and their associated CI workflows
(including packet verification for low power) are removed:
- CSL Transmission and Timeout
- Enhanced Frame Pending and Keep-Alive
- Single Probe and Forward Tracking Series Link Metrics
- SSED Attachment and Parent Selection

The removal of these scripts from tests/scripts/thread-cert/ and
the corresponding GitHub Action workflows reduces CI overhead while
maintaining coverage through the more scalable Nexus tests.
2026-03-06 14:35:51 -06:00
Jonathan Hui 9080e827d8 [tests] fix race condition in Nexus Test 1.1.5.6.2 (#12640)
The packet verification script for Nexus Test 1.1.5.6.2 occasionally
failed because it expected a CoAP ACK followed by an MLE Data Response
in a specific order. Since both packets are triggered by the same
Server Data Notification event, their relative order in the PCAP can
vary.

This commit updates the script to use `pkts.copy()` when searching for
the CoAP ACK. This allows the verification to find the ACK regardless
of whether it appears before or after the MLE Data Response, making
the test more robust.
2026-03-06 13:10:24 -06:00
Jonathan Hui bbff1b461e [pktverify] update pyshark to 0.6 and fix Nexus test verification (#12636)
This commit updates the pyshark dependency to version 0.6 and adapts the
packet verification logic to accommodate changes in pyshark's internal
API and field mapping.

Specifically, this commit:
- Updates requirements.in and requirements.txt to pyshark 0.6.
- Adjusts pktverify and Nexus utility scripts to use the restructured
  pyshark API, importing BaseLayer from pyshark.packet.layers.base
  instead of the deprecated pyshark.packet.layer.Layer.
- Updates verify_1_2_LP_5_3_8.py to utilize wpan.channel for channel
  filtering instead of wpan_tap.ch_num, ensuring consistency with other
  Nexus tests and improving verification reliability.
2026-03-06 12:57:59 -06:00
Jonathan Hui 406496f4de [nexus] implement test 1.2.LP.7.2.2 for Forward Series Probing (#12626)
This commit implements Nexus test 1.2.LP.7.2.2 to verify that the
DUT (Leader) can successfully support a minimum of 6 simultaneous
children (3 SEDs and 3 SSEDs) performing link metrics operations.

Specifically, the test verifies that:
- The DUT correctly handles simultaneous Forward Series Link Metrics
  Management Requests and Enhanced ACK probing requests.
- The DUT properly aggregates metrics for multiple concurrent series
  with different configurations (MAC Data Requests, Link Layer data
  frames, LQI, RSSI, and Link Margin).
- Aggregated results are accurately reported in MLE Data Responses
  when queried by multiple children.
- The DUT successfully provides link metrics in Enhanced ACKs for
  both SED and SSED children.

Changes:
- Added test_1_2_LP_7_2_2.cpp to implement the test logic, including
  node configuration, management requests, and data collection.
- Added verify_1_2_LP_7_2_2.py for automated PCAP verification of
  MLE TLVs and Enhanced ACK Vendor IEs.
- Updated verify_utils.py to include necessary layer fields for
  Link Metrics verification in pktverify.
- Registered the new test in CMakeLists.txt and run_nexus_tests.sh.
2026-03-06 09:36:01 -06:00
Abtin Keshavarzian 0887643bff [coap] simplify URI path parsing in block-wise requests (#12634)
This commit simplifies the handling of URI paths during the processing
of block-wise CoAP requests, effectively removing duplicated code.

Previously, `CoapBase::ProcessBlockwiseRequest()` manually iterated
through CoAP options to parse and construct the URI path string. This
logic was redundant as the same functionality is provided by the
`Message::ReadUriPathOptions()` method.

By calling `ReadUriPathOptions()` earlier in the request processing flow
within `CoapBase::ProcessReceivedRequest()`, we can populate the
`uriPath` string buffer and simply pass it down. Consequently, the
`aUriPath` parameter in `ProcessBlockwiseRequest()` has been updated to
a `const Message::UriPathStringBuffer &` to reflect its new role as a
read-only input. This change leads to cleaner, more cohesive code.
2026-03-06 00:48:18 -06:00
Abtin Keshavarzian a34ad8c153 [otns] use Coap::Message::UriPathStringBuffer in EmitCoapStatus (#12633)
This commit updates the `Otns::EmitCoapStatus()` method to use the
`Coap::Message::UriPathStringBuffer` typedef for the `uriPath` local
variable, replacing an explicit character array definition. This
improves code consistency and matches the expected parameter type of
the `Coap::Message::ReadUriPathOptions()` method.
2026-03-06 00:46:33 -06:00
Abtin Keshavarzian b69463d248 [github] move nexus core and trel tests to nexus workflow (#12631)
This commit moves the execution of nexus `core` and `trel` tests from
the `toranj.yml` GitHub Actions workflow to the `nexus.yml` workflow.
It separates the tests into dedicated jobs (`nexus-core-tests` and
`nexus-trel-tests`) to improve parallelism and organization. The
existing nexus test job is also renamed to `nexus-cert-tests` to
better reflect its purpose.
2026-03-06 00:45:45 -06:00
Abtin Keshavarzian ce5a59fef3 [coap] add new AllocateAndInitPostMessageTo() helper methods (#12630)
This commit introduces `AllocateAndInitPostMessageTo()` and
`AllocateAndInitPriorityPostMessageTo()` methods in `CoapBase`.
These methods simplify the creation of CoAP POST messages by combining
the allocation, initialization, and appending of the payload marker
into a single call. The message type (Confirmable vs. Non-Confirmable)
is automatically determined based on whether the destination address
is multicast.

The previous `InitAsPost()` method in `Coap::Message` is removed,
and all callers in `BbrManager`, `Commissioner`, and
`AddressResolver` are updated to use the new helper methods.
2026-03-06 00:45:02 -06:00
Esko Dijk 9b663f384e [tcat] Update TCAT Commissioner authorization checks; add unit tests (#12182) (#12182)
Updates the TCAT class public methods for doing Commissioner
authorization checks and clarifies the code, with minor updates to
PSKc cases handling.

Unit tests are added for checking Commissioner authorization. To do
these checks, a new test class UnitTester is added which has access to
private members of the TcatAgent class.  Validation/mock functions are
added in the test code to keep the unit tests readable.

Also reverts the CommCert4 fix that was made in #12151.

For more background information see JIRA BHC-766.
2026-03-06 00:28:02 -06:00
Jonathan Hui a3c69b03cc [nexus] implement test 1.2.LP.7.2.1 for Forward Tracking Series (#12624)
This commit implements Nexus test 1.2.LP.7.2.1 to validate the Forward
Tracking Series Link Metrics functionality.

Specifically, the test verifies that:
- The DUT (Leader) correctly handles Forward Series Link Metrics
  Management Requests from SED and SSED children.
- The DUT properly aggregates metrics for Forward Series (MAC Data
  Requests for SED, all data frames for SSED).
- Aggregated results are accurately reported in MLE Data Responses
  when queried.
- Forward Series can be successfully cleared, and unknown Series IDs
  result in appropriate error statuses.

Summary of changes:
- Created test_1_2_LP_7_2_1.cpp to implement the test logic.
- Created verify_1_2_LP_7_2_1.py for automated packet verification.
- Updated verify_utils.py to include MLE TLV field definitions for
  Link Metrics (e.g., forward series, flags, query ID).
- Registered the new test in tests/nexus/CMakeLists.txt and
  tests/nexus/run_nexus_tests.sh.
2026-03-06 00:22:31 -06:00
Jonathan Hui 4b754e03ba [nexus] implement test 1.2.LP.7.1.2 for Link Metrics (#12623)
This commit implements Nexus test 1.2.LP.7.1.2, which validates the
Single Probe Link Metrics without Enhanced ACKs functionality.

The test verifies that:
- The DUT (Leader) successfully responds to Single Probe Link Metrics
  Requests from SED and SSED children using MLE Data Requests.
- The DUT correctly reports RSSI, Layer 2 LQI, and Link Margin metrics
  in MLE Data Responses.
- The DUT reports different RSSI values when the transmission power
  (simulated via MAC filter) is varied.

Changes:
- Add test_1_2_LP_7_1_2.cpp to implement the test logic using the
  Nexus simulation platform.
- Add verify_1_2_LP_7_1_2.py for automated packet verification,
  ensuring Link Metrics Query and Report TLVs are correctly formatted.
- Register the new test in tests/nexus/CMakeLists.txt.
- Add the test to the default test list in tests/nexus/run_nexus_tests.sh.
2026-03-05 22:16:40 -06:00
Jonathan Hui af3e9cc7b8 [nexus] implement test 1.2.LP.7.1.1 for Link Metrics (#12622)
This commit implements Nexus test 1.2.LP.7.1.1, which validates the
Single Probe Link Metrics with Enhanced ACKs functionality.

The test verifies that:
- The DUT (Leader) successfully responds to Link Metrics Management
  Requests from SED and SSED children.
- The DUT includes correct Link Metrics data in IEEE 802.15.4-2015
  Enhanced ACKs when requested.
- The DUT correctly handles registration, clearing, and error cases
  for Link Metrics configurations.

Changes:
- Add test_1_2_LP_7_1_1.cpp to implement the test logic using the
  Nexus simulation platform.
- Add verify_1_2_LP_7_1_1.py for automated packet verification,
  ensuring Link Metrics TLVs and Enhanced ACKs are correctly formatted.
- Register the new test in tests/nexus/CMakeLists.txt.
- Add the test to the default test list in tests/nexus/run_nexus_tests.sh.
2026-03-05 20:13:02 -06:00
Jonathan Hui 553931bd31 [nexus] implement test 1.2.LP.5.2.1 for Enhanced Frame Pending (#12632)
This commit implements and verifies Nexus test case 1.2.LP.5.2.1, which
validates that the Leader (DUT) correctly manages the Frame Pending bit
in acknowledgments to MAC Data and Data Request frames for Thread V1.2
and V1.1 sleepy end devices.

Key changes:
- Created tests/nexus/test_1_2_LP_5_2_1.cpp to simulate the test
  topology (Leader, Router_1, SED_1, SED_2, SED_3) and execution steps.
- Implemented tests/nexus/verify_1_2_LP_5_2_1.py to perform automated
  packet verification of the test criteria.
- Integrated the new test into CMakeLists.txt and run_nexus_tests.sh.
- Used AllowList to specify links between nodes as per the test spec.
- Set log level to note and used direct method calls in C++.
- Verified that the DUT sets the Frame Pending bit correctly in ACKs
  based on whether indirect messages are queued for the SEDs.
2026-03-05 20:12:48 -06:00
988 changed files with 92259 additions and 35491 deletions
@@ -1,6 +1,5 @@
#!/usr/bin/env python3
#
# Copyright (c) 2022, The OpenThread Authors.
# Copyright (c) 2026, The OpenThread Authors.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -27,12 +26,24 @@
# POSSIBILITY OF SUCH DAMAGE.
#
import unittest
from v1_2_LowPower_5_3_01_SSEDAttachment import LowPower_5_3_01_SSEDAttachment
from v1_2_LowPower_5_3_01_SSEDAttachment import LEADER
LowPower_5_3_01_SSEDAttachment.TOPOLOGY[LEADER]['is_otbr'] = True
if __name__ == '__main__':
unittest.main()
changelog:
exclude:
labels:
- duplicate
- question
- invalid
- wontfix
authors:
- dependabot[bot]
categories:
- title: "🚀 Features"
labels:
- feature
- enhancement
- title: "🐛 Bug Fixes"
labels:
- bug
- fix
- title: "📖 Documentation"
labels:
- documentation
+19 -43
View File
@@ -49,7 +49,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
@@ -73,13 +73,16 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Run linkspector
uses: umbrelladocs/action-linkspector@652f85bc57bb1e7d4327260decc10aa68f7694c3 # v1.4.0
uses: umbrelladocs/action-linkspector@963b6264d7de32c904942a70b488d3407453049e # v1.5.1
env:
PUPPETEER_EXECUTABLE_PATH: /usr/bin/google-chrome
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
reporter: github-pr-review
@@ -89,7 +92,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
@@ -108,7 +111,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
@@ -148,7 +151,7 @@ jobs:
CXX: ${{ matrix.compiler_cpp }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
@@ -167,7 +170,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
@@ -186,7 +189,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
@@ -238,9 +241,12 @@ jobs:
- gcc_ver: 14
gcc_download_url: https://developer.arm.com/-/media/Files/downloads/gnu/14.2.rel1/binrel/arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-eabi.tar.xz
gcc_extract_dir: arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-eabi
- gcc_ver: 15
gcc_download_url: https://developer.arm.com/-/media/Files/downloads/gnu/15.2.rel1/binrel/arm-gnu-toolchain-15.2.rel1-x86_64-arm-none-eabi.tar.xz
gcc_extract_dir: arm-gnu-toolchain-15.2.rel1-x86_64-arm-none-eabi
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
@@ -273,7 +279,7 @@ jobs:
CXX: g++-${{ matrix.gcc_ver }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
@@ -306,7 +312,7 @@ jobs:
CXX: clang++-${{ matrix.clang_ver }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
@@ -329,7 +335,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
@@ -360,7 +366,7 @@ jobs:
CXX: ${{ matrix.CXX }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
@@ -376,33 +382,3 @@ jobs:
run: |
script/check-posix-build
script/check-simulation-build
android-ndk:
name: android-ndk
runs-on: ubuntu-24.04
container:
image: openthread/environment
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
- name: Install unzip
run: apt update && apt install -y unzip
- name: Setup NDK
id: setup-ndk
uses: nttld/setup-ndk@afb4c9964b521afb97c864b7d40b11e6911bd410 # v1.5.0
with:
ndk-version: r25c
local-cache: true
- name: Build
env:
NDK: ${{ steps.setup-ndk.outputs.ndk-path }}
run: |
rm -rf build/ && OT_CMAKE_NINJA_TARGET="ot-daemon ot-ctl" script/cmake-build android-ndk
rm -rf build/ && OT_CMAKE_NINJA_TARGET="ot-cli" script/cmake-build android-ndk
+3 -3
View File
@@ -54,7 +54,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
@@ -67,7 +67,7 @@ jobs:
sudo apt-get --no-install-recommends install -y ninja-build libreadline-dev libncurses-dev
- name: Initialize CodeQL
uses: github/codeql-action/init@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10
uses: github/codeql-action/init@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -81,6 +81,6 @@ jobs:
./script/test build
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10
uses: github/codeql-action/analyze@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4
with:
category: "/language:${{matrix.language}}"
+9 -9
View File
@@ -61,7 +61,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
@@ -83,18 +83,18 @@ jobs:
- name: Login to Docker Hub
if: success() && github.repository == 'openthread/openthread' && github.event_name != 'pull_request'
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
- name: Build and push by digest
if: success()
id: build
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
with:
file: etc/docker/environment/Dockerfile
platforms: ${{ matrix.platform }}
@@ -111,7 +111,7 @@ jobs:
- name: Upload digest
if: success() && github.repository == 'openthread/openthread' && github.event_name != 'pull_request'
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: digests-${{ env.PLATFORM_PAIR }}
path: ${{ runner.temp }}/digests/*
@@ -125,25 +125,25 @@ jobs:
- build
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
- name: Download digests
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
path: ${{ runner.temp }}/digests
pattern: digests-*
merge-multiple: true
- name: Login to Docker Hub
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
- name: Docker meta
id: meta
+3 -3
View File
@@ -53,7 +53,7 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
@@ -75,7 +75,7 @@ jobs:
output-sarif: true
- name: Upload Crash
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: failure() && steps.build.outcome == 'success'
with:
name: ${{ matrix.sanitizer }}-artifacts
@@ -83,7 +83,7 @@ jobs:
- name: Upload Sarif
if: always() && steps.build.outcome == 'success'
uses: github/codeql-action/upload-sarif@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10
uses: github/codeql-action/upload-sarif@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4
with:
sarif_file: cifuzz-sarif/results.sarif
checkout_path: cifuzz-sarif
+2 -2
View File
@@ -48,7 +48,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
@@ -63,7 +63,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
+89
View File
@@ -0,0 +1,89 @@
#
# 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.
#
name: Monthly CalVer Release
on:
schedule:
# Runs at 00:00 UTC on the 1st day of every month
- cron: '0 0 1 * *'
# Allows you to trigger the workflow manually from the GitHub Actions UI
workflow_dispatch:
inputs:
tag_override:
description: 'Custom Tag Name (e.g., v2026.05.1). Leave blank for auto CalVer.'
required: false
type: string
jobs:
create-release:
name: Create Monthly Release
runs-on: ubuntu-24.04
# Required permission to create tags and releases
permissions:
contents: write
steps:
- name: Harden Runner
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: block
allowed-endpoints: >
api.github.com:443
github.com:443
- name: Checkout repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
- name: Generate CalVer Tag Name
id: generate_tag
env:
TAG_OVERRIDE: ${{ inputs.tag_override }}
# Formats the date as vYYYY.MM.0 (e.g., v2026.06.0) or uses override if provided
run: |
if [ -n "$TAG_OVERRIDE" ]; then
CALVER_TAG="$TAG_OVERRIDE"
else
CALVER_TAG="v$(date +'%Y.%m').0"
fi
echo "TAG_NAME=$CALVER_TAG" >> $GITHUB_ENV
echo "Generated tag: $CALVER_TAG"
- name: Create GitHub Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Uses the built-in GitHub CLI to create the tag and release simultaneously
run: |
gh release create "$TAG_NAME" \
--target "${{ github.ref_name }}" \
--title "OpenThread $TAG_NAME" \
--generate-notes
+137 -2
View File
@@ -45,14 +45,18 @@ permissions:
jobs:
nexus-tests:
nexus-cert-tests:
name: nexus-cert-tests
runs-on: ubuntu-24.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit
- name: Free Disk Space (Ubuntu)
uses: jlumbroso/free-disk-space@main
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
@@ -72,3 +76,134 @@ jobs:
- name: Run Nexus Tests
run: |
top_builddir=build/nexus ./tests/nexus/run_nexus_tests.sh
nexus-core-tests:
name: nexus-core-tests
runs-on: ubuntu-24.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
- name: Free Disk Space (Ubuntu)
uses: jlumbroso/free-disk-space@main
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
- name: Bootstrap
env:
PR_BODY: "${{ github.event.pull_request.body }}"
run: |
sudo apt-get update
sudo apt-get --no-install-recommends install -y ninja-build lcov
- name: Build Nexus
run: |
mkdir -p build/nexus
top_builddir=build/nexus ./tests/nexus/build.sh
- name: Run Core Tests
run: |
cd build/nexus && ctest -L core --output-on-failure
- name: Run TREL Tests
run: |
cd build/nexus && ctest -L trel --output-on-failure
nexus-long-routes-tests:
name: nexus-long-routes-tests
runs-on: ubuntu-24.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
- name: Free Disk Space (Ubuntu)
uses: jlumbroso/free-disk-space@main
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
- name: Bootstrap
env:
PR_BODY: "${{ github.event.pull_request.body }}"
run: |
sudo apt-get update
sudo apt-get --no-install-recommends install -y ninja-build lcov
- name: Build Nexus
run: |
mkdir -p build/nexus
top_builddir=build/nexus ./tests/nexus/build.sh long_routes
- name: Run LONG_ROUTES Tests
run: |
cd build/nexus && ctest -L long_routes --output-on-failure
nexus-grpc-tests:
name: nexus-grpc-tests
runs-on: ubuntu-24.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit
- name: Free Disk Space (Ubuntu)
uses: jlumbroso/free-disk-space@main
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
- name: Bootstrap
run: |
sudo apt-get update
sudo apt-get --no-install-recommends install -y ninja-build libgrpc++-dev libprotobuf-dev protobuf-compiler-grpc
- name: Build Nexus
run: |
mkdir -p build/nexus
OT_NEXUS_GRPC=ON top_builddir=build/nexus ./tests/nexus/build.sh
- name: Run GRPC Tests
run: |
cd build/nexus && ./tests/nexus/nexus_grpc
nexus-wasm-tests:
name: nexus-wasm-tests
runs-on: ubuntu-24.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit
- name: Free Disk Space (Ubuntu)
uses: jlumbroso/free-disk-space@main
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
- name: Bootstrap
run: |
sudo apt-get update
sudo apt-get --no-install-recommends install -y ninja-build
- name: Set up Emscripten
uses: mymindstorm/setup-emsdk@v14
- name: Build Nexus WASM
run: |
mkdir -p build/nexus
top_builddir=build/nexus ./tests/nexus/build.sh wasm
- name: Run WASM Smoke Test
run: |
node tests/nexus/test_wasm_bindings.mjs build/nexus/tests/nexus/nexus_live_demo.js
+91
View File
@@ -0,0 +1,91 @@
#
# 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.
#
name: OTBR DinD
on:
push:
branches-ignore:
- 'dependabot/**'
pull_request:
branches:
- 'main'
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || (github.repository == 'openthread/openthread' && github.run_id) || github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
dind-dns-sd:
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
mdns: ["", "--mdnsresponder"]
env:
PR_BODY: "${{ github.event.pull_request.body }}"
steps:
- name: Harden Runner
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
- name: Clone ot-br-posix and replace openthread submodule
run: |
OPENTHREAD_DIR=$(pwd)
./script/git-tool clone https://github.com/openthread/ot-br-posix.git --depth 1 --recurse-submodules --shallow-submodules /tmp/ot-br-posix
cd /tmp/ot-br-posix
rm -rf third_party/openthread/repo
mkdir -p third_party/openthread/repo
rsync -r --exclude=.git --exclude=build --exclude=ot_testing "${OPENTHREAD_DIR}/." third_party/openthread/repo
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
- name: Build DinD Runner Image
run: |
cd /tmp/ot-br-posix
docker build -t otbr-dind-runner -f etc/docker/test/Dockerfile.dind_runner .
- name: Run DinD Integration Test
run: |
cd /tmp/ot-br-posix
docker run --privileged --rm \
-v /tmp/ot-br-posix:/usr/src/ot-br-posix \
-w /usr/src/ot-br-posix \
-e DOCKER_HOST=unix:///var/run/docker.sock \
otbr-dind-runner \
bash -c "dockerd --host=unix:///var/run/docker.sock >/dev/null 2>&1 & ./tests/scripts/test_dind_dns_sd.sh ${{ matrix.mdns }}"
+5 -93
View File
@@ -45,74 +45,6 @@ permissions:
jobs:
backbone-router:
runs-on: ubuntu-22.04
env:
REFERENCE_DEVICE: 1
VIRTUAL_TIME: 0
TEST_TIMEOUT: 1800
PACKET_VERIFICATION: 1
THREAD_VERSION: 1.4
INTER_OP: 1
COVERAGE: 1
MULTIPLY: 1
PYTHONUNBUFFERED: 1
VERBOSE: 1
# The Border Routing and DUA feature can coexist, but current wireshark
# packet verification can't handle it because of the order of context ID
# of OMR prefix and Domain prefix is not deterministic.
BORDER_ROUTING: 0
DISCOVERY_PROXY: 0
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
- name: Build OTBR Docker
env:
PR_BODY: "${{ github.event.pull_request.body }}"
run: |
./script/test build_otbr_docker
- name: Bootstrap
run: |
sudo rm /etc/apt/sources.list.d/* && sudo apt-get update
sudo apt-get --no-install-recommends install -y python3-setuptools python3-wheel ninja-build lcov
sudo bash script/install_socat
python3 -m pip install -r tests/scripts/thread-cert/requirements.txt
- name: Build
run: |
./script/test build
- name: Get Thread-Wireshark
run: |
./script/test get_thread_wireshark
- name: Run
run: |
export CI_ENV="$(bash <(curl -s https://codecov.io/env)) -e GITHUB_ACTIONS -e COVERAGE"
echo "CI_ENV=${CI_ENV}"
sudo -E ./script/test cert_suite ./tests/scripts/thread-cert/backbone/*.py || (sudo chmod a+r ot_testing/* && false)
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: cov-thread-1-3-backbone-docker
path: /tmp/coverage/
retention-days: 1
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
if: ${{ failure() }}
with:
name: thread-1-3-backbone-results
path: |
ot_testing/*.pcap
ot_testing/*.json
ot_testing/*.log
ot_testing/coredump_*
ot_testing/otbr-agent_*
- name: Generate Coverage
run: |
./script/test generate_coverage gcc
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: cov-thread-1-3-backbone
path: tmp/coverage.info
retention-days: 1
thread-border-router:
runs-on: ubuntu-22.04
strategy:
@@ -137,31 +69,12 @@ jobs:
packet_verification: 1
nat64: 0
description: "MATN"
- otbr_mdns: "mDNSResponder"
otbr_trel: 0
cert_scripts: ./tests/scripts/thread-cert/border_router/LowPower/*.py
packet_verification: 1
nat64: 0
description: "LowPower"
- otbr_mdns: "mDNSResponder"
otbr_trel: 0
cert_scripts: ./tests/scripts/thread-cert/border_router/internet/*.py
packet_verification: 1
nat64: 1
description: "internet access"
- otbr_mdns: "avahi"
otbr_trel: 0
cert_scripts: ./tests/scripts/thread-cert/border_router/*.py
packet_verification: 1
nat64: 0
description: ""
- otbr_mdns: "avahi"
otbr_trel: 0
cert_scripts: ./tests/scripts/thread-cert/border_router/*.py
packet_verification: 1
nat64: 0
use_core_firewall: 1
description: "core-firewall"
name: BR ${{ matrix.description }} (${{ matrix.otbr_mdns }}, TREL=${{matrix.otbr_trel}})
env:
REFERENCE_DEVICE: 1
@@ -209,12 +122,12 @@ jobs:
export CI_ENV="$(bash <(curl -s https://codecov.io/env)) -e GITHUB_ACTIONS -e COVERAGE"
echo "CI_ENV=${CI_ENV}"
sudo -E ./script/test cert_suite ${{ matrix.cert_scripts }} || (sudo chmod a+r ot_testing/* && false)
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: cov-br-docker-${{ matrix.description }}-${{ matrix.otbr_mdns }}-${{matrix.otbr_trel}}
path: /tmp/coverage/
retention-days: 1
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: ${{ failure() }}
with:
name: br-results-${{ matrix.description }}-${{ matrix.otbr_mdns }}-${{matrix.otbr_trel}}
@@ -227,7 +140,7 @@ jobs:
- name: Generate Coverage
run: |
./script/test generate_coverage gcc
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: cov-br-${{ matrix.description }}-${{ matrix.otbr_mdns }}-${{matrix.otbr_trel}}
path: tmp/coverage.info
@@ -235,7 +148,6 @@ jobs:
upload-coverage:
needs:
- backbone-router
- thread-border-router
runs-on: ubuntu-22.04
steps:
@@ -245,7 +157,7 @@ jobs:
- name: Bootstrap
run: |
sudo apt-get --no-install-recommends install -y lcov
- uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
path: coverage/
pattern: cov-*
@@ -256,7 +168,7 @@ jobs:
script/test combine_coverage
- name: Upload Coverage
continue-on-error: true
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
with:
+2 -2
View File
@@ -58,7 +58,7 @@ jobs:
REAL_DEVICE: 0
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
@@ -80,7 +80,7 @@ jobs:
PYTHONPATH=./tests/scripts/thread-cert pytype tools/otci
- name: Build
run: |
./script/cmake-build simulation -DOT_THREAD_VERSION=1.4 -DOT_DUA=ON -DOT_MLR=ON -DOT_BACKBONE_ROUTER=ON \
./script/cmake-build simulation -DOT_THREAD_VERSION=1.4 -DOT_MLR=ON -DOT_BACKBONE_ROUTER=ON \
-DOT_CSL_RECEIVER=ON -DOT_SIMULATION_VIRTUAL_TIME=${VIRTUAL_TIME}
- name: Install OTCI Python Library
run: |
+13 -13
View File
@@ -58,14 +58,14 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with:
go-version: "1.23"
- name: Set up Python
@@ -84,7 +84,7 @@ jobs:
cd /tmp/otns
./script/test py-unittests
)
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: ${{ failure() }}
with:
name: unittests-pcaps
@@ -94,7 +94,7 @@ jobs:
- name: Generate Coverage
run: |
./script/test generate_coverage gcc
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: cov-otns-unittests
path: tmp/coverage.info
@@ -107,7 +107,7 @@ jobs:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with:
go-version: "1.23"
- name: Set up Python
@@ -126,7 +126,7 @@ jobs:
cd /tmp/otns
./script/test py-examples
)
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: ${{ failure() }}
with:
name: examples-pcaps
@@ -136,7 +136,7 @@ jobs:
- name: Generate Coverage
run: |
./script/test generate_coverage gcc
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: cov-otns-examples
path: tmp/coverage.info
@@ -164,14 +164,14 @@ jobs:
STRESS_LEVEL: ${{ matrix.stress_level }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with:
go-version: "1.23"
- name: Set up Python
@@ -190,7 +190,7 @@ jobs:
cd /tmp/otns
./script/test stress-tests ${{ matrix.suite }}
)
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: ${{ failure() }}
with:
name: stress-tests-${{ matrix.suite }}-pcaps
@@ -200,7 +200,7 @@ jobs:
- name: Generate Coverage
run: |
./script/test generate_coverage gcc
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: cov-otns-stress-tests-${{ matrix.suite }}
path: tmp/coverage.info
@@ -214,7 +214,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
@@ -224,7 +224,7 @@ jobs:
- name: Bootstrap
run: |
sudo apt-get --no-install-recommends install -y lcov
- uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
path: coverage/
pattern: cov-*
+15 -61
View File
@@ -52,7 +52,7 @@ jobs:
CXXFLAGS: -DCLI_COAP_SECURE_USE_COAP_DEFAULT_HANDLER=1 -DOPENTHREAD_CONFIG_MLE_MAX_CHILDREN=15
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
@@ -83,7 +83,7 @@ jobs:
CRASHED=$(./script/test check_crash | tail -1)
[[ $CRASHED -eq "1" ]] && echo "Crashed!" || echo "Not crashed."
echo "CRASHED_RCP=$CRASHED" >> $GITHUB_ENV
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: ${{ failure() && env.CRASHED_RCP == '1' }}
with:
name: core-expect-rcp
@@ -92,7 +92,7 @@ jobs:
- name: Generate Coverage
run: |
./script/test generate_coverage gcc
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: cov-expects-linux-1
path: tmp/coverage.info
@@ -117,13 +117,13 @@ jobs:
CRASHED=$(./script/test check_crash | tail -1)
[[ $CRASHED -eq "1" ]] && echo "Crashed!" || echo "Not crashed."
echo "CRASHED_TUN=$CRASHED" >> $GITHUB_ENV
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: ${{ failure() && env.CRASHED_TUN == '1' }}
with:
name: core-expect-linux
path: |
./ot-core-dump/*
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: ${{ failure() }}
with:
name: syslog-expect-linux
@@ -131,57 +131,12 @@ jobs:
- name: Generate Coverage
run: |
./script/test generate_coverage gcc
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: cov-expects-linux-2
path: tmp/coverage.info
retention-days: 1
thread-cert:
runs-on: ubuntu-22.04
env:
COVERAGE: 1
PYTHONUNBUFFERED: 1
THREAD_VERSION: 1.1
VIRTUAL_TIME: 1
OT_VT_USE_UNIX_SOCKET: 1
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: '3.12'
cache: pip
- name: Bootstrap
run: |
sudo apt-get update
sudo apt-get --no-install-recommends install -y lcov ninja-build
python3 -m pip install -r tests/scripts/thread-cert/requirements.txt
- name: Build
run: |
OT_NODE_TYPE=rcp ./script/test build
- name: Run
run: |
MAX_JOBS=$(getconf _NPROCESSORS_ONLN) ./script/test cert_suite ./tests/scripts/thread-cert/Cert_*.py ./tests/scripts/thread-cert/test_*.py
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
if: ${{ failure() }}
with:
name: thread-cert
path: ot_testing
- name: Generate Coverage
run: |
./script/test generate_coverage gcc
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: cov-thread-cert
path: tmp/coverage.info
pty-linux:
name: pty-linux OT_DAEMON=${{ matrix.OT_DAEMON }}
runs-on: ubuntu-24.04
@@ -195,7 +150,7 @@ jobs:
OT_READLINE: 'readline'
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
@@ -230,7 +185,7 @@ jobs:
- name: Generate Coverage
run: |
./script/test generate_coverage gcc
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: cov-pty-linux-${{ matrix.OT_DAEMON }}
path: tmp/coverage.info
@@ -241,7 +196,7 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
@@ -271,7 +226,7 @@ jobs:
OT_READLINE: 'off'
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
@@ -304,7 +259,7 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
@@ -327,7 +282,7 @@ jobs:
- name: Generate Coverage
run: |
./script/test generate_coverage gcc
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: cov-rcp-stack-reset
path: tmp/coverage.info
@@ -337,11 +292,10 @@ jobs:
needs:
- expects-linux
- pty-linux
- thread-cert
runs-on: ubuntu-22.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
@@ -351,7 +305,7 @@ jobs:
- name: Bootstrap
run: |
sudo apt-get --no-install-recommends install -y lcov
- uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
path: coverage/
pattern: cov-*
@@ -360,7 +314,7 @@ jobs:
run: |
script/test combine_coverage
- name: Upload Coverage
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
with:
+2 -2
View File
@@ -87,7 +87,7 @@ jobs:
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v3.1.0
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v3.1.0
with:
name: SARIF file
path: results.sarif
@@ -95,6 +95,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v2.1.27
uses: github/codeql-action/upload-sarif@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v2.1.27
with:
sarif_file: results.sarif
-472
View File
@@ -1,472 +0,0 @@
#
# Copyright (c) 2020, 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.
#
name: Simulation 1.1
on:
push:
branches-ignore:
- 'dependabot/**'
pull_request:
branches:
- 'main'
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || (github.repository == 'openthread/openthread' && github.run_id) || github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
packet-verification:
runs-on: ubuntu-24.04
env:
PACKET_VERIFICATION: 1
REFERENCE_DEVICE: 1
THREAD_VERSION: 1.1
VIRTUAL_TIME: 1
TEST_TIMEOUT: 300
OT_VT_USE_UNIX_SOCKET: 1
MULTIPLY: 3
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: '3.12'
cache: pip
- name: Bootstrap
run: |
sudo apt-get update
sudo apt-get --no-install-recommends install -y ninja-build lcov
python3 -m pip install -r tests/scripts/thread-cert/requirements.txt
- name: Build
run: |
./script/test build
- name: Get Thread-Wireshark
run: |
./script/test get_thread_wireshark
- name: Run
run: |
./script/test cert_suite ./tests/scripts/thread-cert/Cert_*.py ./tests/scripts/thread-cert/test_*.py
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
if: ${{ failure() }}
with:
name: packet-verification-pcaps
path: |
*.pcap
*.json
- name: Generate Coverage
run: |
./script/test generate_coverage gcc
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: cov-packet-verification
path: tmp/coverage.info
retention-days: 1
cli-ftd:
runs-on: ubuntu-24.04
env:
CFLAGS: -m32
CXXFLAGS: -m32
LDFLAGS: -m32
COVERAGE: 1
REFERENCE_DEVICE: 1
THREAD_VERSION: 1.1
VIRTUAL_TIME: 1
TEST_TIMEOUT: 300
OT_VT_USE_UNIX_SOCKET: 1
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: '3.12'
cache: pip
- name: Bootstrap
run: |
sudo apt-get update
sudo apt-get --no-install-recommends install -y lcov ninja-build g++-multilib
python3 -m pip install -r tests/scripts/thread-cert/requirements.txt
- name: Build
run: |
./script/test build
- name: Run
run: |
./script/test cert_suite ./tests/scripts/thread-cert/Cert_*.py ./tests/scripts/thread-cert/test_*.py
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
if: ${{ failure() }}
with:
name: cli-ftd-thread-cert
path: ot_testing
- name: Generate Coverage
run: |
./script/test generate_coverage gcc
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: cov-cli-ftd
path: tmp/coverage.info
retention-days: 1
cli-mtd:
name: cli-mtd MESSAGE_USE_HEAP=${{ matrix.message_use_heap }}
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
message_use_heap: [0, 1]
env:
CFLAGS: -m32
CXXFLAGS: -m32
LDFLAGS: -m32
COVERAGE: 1
REFERENCE_DEVICE: 1
THREAD_VERSION: 1.1
USE_MTD: 1
VIRTUAL_TIME: 1
TEST_TIMEOUT: 300
OT_VT_USE_UNIX_SOCKET: 1
MESSAGE_USE_HEAP: ${{ matrix.message_use_heap }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: '3.12'
cache: pip
- name: Bootstrap
run: |
sudo apt-get update
sudo apt-get --no-install-recommends install -y lcov ninja-build g++-multilib
python3 -m pip install -r tests/scripts/thread-cert/requirements.txt
- name: Build
run: |
./script/test build
- name: Run
run: |
./script/test cert_suite ./tests/scripts/thread-cert/Cert_*.py ./tests/scripts/thread-cert/test_*.py
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
if: ${{ failure() }}
with:
name: cli-mtd-thread-cert
path: ot_testing
- name: Generate Coverage
run: |
./script/test generate_coverage gcc
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: cov-cli-mtd-${{ matrix.message_use_heap }}
path: tmp/coverage.info
retention-days: 1
cli-time-sync:
runs-on: ubuntu-24.04
env:
CFLAGS: -m32
CXXFLAGS: -m32
LDFLAGS: -m32
COVERAGE: 1
REFERENCE_DEVICE: 1
THREAD_VERSION: 1.1
VIRTUAL_TIME: 1
TEST_TIMEOUT: 300
OT_VT_USE_UNIX_SOCKET: 1
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: '3.12'
cache: pip
- name: Bootstrap
run: |
sudo apt-get update
sudo apt-get --no-install-recommends install -y g++-multilib lcov ninja-build
python3 -m pip install -r tests/scripts/thread-cert/requirements.txt
- name: Build
run: |
OT_OPTIONS="-DOT_TIME_SYNC=ON" ./script/test build
- name: Run
run: |
./script/test cert_suite ./tests/scripts/thread-cert/Cert_*.py ./tests/scripts/thread-cert/test_*.py
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
if: ${{ failure() }}
with:
name: cli-time-sync-thread-cert
path: ot_testing
- name: Generate Coverage
run: |
./script/test generate_coverage gcc
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: cov-cli-time-sync
path: tmp/coverage.info
retention-days: 1
expects:
runs-on: ubuntu-24.04
env:
CFLAGS: -DCLI_COAP_SECURE_USE_COAP_DEFAULT_HANDLER=1 -DOPENTHREAD_CONFIG_MLE_MAX_CHILDREN=15
CXXFLAGS: -DCLI_COAP_SECURE_USE_COAP_DEFAULT_HANDLER=1 -DOPENTHREAD_CONFIG_MLE_MAX_CHILDREN=15
THREAD_VERSION: 1.1
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: '3.12'
cache: pip
- name: Bootstrap
run: |
sudo apt-get --no-install-recommends install -y expect ninja-build lcov
sudo bash script/install_socat
pip install bleak 'cryptography==43.0.0'
- name: Run
run: |
ulimit -c unlimited
./script/test prepare_coredump_upload
OT_OPTIONS='-DOT_TIME_SYNC=ON -DOT_FULL_LOGS=ON -DOT_LOG_OUTPUT=PLATFORM_DEFINED' VIRTUAL_TIME=0 ./script/test build expect
- name: Check Crash
if: ${{ failure() }}
run: |
CRASHED=$(./script/test check_crash | tail -1)
[[ $CRASHED -eq "1" ]] && echo "Crashed!" || echo "Not crashed."
echo "CRASHED_CLI=$CRASHED" >> $GITHUB_ENV
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
if: ${{ failure() && env.CRASHED_CLI == '1' }}
with:
name: core-expect-cli
path: |
./ot-core-dump/*
- name: Generate Coverage
run: |
./script/test generate_coverage gcc
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: cov-expects
path: tmp/coverage.info
retention-days: 1
ot-commissioner:
runs-on: ubuntu-24.04
env:
THREAD_VERSION: 1.1
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: '3.12'
cache: pip
- name: Bootstrap
env:
PR_BODY: "${{ github.event.pull_request.body }}"
run: |
sudo apt-get update
sudo apt-get install -y avahi-daemon avahi-utils lcov
script/git-tool clone https://github.com/openthread/ot-commissioner.git /tmp/ot-commissioner --depth 1 --branch main
- name: Build
run: |
cd /tmp/ot-commissioner
script/bootstrap.sh
cmake -GNinja \
-DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DCMAKE_CXX_STANDARD=11 \
-DCMAKE_CXX_STANDARD_REQUIRED=ON \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr/local \
-DOT_COMM_COVERAGE=ON \
-DOT_COMM_CCM=OFF \
-S . -B build
cmake --build build
sudo cmake --install build
- name: Run
run: |
export OT_COMM_OPENTHREAD="$(pwd)"
cd /tmp/ot-commissioner/tests/integration
./bootstrap.sh
./run_tests.sh
- name: Generate Coverage
run: |
./script/test generate_coverage gcc
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: cov-ot-commissioner
path: tmp/coverage.info
retention-days: 1
multiple-instance:
runs-on: ubuntu-24.04
env:
COVERAGE: 1
THREAD_VERSION: 1.1
VIRTUAL_TIME: 1
TEST_TIMEOUT: 300
OT_VT_USE_UNIX_SOCKET: 1
CXXFLAGS: "-DOPENTHREAD_CONFIG_LOG_PREPEND_UPTIME=0"
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: '3.12'
cache: pip
- name: Bootstrap
run: |
sudo apt-get --no-install-recommends install -y lcov ninja-build
python3 -m pip install -r tests/scripts/thread-cert/requirements.txt
- name: Build
run: |
OT_OPTIONS="-DOT_MULTIPLE_INSTANCE=ON" ./script/test build
- name: Run
run: |
./script/test cert_suite ./tests/scripts/thread-cert/Cert_*.py ./tests/scripts/thread-cert/test_*.py
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
if: ${{ failure() }}
with:
name: ot_testing
path: build/simulation/tests/scripts/thread-cert
- name: Generate Coverage
run: |
./script/test generate_coverage gcc
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: cov-multiple-instance
path: tmp/coverage.info
retention-days: 1
simulation-local-host:
runs-on: ubuntu-24.04
env:
COVERAGE: 1
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
- name: Bootstrap
run: |
sudo apt-get --no-install-recommends install -y expect ninja-build lcov
- name: Run
run: |
./script/check-simulation-local-host
- name: Generate Coverage
run: |
./script/test generate_coverage gcc
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: cov-simulation-local-host
path: tmp/coverage.info
retention-days: 1
upload-coverage:
needs:
- packet-verification
- cli-ftd
- cli-mtd
- cli-time-sync
- expects
- ot-commissioner
- multiple-instance
runs-on: ubuntu-22.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
- name: Bootstrap
run: |
sudo apt-get --no-install-recommends install -y lcov
- uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
with:
path: coverage/
pattern: cov-*
merge-multiple: true
- name: Combine Coverage
run: |
script/test combine_coverage
- name: Upload Coverage
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
with:
files: final.info
fail_ci_if_error: true
-458
View File
@@ -1,458 +0,0 @@
#
# Copyright (c) 2020, 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.
#
name: Simulation 1.4
on:
push:
branches-ignore:
- 'dependabot/**'
pull_request:
branches:
- 'main'
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || (github.repository == 'openthread/openthread' && github.run_id) || github.ref }}
cancel-in-progress: true
permissions: # added using https://github.com/step-security/secure-workflows
contents: read
jobs:
thread-1-4:
name: thread-1-4-${{ matrix.compiler.c }}-${{ matrix.arch }}
runs-on: ubuntu-22.04
env:
CFLAGS: -${{ matrix.arch }}
CXXFLAGS: -${{ matrix.arch }}
LDFLAGS: -${{ matrix.arch }}
COVERAGE: 1
THREAD_VERSION: 1.4
VIRTUAL_TIME: 1
TEST_TIMEOUT: 300
OT_VT_USE_UNIX_SOCKET: 1
INTER_OP: 1
INTER_OP_BBR: 1
CC: ${{ matrix.compiler.c }}
CXX: ${{ matrix.compiler.cxx }}
strategy:
fail-fast: false
matrix:
compiler: [{c: "gcc", cxx: "g++", gcov: "gcc"}, { c: "clang", cxx: "clang++", gcov: "llvm"}]
arch: ["m32", "m64"]
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: '3.12'
cache: pip
- name: Bootstrap
run: |
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get --no-install-recommends install -y ninja-build llvm lcov
sudo apt-get --no-install-recommends install -y g++-multilib libreadline-dev:i386 libncurses-dev:i386
python3 -m pip install -r tests/scripts/thread-cert/requirements.txt
- name: Build
run: |
./script/test build
- name: Run
run: |
ulimit -c unlimited
./script/test prepare_coredump_upload
./script/test unit
./script/test cert_suite tests/scripts/thread-cert/v1_2_*
- name: Check Crash
if: ${{ failure() }}
run: |
CRASHED=$(./script/test check_crash | tail -1)
[[ $CRASHED -eq "1" ]] && echo "Crashed!" || echo "Not crashed."
echo "CRASHED=$CRASHED" >> $GITHUB_ENV
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
if: ${{ failure() }}
with:
name: thread-1-4-${{ matrix.compiler.c }}-${{ matrix.arch }}-pcaps
path: "*.pcap"
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
if: ${{ failure() && env.CRASHED == '1' }}
with:
name: core-packet-verification-thread-1-4
path: |
./ot-core-dump/*
- name: Generate Coverage
run: |
./script/test generate_coverage "${{ matrix.compiler.gcov }}"
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: cov-thread-1-4-${{ matrix.compiler.c }}-${{ matrix.arch }}
path: tmp/coverage.info
retention-days: 1
packet-verification-low-power:
runs-on: ubuntu-24.04
env:
REFERENCE_DEVICE: 1
VIRTUAL_TIME: 1
TEST_TIMEOUT: 300
OT_VT_USE_UNIX_SOCKET: 1
COVERAGE: 1
PACKET_VERIFICATION: 1
THREAD_VERSION: 1.4
MAC_FILTER: 1
INTER_OP: 1
INTER_OP_BBR: 0
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: '3.12'
cache: pip
- name: Bootstrap
run: |
sudo apt-get update
sudo apt-get --no-install-recommends install -y ninja-build lcov
python3 -m pip install -r tests/scripts/thread-cert/requirements.txt
- name: Build
run: |
./script/test build
- name: Build with OT_CSL_RECEIVER_LOCAL_TIME_SYNC
run: |
OT_BUILDDIR="${PWD}/build_csl_receiver_local_time_sync" OT_OPTIONS="-DOT_CSL_RECEIVER_LOCAL_TIME_SYNC=ON" ./script/test build
- name: Get Thread-Wireshark
run: |
./script/test get_thread_wireshark
- name: Run
run: |
ulimit -c unlimited
./script/test prepare_coredump_upload
for i in {1..10}
do
./script/test cert_suite ./tests/scripts/thread-cert/v1_2_LowPower*.py
done
- name: Run with OT_CSL_RECEIVER_LOCAL_TIME_SYNC
run: |
OT_BUILDDIR="${PWD}/build_csl_receiver_local_time_sync" ./script/test cert_suite ./tests/scripts/thread-cert/v1_2_LowPower*.py
- name: Check Crash
if: ${{ failure() }}
run: |
CRASHED=$(./script/test check_crash | tail -1)
[[ $CRASHED -eq "1" ]] && echo "Crashed!" || echo "Not crashed."
echo "CRASHED=$CRASHED" >> $GITHUB_ENV
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
if: ${{ failure() }}
with:
name: packet-verification-low-power-pcaps
path: |
*.pcap
*.json
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
if: ${{ failure() && env.CRASHED == '1' }}
with:
name: core-packet-verification-low-power
path: |
./ot-core-dump/*
- name: Generate Coverage
run: |
./script/test generate_coverage gcc
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: cov-packet-verification-low-power
path: tmp/coverage.info
retention-days: 1
packet-verification-1-1-on-1-4:
runs-on: ubuntu-24.04
env:
REFERENCE_DEVICE: 1
VIRTUAL_TIME: 1
OT_VT_USE_UNIX_SOCKET: 1
PACKET_VERIFICATION: 1
THREAD_VERSION: 1.4
INTER_OP_BBR: 1
MULTIPLY: 3
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: '3.12'
cache: pip
- name: Bootstrap
run: |
sudo apt-get update
sudo apt-get --no-install-recommends install -y ninja-build lcov
python3 -m pip install -r tests/scripts/thread-cert/requirements.txt
- name: Build
run: |
./script/test build
- name: Get Thread-Wireshark
run: |
./script/test get_thread_wireshark
- name: Run
run: |
./script/test cert_suite ./tests/scripts/thread-cert/Cert_*.py ./tests/scripts/thread-cert/test_*.py
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
if: ${{ failure() }}
with:
name: packet-verification-1.1-on-1.4-pcaps
path: |
*.pcap
*.json
- name: Generate Coverage
run: |
./script/test generate_coverage gcc
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: cov-packet-verification-1-1-on-1-4
path: tmp/coverage.info
retention-days: 1
channel-manager-csl:
runs-on: ubuntu-24.04
env:
CFLAGS: -m32
CXXFLAGS: -m32
LDFLAGS: -m32
COVERAGE: 1
THREAD_VERSION: 1.4
VIRTUAL_TIME: 1
OT_VT_USE_UNIX_SOCKET: 1
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: '3.12'
cache: pip
- name: Bootstrap
run: |
sudo apt-get update
sudo apt-get --no-install-recommends install -y g++-multilib lcov ninja-build
python3 -m pip install -r tests/scripts/thread-cert/requirements.txt
- name: Build
run: |
OT_OPTIONS="-DOT_CHANNEL_MANAGER_CSL=ON" ./script/test build
- name: Run
run: |
ulimit -c unlimited
./script/test cert_suite ./tests/scripts/thread-cert/addon_test_channel_manager_autocsl*.py
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
if: ${{ failure() }}
with:
name: channel-manager-csl
path: ot_testing
- name: Generate Coverage
run: |
./script/test generate_coverage gcc
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: cov-channel-manager-csl
path: tmp/coverage.info
retention-days: 1
expects:
runs-on: ubuntu-24.04
env:
COVERAGE: 1
THREAD_VERSION: 1.4
VIRTUAL_TIME: 0
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: '3.12'
cache: pip
- name: Bootstrap
run: |
sudo apt-get --no-install-recommends install -y expect ninja-build lcov
sudo bash script/install_socat
pip install bleak 'cryptography==43.0.0'
- name: Run RCP Mode
run: |
ulimit -c unlimited
./script/test prepare_coredump_upload
OT_OPTIONS=-DOT_READLINE=OFF OT_NODE_TYPE=rcp ./script/test build expect
- name: Check Crash
if: ${{ failure() }}
run: |
CRASHED=$(./script/test check_crash | tail -1)
[[ $CRASHED -eq "1" ]] && echo "Crashed!" || echo "Not crashed."
echo "CRASHED=$CRASHED" >> $GITHUB_ENV
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
if: ${{ failure() && env.CRASHED == '1' }}
with:
name: core-expect-1-4
path: |
./ot-core-dump/*
- name: Generate Coverage
run: |
./script/test generate_coverage gcc
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: cov-expects
path: tmp/coverage.info
retention-days: 1
thread-1-4-posix:
runs-on: ubuntu-24.04
env:
COVERAGE: 1
PYTHONUNBUFFERED: 1
READLINE: readline
THREAD_VERSION: 1.4
OT_NODE_TYPE: rcp
USE_MTD: 1
VIRTUAL_TIME: 1
OT_VT_USE_UNIX_SOCKET: 1
INTER_OP: 1
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: '3.12'
cache: pip
- name: Bootstrap
run: |
sudo apt-get update
sudo apt-get --no-install-recommends install -y libreadline6-dev ninja-build llvm lcov
python3 -m pip install -r tests/scripts/thread-cert/requirements.txt
- name: Build
run: |
./script/test build
- name: Run
run: |
ulimit -c unlimited
./script/test prepare_coredump_upload
./script/test cert tests/scripts/thread-cert/v1_2_LowPower_5_3_01_SSEDAttachment.py
./script/test cert tests/scripts/thread-cert/v1_2_LowPower_6_1_07_PreferringARouterOverAReed.py
./script/test cert tests/scripts/thread-cert/v1_2_router_5_1_1.py
./script/test cert tests/scripts/thread-cert/v1_2_test_csl_transmission.py
./script/test cert tests/scripts/thread-cert/v1_2_test_enhanced_frame_pending.py
./script/test cert tests/scripts/thread-cert/v1_2_test_parent_selection.py
- name: Check Crash
if: ${{ failure() }}
run: |
CRASHED=$(./script/test check_crash | tail -1)
[[ $CRASHED -eq "1" ]] && echo "Crashed!" || echo "Not crashed."
echo "CRASHED=$CRASHED" >> $GITHUB_ENV
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
if: ${{ failure() }}
with:
name: thread-1-4-posix-pcaps
path: "*.pcap"
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
if: ${{ failure() && env.CRASHED == '1' }}
with:
name: core-thread-1-4-posix
path: |
./ot-core-dump/*
- name: Generate Coverage
run: |
./script/test generate_coverage gcc
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: cov-thread-1-4-posix
path: tmp/coverage.info
retention-days: 1
upload-coverage:
needs:
- thread-1-4
- packet-verification-low-power
- packet-verification-1-1-on-1-4
- expects
- thread-1-4-posix
runs-on: ubuntu-22.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
- name: Bootstrap
run: |
sudo apt-get --no-install-recommends install -y lcov
- uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
with:
path: coverage/
pattern: cov-*
merge-multiple: true
- name: Combine Coverage
run: |
script/test combine_coverage
- name: Upload Coverage
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
with:
files: final.info
fail_ci_if_error: true
+258
View File
@@ -0,0 +1,258 @@
#
# Copyright (c) 2020, 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.
#
name: Simulation
on:
push:
branches-ignore:
- 'dependabot/**'
pull_request:
branches:
- 'main'
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || (github.repository == 'openthread/openthread' && github.run_id) || github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
ot-commissioner:
runs-on: ubuntu-24.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: '3.12'
cache: pip
- name: Bootstrap
env:
PR_BODY: "${{ github.event.pull_request.body }}"
run: |
sudo apt-get update
sudo apt-get install -y avahi-daemon avahi-utils lcov
script/git-tool clone https://github.com/openthread/ot-commissioner.git /tmp/ot-commissioner --depth 1 --branch main
- name: Build
run: |
cd /tmp/ot-commissioner
script/bootstrap.sh
cmake -GNinja \
-DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DCMAKE_CXX_STANDARD=11 \
-DCMAKE_CXX_STANDARD_REQUIRED=ON \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr/local \
-DOT_COMM_COVERAGE=ON \
-DOT_COMM_CCM=OFF \
-S . -B build
cmake --build build
sudo cmake --install build
- name: Run
run: |
export OT_COMM_OPENTHREAD="$(pwd)"
cd /tmp/ot-commissioner/tests/integration
./bootstrap.sh
./run_tests.sh
- name: Generate Coverage
run: |
./script/test generate_coverage gcc
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: cov-ot-commissioner
path: tmp/coverage.info
retention-days: 1
simulation-local-host:
runs-on: ubuntu-24.04
env:
COVERAGE: 1
steps:
- name: Harden Runner
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
- name: Bootstrap
run: |
sudo apt-get --no-install-recommends install -y expect ninja-build lcov
- name: Run
run: |
./script/check-simulation-local-host
- name: Generate Coverage
run: |
./script/test generate_coverage gcc
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: cov-simulation-local-host
path: tmp/coverage.info
retention-days: 1
channel-manager-csl:
runs-on: ubuntu-24.04
env:
CFLAGS: -m32
CXXFLAGS: -m32
LDFLAGS: -m32
COVERAGE: 1
VIRTUAL_TIME: 1
OT_VT_USE_UNIX_SOCKET: 1
steps:
- name: Harden Runner
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: '3.12'
cache: pip
- name: Bootstrap
run: |
sudo apt-get update
sudo apt-get --no-install-recommends install -y g++-multilib lcov ninja-build
python3 -m pip install -r tests/scripts/thread-cert/requirements.txt
- name: Build
run: |
OT_OPTIONS="-DOT_CHANNEL_MANAGER_CSL=ON" ./script/test build
- name: Run
run: |
ulimit -c unlimited
./script/test cert_suite ./tests/scripts/thread-cert/addon_test_channel_manager_autocsl*.py
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: ${{ failure() }}
with:
name: channel-manager-csl
path: ot_testing
- name: Generate Coverage
run: |
./script/test generate_coverage gcc
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: cov-channel-manager-csl
path: tmp/coverage.info
retention-days: 1
expects:
runs-on: ubuntu-24.04
env:
COVERAGE: 1
VIRTUAL_TIME: 0
steps:
- name: Harden Runner
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: '3.12'
cache: pip
- name: Bootstrap
run: |
sudo apt-get --no-install-recommends install -y expect ninja-build lcov
sudo bash script/install_socat
pip install bleak 'cryptography==43.0.0'
- name: Run RCP Mode
run: |
ulimit -c unlimited
./script/test prepare_coredump_upload
OT_OPTIONS=-DOT_READLINE=OFF OT_NODE_TYPE=rcp ./script/test build expect
- name: Check Crash
if: ${{ failure() }}
run: |
CRASHED=$(./script/test check_crash | tail -1)
[[ $CRASHED -eq "1" ]] && echo "Crashed!" || echo "Not crashed."
echo "CRASHED=$CRASHED" >> $GITHUB_ENV
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: ${{ failure() && env.CRASHED == '1' }}
with:
name: core-expect
path: |
./ot-core-dump/*
- name: Generate Coverage
run: |
./script/test generate_coverage gcc
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: cov-expects
path: tmp/coverage.info
retention-days: 1
upload-coverage:
needs:
- ot-commissioner
- simulation-local-host
- channel-manager-csl
- expects
runs-on: ubuntu-22.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
- name: Bootstrap
run: |
sudo apt-get --no-install-recommends install -y lcov
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
path: coverage/
pattern: cov-*
merge-multiple: true
- name: Combine Coverage
run: |
script/test combine_coverage
- name: Upload Coverage
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
with:
files: final.info
fail_ci_if_error: true
+37 -45
View File
@@ -1,6 +1,5 @@
#!/usr/bin/env python3
#
# Copyright (c) 2016, The OpenThread Authors.
# Copyright (c) 2026, The OpenThread Authors.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -26,53 +25,46 @@
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
import logging
import unittest
import config
import thread_cert
name: Size Check
LEADER = 1
ROUTER = 2
on:
push:
branches:
- 'main'
pull_request:
branches:
- 'main'
CHANNEL = 12
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || (github.repository == 'openthread/openthread' && github.run_id) || github.ref }}
cancel-in-progress: true
class Test_MacScan(thread_cert.TestCase):
USE_MESSAGE_FACTORY = False
SUPPORT_NCP = False
jobs:
TOPOLOGY = {
LEADER: {
'channel': CHANNEL,
'mode': 'rdn',
'network_name': 'OpenThread',
'allowlist': [ROUTER]
},
ROUTER: {
'channel': CHANNEL,
'mode': 'rdn',
'network_name': 'OpenThread',
'allowlist': [LEADER]
},
}
size-check:
runs-on: ubuntu-24.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
def test(self):
self.nodes[LEADER].start()
self.nodes[LEADER].set_state('leader')
self.assertEqual(self.nodes[LEADER].get_state(), 'leader')
self.nodes[ROUTER].start()
self.simulator.go(config.ROUTER_STARTUP_DELAY)
self.assertEqual(self.nodes[ROUTER].get_state(), 'router')
results = self.nodes[LEADER].scan(result=True)
logging.info('scan result: %r', results)
self.assertEqual(len(results), 1)
network = results[0]
self.assertEqual(network['extaddr'], self.nodes[ROUTER].get_addr64())
self.assertEqual(network['channel'], CHANNEL)
if __name__ == '__main__':
unittest.main()
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Run
env:
PR_BODY: "${{ github.event.pull_request.body }}"
PR_NUMBER: "${{ github.event.pull_request.number }}"
run: |
./script/check-size
cat /tmp/ot-size-report/report_pr >> $GITHUB_STEP_SUMMARY
echo "${{ github.event.pull_request.number }}" > /tmp/ot-size-report/pr_number
- name: Upload report
if: ${{ github.event_name == 'pull_request' }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: report_pr
path: /tmp/ot-size-report
@@ -1,5 +1,5 @@
#
# Copyright (c) 2020, The OpenThread Authors.
# Copyright (c) 2026, The OpenThread Authors.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -26,84 +26,51 @@
# POSSIBILITY OF SUCH DAMAGE.
#
name: Size
name: Size Report
on:
push:
branches-ignore:
- 'dependabot/**'
pull_request_target:
branches:
- 'main'
workflow_run:
workflows: ["Size Check"]
types:
- completed
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || (github.repository == 'openthread/openthread' && github.run_id) || github.ref }}
cancel-in-progress: true
pull-requests: write
jobs:
size-check:
runs-on: ubuntu-24.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Fetch Pull Request ref
if: ${{ github.event_name == 'pull_request_target' }}
run: |
git fetch --depth 2 origin pull/${{ github.event.pull_request.number }}/merge
echo "OT_SHA_NEW=$(git rev-parse FETCH_HEAD)" >> $GITHUB_ENV
- name: Run
env:
PR_BODY: "${{ github.event.pull_request.body }}"
PR_NUMBER: "${{ github.event.pull_request.number }}"
run: |
./script/check-size
cat /tmp/ot-size-report/report_pr >> $GITHUB_STEP_SUMMARY
- name: Upload report
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: report_pr
path: /tmp/ot-size-report/report_pr
size-report:
needs:
- size-check
permissions:
pull-requests: write
if: github.event_name == 'pull_request_target'
if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success'
runs-on: ubuntu-24.04
steps:
- name: Download report
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: report_pr
path: /tmp/ot-size-report
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Post Report
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3
id: post-report
with:
script: |
const fs = require('fs')
const report = fs.readFileSync('/tmp/ot-size-report/report_pr', 'utf8');
const pr_number = parseInt(fs.readFileSync('/tmp/ot-size-report/pr_number', 'utf8').trim());
const params = {
issue_number: context.issue.number,
issue_number: pr_number,
owner: context.repo.owner,
repo: context.repo.repo,
body: report,
}
const response = await github.rest.issues.listComments({
issue_number: context.issue.number,
issue_number: pr_number,
owner: context.repo.owner,
repo: context.repo.repo,
});
+8 -34
View File
@@ -59,7 +59,7 @@ jobs:
TORANJ_EVENT_NAME: ${{ github.event_name }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
@@ -94,7 +94,7 @@ jobs:
TORANJ_CLI: 1
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
@@ -119,7 +119,7 @@ jobs:
if: "matrix.TORANJ_RADIO != 'multi'"
run: |
./script/test generate_coverage gcc
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: "matrix.TORANJ_RADIO != 'multi'"
with:
name: cov-toranj-cli-${{ matrix.TORANJ_RADIO }}
@@ -131,7 +131,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
@@ -189,7 +189,7 @@ jobs:
runs-on: macos-14
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
@@ -206,39 +206,13 @@ jobs:
run: |
./tests/toranj/build.sh posix-15.4
nexus:
name: nexus
runs-on: ubuntu-24.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
submodules: recursive
- name: Bootstrap
env:
PR_BODY: "${{ github.event.pull_request.body }}"
run: |
sudo apt-get update
sudo apt-get --no-install-recommends install -y ninja-build lcov
- name: Build & Run
run: |
./tests/nexus/build.sh
ctest -L core --output-on-failure
git clean -dfx
./tests/nexus/build.sh trel
ctest -L trel --output-on-failure
upload-coverage:
needs:
- toranj-cli
runs-on: ubuntu-22.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
@@ -248,7 +222,7 @@ jobs:
- name: Bootstrap
run: |
sudo apt-get --no-install-recommends install -y lcov
- uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
path: coverage/
pattern: cov-*
@@ -257,7 +231,7 @@ jobs:
run: |
script/test combine_coverage
- name: Upload Coverage
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
with:
+6 -6
View File
@@ -49,7 +49,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
@@ -67,7 +67,7 @@ jobs:
COVERAGE: 1
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
@@ -98,7 +98,7 @@ jobs:
- name: Generate Coverage
run: |
./script/test generate_coverage gcc
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: cov-unit-tests
path: tmp/coverage.info
@@ -109,7 +109,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
@@ -119,7 +119,7 @@ jobs:
- name: Bootstrap
run: |
sudo apt-get --no-install-recommends install -y lcov
- uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
path: coverage/
pattern: cov-*
@@ -128,7 +128,7 @@ jobs:
run: |
script/test combine_coverage
- name: Upload Coverage
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
with:
+1 -1
View File
@@ -45,7 +45,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@5ef0c079ce82195b2a36a210272d6b661572d83e # v2.14.2
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
+5
View File
@@ -49,6 +49,11 @@ set(CMAKE_CXX_STANDARD 11)
set(CMAKE_C_EXTENSIONS OFF)
set(CMAKE_C_STANDARD 99)
if(APPLE)
set(CMAKE_AR "/usr/bin/ar")
set(CMAKE_RANLIB "/usr/bin/ranlib")
endif()
message(STATUS "OpenThread Source Directory: ${PROJECT_SOURCE_DIR}")
target_include_directories(ot-config INTERFACE
+1
View File
@@ -215,6 +215,7 @@
* @defgroup plat-radio Radio
* @defgroup plat-settings Settings
* @defgroup plat-spi-slave SPI Slave
* @defgroup plat-tcp TCP - Platform
* @defgroup plat-time Time Service
* @defgroup plat-toolchain Toolchain
* @defgroup plat-trel TREL - Platform
+3 -2
View File
@@ -170,7 +170,6 @@ ot_option(OT_ANDROID_NDK OPENTHREAD_CONFIG_ANDROID_NDK_ENABLE "enable android ND
ot_option(OT_ANYCAST_LOCATOR OPENTHREAD_CONFIG_TMF_ANYCAST_LOCATOR_ENABLE "anycast locator")
ot_option(OT_ASSERT OPENTHREAD_CONFIG_ASSERT_ENABLE "assert function OT_ASSERT()")
ot_option(OT_BACKBONE_ROUTER OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE "backbone router functionality")
ot_option(OT_BACKBONE_ROUTER_DUA_NDPROXYING OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE "BBR DUA ND Proxy")
ot_option(OT_BACKBONE_ROUTER_MULTICAST_ROUTING OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE "BBR MR")
ot_option(OT_BLE_TCAT OPENTHREAD_CONFIG_BLE_TCAT_ENABLE "Ble based thread commissioning")
ot_option(OT_BORDER_ADMITTER OPENTHREAD_CONFIG_BORDER_AGENT_ADMITTER_ENABLE "border agent admitter")
@@ -211,13 +210,13 @@ ot_option(OT_DNS_DSO OPENTHREAD_CONFIG_DNS_DSO_ENABLE "DNS Stateful Operations (
ot_option(OT_DNS_UPSTREAM_QUERY OPENTHREAD_CONFIG_DNS_UPSTREAM_QUERY_ENABLE "Allow sending DNS queries to upstream")
ot_option(OT_DNSSD_DISCOVERY_PROXY OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE "DNS-SD discovery proxy")
ot_option(OT_DNSSD_SERVER OPENTHREAD_CONFIG_DNSSD_SERVER_ENABLE "DNS-SD server")
ot_option(OT_DUA OPENTHREAD_CONFIG_DUA_ENABLE "Domain Unicast Address (DUA)")
ot_option(OT_DYNAMIC_STORE_FRAME_AHEAD_COUNTER OPENTHREAD_CONFIG_DYNAMIC_STORE_FRAME_AHEAD_COUNTER_ENABLE "dynamic store frame ahead counter")
ot_option(OT_ECDSA OPENTHREAD_CONFIG_ECDSA_ENABLE "ECDSA")
ot_option(OT_EXTERNAL_HEAP OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE "external heap")
ot_option(OT_FIREWALL OPENTHREAD_POSIX_CONFIG_FIREWALL_ENABLE "firewall")
ot_option(OT_HISTORY_TRACKER OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE "history tracker")
ot_option(OT_IP6_FRAGM OPENTHREAD_CONFIG_IP6_FRAGMENTATION_ENABLE "ipv6 fragmentation")
ot_option(OT_IP6_INIT_ADDR_POOL OPENTHREAD_CONFIG_IP6_INIT_EXT_ADDR_POOL_ENABLE "IPv6 init address pool")
ot_option(OT_JAM_DETECTION OPENTHREAD_CONFIG_JAM_DETECTION_ENABLE "jam detection")
ot_option(OT_JOINER OPENTHREAD_CONFIG_JOINER_ENABLE "joiner")
ot_option(OT_LINK_METRICS_INITIATOR OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE "link metrics initiator")
@@ -251,6 +250,7 @@ ot_option(OT_PLATFORM_KEY_REF OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE "
ot_option(OT_PLATFORM_LOG_CRASH_DUMP OPENTHREAD_CONFIG_PLATFORM_LOG_CRASH_DUMP_ENABLE "platform log crash dump")
ot_option(OT_PLATFORM_NETIF OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE "platform netif")
ot_option(OT_PLATFORM_POWER_CALIBRATION OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE "power calibration")
ot_option(OT_PLATFORM_TCP OPENTHREAD_CONFIG_PLATFORM_TCP_ENABLE "Platform TCP")
ot_option(OT_PLATFORM_UDP OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE "platform UDP")
ot_option(OT_REFERENCE_DEVICE OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE "test harness reference device")
ot_option(OT_SEEKER OPENTHREAD_CONFIG_SEEKER_ENABLE "seeker")
@@ -361,6 +361,7 @@ ot_int_option(OT_MLE_MAX_CHILDREN OPENTHREAD_CONFIG_MLE_MAX_CHILDREN "set maximu
ot_int_option(OT_RCP_RESTORATION_MAX_COUNT OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT "set max RCP restoration count")
ot_int_option(OT_RCP_TIME_SYNC_INTERVAL OPENTHREAD_SPINEL_CONFIG_RCP_TIME_SYNC_INTERVAL "set host-RCP time sync interval in microseconds")
ot_int_option(OT_RCP_TX_WAIT_TIME_SECS OPENTHREAD_SPINEL_CONFIG_RCP_TX_WAIT_TIME_SECS "set RCP TX wait TIME in seconds")
ot_int_option(OT_VENDOR_OUI OPENTHREAD_CONFIG_NET_DIAG_VENDOR_OUI "set the vendor OUI")
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+1 -1
View File
@@ -37,7 +37,7 @@ COPY . openthread
RUN set -x \
&& cd openthread \
&& ./script/bootstrap \
&& mkdir build \
&& mkdir -p build \
&& cd build \
&& cmake -GNinja -DOT_COMMISSIONER=ON -DOT_JOINER=ON -DOT_PLATFORM=simulation .. \
&& ninja
-3
View File
@@ -138,9 +138,6 @@ if (openthread_enable_core_config_args) {
# Enable ECDSA support
openthread_config_ecdsa_enable = false
# Enable Domain Unicast Address feature for Thread 1.2
openthread_config_dua_enable = false
# Enable Multicast Listener Registration feature for Thread 1.2
openthread_config_mlr_enable = false
-1
View File
@@ -342,7 +342,6 @@ static int CliUartOutput(void *aContext, const char *aFormat, va_list aArguments
else
{
// Flush did not succeed, so abandon buffered output.
otLogWarnPlat("Failed to output CLI: %s", otThreadErrorToString(error));
break;
}
}
+1 -1
View File
@@ -56,7 +56,7 @@ target_link_libraries(ot-cli-ftd PRIVATE
)
if(OT_LINKER_MAP)
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "AppleClang")
if(APPLE)
target_link_libraries(ot-cli-ftd PRIVATE -Wl,-map,ot-cli-ftd.map)
else()
target_link_libraries(ot-cli-ftd PRIVATE -Wl,-Map=ot-cli-ftd.map)
+1 -1
View File
@@ -56,7 +56,7 @@ target_link_libraries(ot-cli-mtd PRIVATE
)
if(OT_LINKER_MAP)
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "AppleClang")
if(APPLE)
target_link_libraries(ot-cli-mtd PRIVATE -Wl,-map,ot-cli-mtd.map)
else()
target_link_libraries(ot-cli-mtd PRIVATE -Wl,-Map=ot-cli-mtd.map)
+1 -1
View File
@@ -60,7 +60,7 @@ target_link_libraries(ot-cli-radio PRIVATE
)
if(OT_LINKER_MAP)
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "AppleClang")
if(APPLE)
target_link_libraries(ot-cli-radio PRIVATE -Wl,-map,ot-cli-radio.map)
else()
target_link_libraries(ot-cli-radio PRIVATE -Wl,-Map=ot-cli-radio.map)
+1 -1
View File
@@ -49,7 +49,7 @@ target_link_libraries(ot-ncp-ftd PRIVATE
)
if(OT_LINKER_MAP)
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "AppleClang")
if(APPLE)
target_link_libraries(ot-ncp-ftd PRIVATE -Wl,-map,ot-ncp-ftd.map)
else()
target_link_libraries(ot-ncp-ftd PRIVATE -Wl,-Map=ot-ncp-ftd.map)
+1 -1
View File
@@ -49,7 +49,7 @@ target_link_libraries(ot-ncp-mtd PRIVATE
)
if(OT_LINKER_MAP)
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "AppleClang")
if(APPLE)
target_link_libraries(ot-ncp-mtd PRIVATE -Wl,-map,ot-ncp-mtd.map)
else()
target_link_libraries(ot-ncp-mtd PRIVATE -Wl,-Map=ot-ncp-mtd.map)
+1 -1
View File
@@ -48,7 +48,7 @@ target_link_libraries(ot-rcp PRIVATE
)
if(OT_LINKER_MAP)
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "AppleClang")
if(APPLE)
target_link_libraries(ot-rcp PRIVATE -Wl,-map,ot-rcp.map)
else()
target_link_libraries(ot-rcp PRIVATE -Wl,-Map=ot-rcp.map)
@@ -60,7 +60,6 @@
#define OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE 1
#define OPENTHREAD_CONFIG_DNS_DSO_ENABLE 1
#define OPENTHREAD_CONFIG_DNS_UPSTREAM_QUERY_ENABLE 1
#define OPENTHREAD_CONFIG_DUA_ENABLE 1
#define OPENTHREAD_CONFIG_ECDSA_ENABLE 1
#define OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE 1
#define OPENTHREAD_CONFIG_IP6_BR_COUNTERS_ENABLE 1
@@ -59,7 +59,6 @@
#define OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE 1
#define OPENTHREAD_CONFIG_DNS_DSO_ENABLE 0
#define OPENTHREAD_CONFIG_DNS_UPSTREAM_QUERY_ENABLE 0
#define OPENTHREAD_CONFIG_DUA_ENABLE 1
#define OPENTHREAD_CONFIG_ECDSA_ENABLE 1
#define OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE 0
#define OPENTHREAD_CONFIG_IP6_BR_COUNTERS_ENABLE 0
@@ -59,7 +59,6 @@
#define OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE 1
#define OPENTHREAD_CONFIG_DNS_DSO_ENABLE 0
#define OPENTHREAD_CONFIG_DNS_UPSTREAM_QUERY_ENABLE 0
#define OPENTHREAD_CONFIG_DUA_ENABLE 1
#define OPENTHREAD_CONFIG_ECDSA_ENABLE 1
#define OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE 0
#define OPENTHREAD_CONFIG_IP6_BR_COUNTERS_ENABLE 0
@@ -90,6 +90,7 @@ add_library(openthread-simulation
simul_utils.c
spi-stubs.c
system.c
tcp.c
trel.c
uart.c
virtual_time/alarm-sim.c
+87 -9
View File
@@ -28,12 +28,15 @@
#include "platform-simulation.h"
#if OPENTHREAD_CONFIG_BLE_TCAT_ENABLE
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <openthread/error.h>
#include <openthread/logging.h>
#include <openthread/tcat.h>
#include <openthread/platform/ble.h>
@@ -43,7 +46,10 @@
#define PLAT_BLE_MSG_DATA_MAX 2048
static uint8_t sBleBuffer[PLAT_BLE_MSG_DATA_MAX];
static int sFd = -1;
static int sFd = -1;
static bool sIsConnected = false;
static bool sIsDisconnecting = false;
static bool sIsEnabled = false;
static const uint16_t kPortBase = 10000;
static uint16_t sPort = 0;
@@ -103,33 +109,59 @@ otError otPlatBleGetAdvertisementBuffer(otInstance *aInstance, uint8_t **aAdvert
otError otPlatBleEnable(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
initFds();
if (!sIsEnabled)
{
initFds();
sIsEnabled = true;
sIsConnected = false;
sIsDisconnecting = false;
}
return OT_ERROR_NONE;
}
otError otPlatBleDisable(otInstance *aInstance)
{
deinitFds();
OT_UNUSED_VARIABLE(aInstance);
if (sIsEnabled)
{
deinitFds();
sIsEnabled = false;
}
return OT_ERROR_NONE;
}
otError otPlatBleGapAdvStart(otInstance *aInstance, uint16_t aInterval)
{
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aInterval);
if (sIsConnected || !sIsEnabled)
{
return OT_ERROR_INVALID_STATE;
}
otLogDebgPlat("BLE adv start (interval %u)", aInterval);
return OT_ERROR_NONE;
}
otError otPlatBleGapAdvStop(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
if (!sIsEnabled)
{
return OT_ERROR_INVALID_STATE;
}
otLogDebgPlat("BLE adv stop");
return OT_ERROR_NONE;
}
otError otPlatBleGapDisconnect(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
if (!sIsConnected)
{
return OT_ERROR_INVALID_STATE;
}
// Only flag the disconnection here. The 'disconnected' event is delivered asynchronously
// by platformBleProcess() (via otPlatBleGapOnDisconnected), per API contract.
sIsDisconnecting = true;
return OT_ERROR_NONE;
}
@@ -164,7 +196,6 @@ void platformBleDeinit(void) { deinitFds(); }
void platformBleUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, struct timeval *aTimeout, int *aMaxFd)
{
OT_UNUSED_VARIABLE(aTimeout);
OT_UNUSED_VARIABLE(aWriteFdSet);
if (aReadFdSet != NULL && sFd != -1)
@@ -176,6 +207,13 @@ void platformBleUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, struct time
*aMaxFd = sFd;
}
}
// A pending disconnection must be delivered promptly; ensure the main loop does not block.
if (sIsDisconnecting && aTimeout != NULL)
{
aTimeout->tv_sec = 0;
aTimeout->tv_usec = 0;
}
}
void platformBleProcess(otInstance *aInstance, const fd_set *aReadFdSet, const fd_set *aWriteFdSet)
@@ -184,6 +222,14 @@ void platformBleProcess(otInstance *aInstance, const fd_set *aReadFdSet, const f
otEXPECT(sFd != -1);
// Deliver a pending disconnection (requested earlier via otPlatBleGapDisconnect)
if (sIsDisconnecting)
{
sIsConnected = false;
otPlatBleGapOnDisconnected(aInstance, 0);
sIsDisconnecting = false;
}
if (FD_ISSET(sFd, aReadFdSet))
{
socklen_t len = sizeof(sSockaddr);
@@ -193,6 +239,14 @@ void platformBleProcess(otInstance *aInstance, const fd_set *aReadFdSet, const f
if (rval > 0)
{
otBleRadioPacket myPacket;
if (!sIsConnected)
{
sIsConnected = true;
otLogDebgPlat("BLE client connected");
otPlatBleGapOnConnected(aInstance, 0);
}
myPacket.mValue = sBleBuffer;
myPacket.mLength = (uint16_t)rval;
myPacket.mPower = 0;
@@ -211,10 +265,27 @@ void platformBleProcess(otInstance *aInstance, const fd_set *aReadFdSet, const f
DieNow(OT_EXIT_FAILURE);
}
}
exit:
return;
}
/* Weak stubs for callbacks defined in the FTD/MTD core library, not available for RCP targets. */
OT_TOOL_WEAK void otPlatBleGapOnConnected(otInstance *aInstance, uint16_t aConnectionId)
{
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aConnectionId);
assert(false);
}
OT_TOOL_WEAK void otPlatBleGapOnDisconnected(otInstance *aInstance, uint16_t aConnectionId)
{
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aConnectionId);
assert(false);
}
OT_TOOL_WEAK void otPlatBleGattServerOnWriteRequest(otInstance *aInstance,
uint16_t aHandle,
const otBleRadioPacket *aPacket)
@@ -223,9 +294,6 @@ OT_TOOL_WEAK void otPlatBleGattServerOnWriteRequest(otInstance *aIns
OT_UNUSED_VARIABLE(aHandle);
OT_UNUSED_VARIABLE(aPacket);
assert(false);
/* In case of rcp there is a problem with linking to otPlatBleGattServerOnWriteRequest
* which is available in FTD/MTD library.
*/
}
void otPlatBleGetLinkCapabilities(otInstance *aInstance, otBleLinkCapabilities *aBleLinkCapabilities)
@@ -241,6 +309,10 @@ otError otPlatBleGapAdvSetData(otInstance *aInstance, uint8_t *aAdvertisementDat
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aAdvertisementData);
OT_UNUSED_VARIABLE(aAdvertisementLen);
if (!sIsEnabled)
{
return OT_ERROR_INVALID_STATE;
}
return OT_ERROR_NONE;
}
@@ -249,11 +321,17 @@ otError otPlatBleGapAdvUpdateData(otInstance *aInstance, uint8_t *aAdvertisement
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aAdvertisementData);
OT_UNUSED_VARIABLE(aAdvertisementLen);
if (!sIsEnabled)
{
return OT_ERROR_INVALID_STATE;
}
return OT_ERROR_NONE;
}
bool otPlatBleSupportsMultiRadio(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
return false;
return true;
}
#endif // OPENTHREAD_CONFIG_BLE_TCAT_ENABLE
+15 -3
View File
@@ -172,18 +172,22 @@ exit:
//---------------------------------------------------------------------------------------------------------------------
// otPlatInfraIf
bool otPlatInfraIfHasAddress(uint32_t aInfraIfIndex, const otIp6Address *aAddress)
bool otPlatInfraIfHasAddress(otInstance *aInstance, uint32_t aInfraIfIndex, const otIp6Address *aAddress)
{
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aInfraIfIndex);
return addressesMatch(aAddress, &sIp6Address);
}
otError otPlatInfraIfSendIcmp6Nd(uint32_t aInfraIfIndex,
otError otPlatInfraIfSendIcmp6Nd(otInstance *aInstance,
uint32_t aInfraIfIndex,
const otIp6Address *aDestAddress,
const uint8_t *aBuffer,
uint16_t aBufferLength)
{
OT_UNUSED_VARIABLE(aInstance);
otError error = OT_ERROR_FAILED;
Message *message;
@@ -207,8 +211,9 @@ exit:
return error;
}
otError otPlatInfraIfDiscoverNat64Prefix(uint32_t aInfraIfIndex)
otError otPlatInfraIfDiscoverNat64Prefix(otInstance *aInstance, uint32_t aInfraIfIndex)
{
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aInfraIfIndex);
return OT_ERROR_NONE;
@@ -358,4 +363,11 @@ OT_TOOL_WEAK void otPlatInfraIfRecvIcmp6Nd(otInstance *aInstance,
DieNow(OT_EXIT_FAILURE);
}
OT_TOOL_WEAK void otMessageFree(otMessage *aMessage)
{
OT_UNUSED_VARIABLE(aMessage);
fprintf(stderr, "\n\rWeak otMessageFree() is incorrectly used\n\r");
DieNow(OT_EXIT_FAILURE);
}
#endif // OPENTHREAD_SIMULATION_IMPLEMENT_INFRA_IF && OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
+23 -2
View File
@@ -90,6 +90,25 @@ void platformLoggingDeinit(void)
}
}
#if OPENTHREAD_CONFIG_LOG_INSTANCE_AWARE_API_ENABLE
void otPlatLogOutput(otInstance *aInstance, otLogLevel aLogLevel, const char *aLogLine)
{
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aLogLevel);
if (sLogFile == NULL)
{
syslog(LOG_CRIT, "[%lu] %s", (unsigned long)gNodeId, aLogLine);
}
else
{
fprintf(sLogFile, "%s\r\n", aLogLine);
}
}
#else
void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
{
OT_UNUSED_VARIABLE(aLogLevel);
@@ -118,9 +137,11 @@ void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat
va_end(args);
}
#else
#endif // OPENTHREAD_CONFIG_LOG_INSTANCE_AWARE_API_ENABLE
#else // (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED)
void platformLoggingInit(const char *aName) { OT_UNUSED_VARIABLE(aName); }
void platformLoggingDeinit(void) {}
#endif // (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED)
#endif
@@ -77,6 +77,9 @@
#define OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_TIMING_ENABLE 1
#endif
#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_RETX_SECURITY_ENABLE
#define OPENTHREAD_CONFIG_MAC_SOFTWARE_RETX_SECURITY_ENABLE 1
#endif
#endif // OPENTHREAD_RADIO
#ifndef OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
+1 -5
View File
@@ -645,7 +645,6 @@ void radioSendMessage(otInstance *aInstance)
{
uint64_t sfdTxTime = otPlatTimeGet();
sRadioContext.mCslPresent = sTransmitFrame.mInfo.mTxInfo.mCslPresent;
otEXPECT(otMacFrameProcessTxSfd(&sTransmitFrame, sfdTxTime, &sRadioContext) == OT_ERROR_NONE);
}
@@ -1061,10 +1060,7 @@ static uint8_t generateAckIeData(uint8_t *aLinkMetricsIeData,
uint8_t offset = 0;
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
sRadioContext.mCslPresent =
(sRadioContext.mCslPeriod > 0) && otMacFrameSrcAddrMatchCslReceiverPeer(aReceivedFrame, &sRadioContext);
if (sRadioContext.mCslPresent)
if ((sRadioContext.mCslPeriod > 0) && otMacFrameSrcAddrMatchCslReceiverPeer(aReceivedFrame, &sRadioContext))
{
offset += otMacFrameGenerateCslIeTemplate(sAckIeData);
}
+28 -9
View File
@@ -50,6 +50,7 @@
#define UTILS_SOCKET_LOCAL_HOST_ADDR "127.0.0.1"
#define UTILS_SOCKET_GROUP_ADDR "224.0.0.116"
#define UTILS_SOCKET_GROUP_ADDR6 "ff02::116"
#define UTILS_SOCKET_GROUP_ADDR6_LO "ff01::116"
const char *gLocalInterface = UTILS_SOCKET_LOCAL_HOST_ADDR;
@@ -76,11 +77,21 @@ static bool IsAddressLinkLocal(const struct in6_addr *aAddress)
return ((aAddress->s6_addr[0] & 0xff) == 0xfe) && ((aAddress->s6_addr[1] & 0xc0) == 0x80);
}
static void InitRxSocket(utilsSocket *aSocket, const struct in_addr *aIp4Address, unsigned int aIfIndex)
static bool IsAddressLoopback(const struct in6_addr *aAddress)
{
static const uint8_t sLoopbackAddr[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
return memcmp(aAddress->s6_addr, sLoopbackAddr, sizeof(aAddress->s6_addr)) == 0;
}
static void InitRxSocket(utilsSocket *aSocket,
const struct in_addr *aIp4Address,
const struct in6_addr *aIp6Address,
unsigned int aIfIndex)
{
int fd;
int one = 1;
int rval;
int rcvBufSize = 2 * 1024 * 1024;
fd = socket(aIp4Address ? AF_INET : AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
ExpectOrExitWithErrorMsg(fd != -1, "socket(RxFd)");
@@ -91,6 +102,9 @@ static void InitRxSocket(utilsSocket *aSocket, const struct in_addr *aIp4Address
rval = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one));
ExpectOrExitWithErrorMsg(rval != -1, "setsockopt(RxFd, SO_REUSEPORT)");
rval = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcvBufSize, sizeof(rcvBufSize));
ExpectOrExitWithErrorMsg(rval != -1, "setsockopt(RxFd, SO_RCVBUF)");
if (aIp4Address)
{
struct ip_mreqn mreq;
@@ -118,7 +132,13 @@ static void InitRxSocket(utilsSocket *aSocket, const struct in_addr *aIp4Address
else
{
struct ipv6_mreq mreq;
struct sockaddr_in6 *sockaddr = &aSocket->mGroupAddr.mSockAddr6;
struct sockaddr_in6 *sockaddr = &aSocket->mGroupAddr.mSockAddr6;
const char *groupAddr = UTILS_SOCKET_GROUP_ADDR6;
if (aIp6Address != NULL && IsAddressLoopback(aIp6Address))
{
groupAddr = UTILS_SOCKET_GROUP_ADDR6_LO;
}
rval = setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &aIfIndex, sizeof(aIfIndex));
ExpectOrExitWithErrorMsg(rval != -1, "setsockopt(RxFd, IPV6_MULTICAST_IF)");
@@ -127,8 +147,7 @@ static void InitRxSocket(utilsSocket *aSocket, const struct in_addr *aIp4Address
sockaddr->sin6_family = AF_INET6;
sockaddr->sin6_port = htons(aSocket->mPortBase);
sockaddr->sin6_scope_id = aIfIndex; // This specifies network interface for link local scope
ExpectOrExitWithErrorMsg(inet_pton(AF_INET6, UTILS_SOCKET_GROUP_ADDR6, &sockaddr->sin6_addr),
"inet_pton(AF_INET6)");
ExpectOrExitWithErrorMsg(inet_pton(AF_INET6, groupAddr, &sockaddr->sin6_addr), "inet_pton(AF_INET6)");
memset(&mreq, 0, sizeof(mreq));
mreq.ipv6mr_multiaddr = sockaddr->sin6_addr;
@@ -150,7 +169,7 @@ exit:
}
}
void InitTxSocketIp6(utilsSocket *aSocket, const struct in6_addr *aAddress, unsigned int aIfIndex)
static void InitTxSocketIp6(utilsSocket *aSocket, const struct in6_addr *aAddress, unsigned int aIfIndex)
{
int fd;
int one = 1;
@@ -164,7 +183,7 @@ void InitTxSocketIp6(utilsSocket *aSocket, const struct in6_addr *aAddress, unsi
sockaddr.sin6_family = AF_INET6;
sockaddr.sin6_addr = *aAddress;
sockaddr.sin6_port = htons(aSocket->mPort);
if (IsAddressLinkLocal(aAddress))
if (IsAddressLinkLocal(aAddress) || IsAddressLoopback(aAddress))
{
sockaddr.sin6_scope_id = aIfIndex;
}
@@ -283,7 +302,7 @@ static bool TryInitSocketIfname(utilsSocket *aSocket, const char *aLocalInterfac
DieNow(OT_EXIT_FAILURE);
}
InitRxSocket(aSocket, (addr6 ? NULL : addr4), ifIndex);
InitRxSocket(aSocket, (addr6 ? NULL : addr4), addr6, ifIndex);
aSocket->mInitialized = true;
aSocket->mUseIp6 = (addr6 != NULL);
@@ -299,7 +318,7 @@ static bool TryInitSocketIp4(utilsSocket *aSocket, const char *aLocalInterface)
ExpectOrExitWithErrorMsg(inet_pton(AF_INET, aLocalInterface, &addr4), "inet_pton(AF_INET)");
InitTxSocketIp4(aSocket, &addr4);
InitRxSocket(aSocket, &addr4, 0);
InitRxSocket(aSocket, &addr4, NULL, 0);
aSocket->mInitialized = true;
aSocket->mUseIp6 = false;
@@ -344,7 +363,7 @@ static bool TryInitSocketIp6(utilsSocket *aSocket, const char *aLocalInterface)
}
InitTxSocketIp6(aSocket, &addr6, ifIndex);
InitRxSocket(aSocket, NULL, ifIndex);
InitRxSocket(aSocket, NULL, &addr6, ifIndex);
aSocket->mInitialized = true;
aSocket->mUseIp6 = true;
break;
+71
View File
@@ -0,0 +1,71 @@
/*
* 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 "platform-simulation.h"
#include <openthread/platform/tcp.h>
#if OPENTHREAD_CONFIG_PLATFORM_TCP_ENABLE
otError otPlatTcpEnableListener(otPlatTcpListener *aListener, const otPlatTcpSockAddr *aLocalSockAddr)
{
OT_UNUSED_VARIABLE(aListener);
OT_UNUSED_VARIABLE(aLocalSockAddr);
return OT_ERROR_FAILED;
}
void otPlatTcpDisableListener(otPlatTcpListener *aListener) { OT_UNUSED_VARIABLE(aListener); }
otError otPlatTcpConnect(otPlatTcpConnection *aConn,
const otPlatTcpSockAddr *aPeerSockAddr,
const otPlatTcpSockAddr *aLocalSockAddr)
{
OT_UNUSED_VARIABLE(aConn);
OT_UNUSED_VARIABLE(aPeerSockAddr);
OT_UNUSED_VARIABLE(aLocalSockAddr);
return OT_ERROR_FAILED;
}
void otPlatTcpNotifyTxPending(otPlatTcpConnection *aConn) { OT_UNUSED_VARIABLE(aConn); }
uint16_t otPlatTcpSend(otPlatTcpConnection *aConn, const uint8_t *aBuffer, uint16_t aLength)
{
OT_UNUSED_VARIABLE(aConn);
OT_UNUSED_VARIABLE(aBuffer);
OT_UNUSED_VARIABLE(aLength);
return 0;
}
void otPlatTcpClose(otPlatTcpConnection *aConn) { OT_UNUSED_VARIABLE(aConn); }
void otPlatTcpAbort(otPlatTcpConnection *aConn) { OT_UNUSED_VARIABLE(aConn); }
#endif // #if OPENTHREAD_CONFIG_PLATFORM_TCP_ENABLE
+9
View File
@@ -120,6 +120,15 @@ otError otPlatDebugUart_logfile(const char *filename)
}
#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_DEBUG_UART)
#if OPENTHREAD_CONFIG_LOG_INSTANCE_AWARE_API_ENABLE
void otPlatLogOutput(otInstance *aInstance, otLogLevel aLogLevel, const char *aLogLine)
{
OT_UNUSED_VARIABLE(aInstance);
otPlatLog(aLogLevel, OT_LOG_REGION_CORE, "%s", aLogLine);
}
#endif
/* this should not be a WEAK function */
void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
{
+11 -3
View File
@@ -404,8 +404,14 @@ exit:
otError otMacFrameProcessTxSfd(otRadioFrame *aFrame, uint64_t aRadioTime, otRadioContext *aRadioContext)
{
otError error = OT_ERROR_NONE;
aFrame->mInfo.mTxInfo.mTimestamp = aRadioTime;
VerifyOrExit(!otMacFrameIsSecurityEnabled(aFrame) || !aFrame->mInfo.mTxInfo.mIsSecurityProcessed);
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
if (aRadioContext->mCslPresent) // CSL IE should be filled for every transmit attempt
if (static_cast<Mac::Frame *>(aFrame)->HasCslIe()) // CSL IE should be filled for every transmit attempt
{
otMacFrameSetCslIe(aFrame, aRadioContext->mCslPeriod, ComputeCslPhase(aRadioTime, aRadioContext));
}
@@ -413,8 +419,10 @@ otError otMacFrameProcessTxSfd(otRadioFrame *aFrame, uint64_t aRadioTime, otRadi
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
otMacFrameUpdateTimeIe(aFrame, aRadioTime, aRadioContext);
#endif
aFrame->mInfo.mTxInfo.mTimestamp = aRadioTime;
return otMacFrameProcessTransmitSecurity(aFrame, aRadioContext);
error = otMacFrameProcessTransmitSecurity(aFrame, aRadioContext);
exit:
return error;
}
bool otMacFrameSrcAddrMatchCslReceiverPeer(const otRadioFrame *aFrame, const otRadioContext *aRadioContext)
-1
View File
@@ -349,7 +349,6 @@ typedef struct otRadioContext
uint16_t mCslPeriod; ///< In unit of 10 symbols.
otShortAddress mCslShortAddress; ///< The short address of the CSL receiver's peer.
otExtAddress mCslExtAddress; ///< The extended address of the CSL receiver's peer.
bool mCslPresent : 1; ///< Indicates whether the CSL header IE is present.
otShortAddress mShortAddress;
otShortAddress mAlternateShortAddress;
otRadioKeyType mKeyType;
+1
View File
@@ -112,6 +112,7 @@ source_set("openthread") {
"platform/radio.h",
"platform/settings.h",
"platform/spi-slave.h",
"platform/tcp.h",
"platform/time.h",
"platform/toolchain.h",
"platform/trel.h",
-118
View File
@@ -43,7 +43,6 @@
#include <openthread/error.h>
#include <openthread/instance.h>
#include <openthread/ip6.h>
#include <openthread/netdata.h>
#ifdef __cplusplus
extern "C" {
@@ -175,34 +174,6 @@ uint8_t otBackboneRouterGetRegistrationJitter(otInstance *aInstance);
*/
void otBackboneRouterSetRegistrationJitter(otInstance *aInstance, uint8_t aJitter);
/**
* Gets the local Domain Prefix configuration.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[out] aConfig A pointer to the Domain Prefix configuration.
*
* @retval OT_ERROR_NONE Successfully got the Domain Prefix configuration.
* @retval OT_ERROR_NOT_FOUND No Domain Prefix was configured.
*/
otError otBackboneRouterGetDomainPrefix(otInstance *aInstance, otBorderRouterConfig *aConfig);
/**
* Configures response status for next DUA registration.
*
* Note: available only when `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE` is enabled.
* Only used for test and certification.
*
* TODO: (DUA) support coap error code and corresponding process for certification purpose.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aMlIid A pointer to the Mesh Local IID. If NULL, respond with @p aStatus for any
* coming DUA.req, otherwise only respond the one with matching @p aMlIid.
* @param[in] aStatus The status to respond.
*/
void otBackboneRouterConfigNextDuaRegistrationResponse(otInstance *aInstance,
const otIp6InterfaceIdentifier *aMlIid,
uint8_t aStatus);
/**
* Configures the response status for the next Multicast Listener Registration.
*
@@ -317,95 +288,6 @@ otError otBackboneRouterMulticastListenerGetNext(otInstance
otBackboneRouterMulticastListenerIterator *aIterator,
otBackboneRouterMulticastListenerInfo *aListenerInfo);
/**
* Represents the ND Proxy events.
*/
typedef enum
{
OT_BACKBONE_ROUTER_NDPROXY_ADDED = 0, ///< ND Proxy was added.
OT_BACKBONE_ROUTER_NDPROXY_REMOVED = 1, ///< ND Proxy was removed.
OT_BACKBONE_ROUTER_NDPROXY_RENEWED = 2, ///< ND Proxy was renewed.
OT_BACKBONE_ROUTER_NDPROXY_CLEARED = 3, ///< All ND Proxies were cleared.
} otBackboneRouterNdProxyEvent;
/**
* Pointer is called whenever the Nd Proxy changed.
*
* @param[in] aContext The user context pointer.
* @param[in] aEvent The ND Proxy event.
* @param[in] aDua The Domain Unicast Address of the ND Proxy, or NULL if @p aEvent is
* `OT_BACKBONE_ROUTER_NDPROXY_CLEARED`.
*/
typedef void (*otBackboneRouterNdProxyCallback)(void *aContext,
otBackboneRouterNdProxyEvent aEvent,
const otIp6Address *aDua);
/**
* Sets the Backbone Router ND Proxy callback.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aCallback A pointer to the ND Proxy callback.
* @param[in] aContext A user context pointer.
*/
void otBackboneRouterSetNdProxyCallback(otInstance *aInstance,
otBackboneRouterNdProxyCallback aCallback,
void *aContext);
/**
* Represents the Backbone Router ND Proxy info.
*/
typedef struct otBackboneRouterNdProxyInfo
{
otIp6InterfaceIdentifier *mMeshLocalIid; ///< Mesh-local IID
uint32_t mTimeSinceLastTransaction; ///< Time since last transaction (Seconds)
uint16_t mRloc16; ///< RLOC16
} otBackboneRouterNdProxyInfo;
/**
* Gets the Backbone Router ND Proxy info.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aDua The Domain Unicast Address.
* @param[out] aNdProxyInfo A pointer to the ND Proxy info.
*
* @retval OT_ERROR_NONE Successfully got the ND Proxy info.
* @retval OT_ERROR_NOT_FOUND Failed to find the Domain Unicast Address in the ND Proxy table.
*/
otError otBackboneRouterGetNdProxyInfo(otInstance *aInstance,
const otIp6Address *aDua,
otBackboneRouterNdProxyInfo *aNdProxyInfo);
/**
* Represents the Domain Prefix events.
*/
typedef enum
{
OT_BACKBONE_ROUTER_DOMAIN_PREFIX_ADDED = 0, ///< Domain Prefix was added.
OT_BACKBONE_ROUTER_DOMAIN_PREFIX_REMOVED = 1, ///< Domain Prefix was removed.
OT_BACKBONE_ROUTER_DOMAIN_PREFIX_CHANGED = 2, ///< Domain Prefix was changed.
} otBackboneRouterDomainPrefixEvent;
/**
* Pointer is called whenever the Domain Prefix changed.
*
* @param[in] aContext The user context pointer.
* @param[in] aEvent The Domain Prefix event.
* @param[in] aDomainPrefix The new Domain Prefix if added or changed, NULL otherwise.
*/
typedef void (*otBackboneRouterDomainPrefixCallback)(void *aContext,
otBackboneRouterDomainPrefixEvent aEvent,
const otIp6Prefix *aDomainPrefix);
/**
* Sets the Backbone Router Domain Prefix callback.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aCallback A pointer to the Domain Prefix callback.
* @param[in] aContext A user context pointer.
*/
void otBackboneRouterSetDomainPrefixCallback(otInstance *aInstance,
otBackboneRouterDomainPrefixCallback aCallback,
void *aContext);
/**
* @}
*/
+3
View File
@@ -138,6 +138,9 @@ otError otBleSecureSetTcatVendorInfo(otInstance *aInstance, const otTcatVendorIn
/**
* Enables the TCAT protocol over BLE Secure.
*
* Vendor info must be set before calling this function. Depending on the policy defined in the vendor info, TCAT may
* start in standby mode if the device is commissioned and Thread is enabled.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aJoinHandler A pointer to a function that is called when a network join or leave
* operation is requested under guidance of the TCAT Commissioner.
+6 -4
View File
@@ -258,10 +258,11 @@ otError otBorderAgentGetMeshCoPServiceTxtData(otInstance *aInstance, otBorderAge
/**
* Maximum string length of base name used in `otBorderAgentSetMeshCoPServiceBaseName()`.
*
* The full DNS label is constructed by appending the Extended Address of the device (as 16-character hex digits) to
* To ensure name uniqueness and handle potential name conflicts, the OpenThread Border Agent module appends a
* suffix (e.g., " #XXXX" where "XXXX" represents the last two bytes of the device's Extended Address in hex) to
* the given base name.
*/
#define OT_BORDER_AGENT_MESHCOP_SERVICE_BASE_NAME_MAX_LENGTH (OT_DNS_MAX_LABEL_SIZE - 17)
#define OT_BORDER_AGENT_MESHCOP_SERVICE_BASE_NAME_MAX_LENGTH (OT_DNS_MAX_LABEL_SIZE - 13)
/**
* Sets the base name to construct the service instance name used when advertising the mDNS `_meshcop._udp` service by
@@ -276,8 +277,9 @@ otError otBorderAgentGetMeshCoPServiceTxtData(otInstance *aInstance, otBorderAge
* Per the Thread specification, the service instance should be a user-friendly name identifying the device model or
* product. A recommended format is "VendorName ProductName".
*
* To construct the full name and ensure name uniqueness, the OpenThread Border Agent module will append the Extended
* Address of the device (as 16-character hex digits) to the given base name.
* To construct the full name and ensure name uniqueness, the OpenThread Border Agent module appends a suffix
* (e.g., " #XXXX" where "XXXX" represents the last two bytes of the device's Extended Address in hex) to the given
* base name. If a name conflict is detected on the network, an additional index may be appended (e.g., " #XXXX (1)").
*
* Note that the same name will be used for the ephemeral key service `_meshcop-e._udp` when the ephemeral key feature
* is enabled and used.
@@ -61,6 +61,7 @@ extern "C" {
#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`.
#define OT_BORDER_AGENT_VENDOR_OUI_SIZE (3) ///< Size of Vendor OUI (in bytes) in `otBorderAgentTxtDataInfo`.
/**
* Represents the Connection Mode in a Border Agent State Bitmap.
@@ -152,6 +153,7 @@ typedef struct otBorderAgentTxtDataInfo
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.
bool mHasVendorOui : 1; ///< Indicates whether Vendor OUI 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.
@@ -167,6 +169,7 @@ typedef struct otBorderAgentTxtDataInfo
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.
uint8_t mVendorOui[OT_BORDER_AGENT_VENDOR_OUI_SIZE]; ///< Vendor OUI (24-bit).
} otBorderAgentTxtDataInfo;
/**
-2
View File
@@ -603,7 +603,6 @@ otError otBorderRoutingGetNextRouterEntry(otInstance *aI
*
* - It has added at least one external route entry.
* - It has added at least one prefix entry with both the default-route and on-mesh flags set.
* - It has added at least one domain prefix (with both the domain and on-mesh flags set).
*
* The list of peer BRs specifically excludes the current device, even if it is itself acting as a BR.
*
@@ -629,7 +628,6 @@ otError otBorderRoutingGetNextPeerBrEntry(otInstance *
*
* - It has added at least one external route entry.
* - It has added at least one prefix entry with both the default-route and on-mesh flags set.
* - It has added at least one domain prefix (with both the domain and on-mesh flags set).
*
* The list of peer BRs specifically excludes the current device, even if it is itself acting as a BR.
*
+112 -25
View File
@@ -36,6 +36,8 @@
#define OPENTHREAD_CLI_H_
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <openthread/error.h>
@@ -47,17 +49,6 @@
extern "C" {
#endif
/**
* Represents a CLI command.
*/
typedef struct otCliCommand
{
const char *mName; ///< A pointer to the command string.
otError (*mCommand)(void *aContext,
uint8_t aArgsLength,
char *aArgs[]); ///< A function pointer to process the command.
} otCliCommand;
/**
* @addtogroup api-cli
*
@@ -68,7 +59,12 @@ typedef struct otCliCommand
*/
/**
* Pointer is called to notify about Console output.
* Opaque type for a CLI interpreter.
*/
typedef struct otCliInterpreter otCliInterpreter;
/**
* Pointer is called to notify about CLI interpreter output.
*
* @param[out] aContext A user context pointer.
* @param[in] aFormat The format string.
@@ -80,7 +76,62 @@ typedef int (*otCliOutputCallback)(void *aContext, const char *aFormat, va_list
OT_TOOL_PRINTF_STYLE_FORMAT_ARG_CHECK(2, 0);
/**
* Initialize the CLI module.
* Gets the size of the CLI interpreter object.
*
* @returns The size of the CLI interpreter object in bytes.
*/
size_t otCliInterpreterGetSize(void);
/**
* Initializes a CLI interpreter.
*
* @param[in] aBuffer A pointer to a memory buffer for the CLI interpreter.
* @param[in] aSize The size of the memory buffer.
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aCallback A callback method called to process CLI output.
* @param[in] aContext A user context pointer.
*
* @returns A pointer to the initialized CLI interpreter, or `NULL` if @p aSize is too small.
*/
otCliInterpreter *otCliInterpreterInit(void *aBuffer,
size_t aSize,
otInstance *aInstance,
otCliOutputCallback aCallback,
void *aContext);
/**
* Configures whether or not the CLI interpreter outputs the prompt string.
*
* Requires `OPENTHREAD_CONFIG_CLI_PROMPT_ENABLE`.
*
* It is enabled by default.
*
* @param[in] aInterpreter A pointer to a CLI interpreter.
* @param[in] aEnable TRUE to enable outputting the prompt, FALSE to disable.
*/
void otCliInterpreterSetPromptConfig(otCliInterpreter *aInterpreter, bool aEnable);
/**
* Feeds input to the CLI interpreter.
*
* @param[in] aInterpreter A pointer to a CLI interpreter.
* @param[in] aLine A pointer to a null-terminated string.
*/
void otCliInterpreterInputLine(otCliInterpreter *aInterpreter, char *aLine);
/**
* Finalizes the CLI interpreter.
*
* @param[in] aInterpreter A pointer to a CLI interpreter.
*/
void otCliInterpreterFinalize(otCliInterpreter *aInterpreter);
//--------------------------------------------------------------------------------------------------------------------
/**
* Initialize the static CLI interpreter.
*
* Requires `OPENTHREAD_CONFIG_CLI_STATIC_INTERPRETER_ENABLE`.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aCallback A callback method called to process CLI output.
@@ -89,26 +140,52 @@ typedef int (*otCliOutputCallback)(void *aContext, const char *aFormat, va_list
void otCliInit(otInstance *aInstance, otCliOutputCallback aCallback, void *aContext);
/**
* Is called to feed in a console input line.
* Gets the pointer to the static CLI interpreter.
*
* @param[in] aBuf A pointer to a null-terminated string.
* Requires `OPENTHREAD_CONFIG_CLI_STATIC_INTERPRETER_ENABLE`.
*
* @returns A pointer to the static CLI interpreter.
*/
void otCliInputLine(char *aBuf);
otCliInterpreter *otCliGetStaticInterpreter(void);
/**
* Set a user command table.
* Feeds input to the static CLI interpreter.
*
* Requires `OPENTHREAD_CONFIG_CLI_STATIC_INTERPRETER_ENABLE`.
*
* @param[in] aLine A pointer to a null-terminated string.
*/
void otCliInputLine(char *aLine);
/**
* Represents a user provided CLI command entry.
*/
typedef struct otCliCommand
{
const char *mName; ///< The command string.
otError (*mCommand)(void *aContext, uint8_t aArgsLength, char *aArgs[]); ///< Command handler function pointer.
} otCliCommand;
/**
* Set a user command table on the static CLI interpreter.
*
* Requires `OPENTHREAD_CONFIG_CLI_STATIC_INTERPRETER_ENABLE`.
*
* @param[in] aUserCommands A pointer to an array with user commands.
* @param[in] aLength @p aUserCommands length.
* @param[in] aContext @p The context passed to the handler.
* @param[in] aLength The @p aUserCommands length.
* @param[in] aContext The context passed to the handler.
*
* @retval OT_ERROR_NONE Successfully updated command table with commands from @p aUserCommands.
* @retval OT_ERROR_FAILED Maximum number of command entries have already been set.
* @retval OT_ERROR_NONE Successfully updated command table with commands from @p aUserCommands.
* @retval OT_ERROR_NO_BUFS Maximum number of command entries have already been set.
*/
otError otCliSetUserCommands(const otCliCommand *aUserCommands, uint8_t aLength, void *aContext);
/**
* Write a number of bytes to the CLI console as a hex string.
* Write a number of bytes to the static CLI interpreter output as a hex string.
*
* Requires `OPENTHREAD_CONFIG_CLI_STATIC_INTERPRETER_ENABLE`.
*
* This is intended for use by user-provided CLI command handlers.
*
* @param[in] aBytes A pointer to data which should be printed.
* @param[in] aLength @p aBytes length.
@@ -116,7 +193,11 @@ otError otCliSetUserCommands(const otCliCommand *aUserCommands, uint8_t aLength,
void otCliOutputBytes(const uint8_t *aBytes, uint8_t aLength);
/**
* Write formatted string to the CLI console
* Write formatted string to the static CLI interpreter output.
*
* Requires `OPENTHREAD_CONFIG_CLI_STATIC_INTERPRETER_ENABLE`.
*
* This is intended for use by user-provided CLI command handlers.
*
* @param[in] aFmt A pointer to the format string.
* @param[in] ... A matching list of arguments.
@@ -124,7 +205,11 @@ void otCliOutputBytes(const uint8_t *aBytes, uint8_t aLength);
void otCliOutputFormat(const char *aFmt, ...) OT_TOOL_PRINTF_STYLE_FORMAT_ARG_CHECK(1, 2);
/**
* Write error code to the CLI console
* Write a given error code as the result of previous command to the static CLI interpreter output.
*
* Requires `OPENTHREAD_CONFIG_CLI_STATIC_INTERPRETER_ENABLE`.
*
* This is intended for use by user-provided CLI command handlers.
*
* If the @p aError is `OT_ERROR_PENDING` nothing will be outputted.
*
@@ -133,7 +218,7 @@ void otCliOutputFormat(const char *aFmt, ...) OT_TOOL_PRINTF_STYLE_FORMAT_ARG_CH
void otCliAppendResult(otError aError);
/**
* Callback to write the OpenThread Log to the CLI console
* Callback to write the OpenThread Log to the static CLI interpreter output.
*
* @param[in] aLogLevel The log level.
* @param[in] aLogRegion The log region.
@@ -148,6 +233,8 @@ void otCliPlatLogv(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFo
*
* Available when `OPENTHREAD_CONFIG_CLI_VENDOR_COMMANDS_ENABLE` is enabled and
* `OPENTHREAD_CONFIG_CLI_MAX_USER_CMD_ENTRIES` is greater than 1.
*
* Requires `OPENTHREAD_CONFIG_CLI_STATIC_INTERPRETER_ENABLE`.
*/
extern void otCliVendorSetUserCommands(void);
+51
View File
@@ -567,6 +567,24 @@ otError otDatasetGeneratePskc(const char *aPassPhrase,
*/
otError otNetworkNameFromString(otNetworkName *aNetworkName, const char *aNameString);
/**
* Indicates whether or not the given Operational Dataset TLVs is a valid Active or Pending Dataset.
*
* A valid Active Dataset MUST contain all the required TLVs (Active Timestamp, Channel, Channel Mask, Extended PAN ID,
* Mesh-Local Prefix, Network Key, Network Name, PAN ID, PSKc, and Security Policy).
*
* A valid Pending Dataset MUST contain all the required TLVs for an Active Dataset and additionally MUST contain
* Pending Timestamp and Delay Timer TLVs.
*
* This method also checks whether there are duplicated TLVs or the TLVs are not well-formed in the @p aDatasetTlvs.
*
* @param[in] aDatasetTlvs A pointer to dataset TLVs.
* @param[in] aActive TRUE for Active Dataset, FALSE for Pending Dataset.
*
* @returns TRUE if @p aDatasetTlvs is a valid Dataset, FALSE otherwise.
*/
bool otDatasetIsValid(const otOperationalDatasetTlvs *aDatasetTlvs, bool aActive);
/**
* Parses an Operational Dataset from a given `otOperationalDatasetTlvs`.
*
@@ -578,6 +596,21 @@ otError otNetworkNameFromString(otNetworkName *aNetworkName, const char *aNameSt
*/
otError otDatasetParseTlvs(const otOperationalDatasetTlvs *aDatasetTlvs, otOperationalDataset *aDataset);
/**
* Compares two Operational Dataset TLVs to determine if they contain the same set of TLVs.
*
* This function performs a deep comparison. It parses both @p aDatasetTlvsA and @p aDatasetTlvsB and checks if
* they contain the exact same set of TLVs (same type and same value). The order of TLVs within the
* `otOperationalDatasetTlvs` does not matter.
*
* @param[in] aDatasetTlvsA A pointer to dataset TLVs A. Must not be NULL.
* @param[in] aDatasetTlvsB A pointer to dataset TLVs B. Must not be NULL.
*
* @returns TRUE if the two Operational Dataset TLVs match, FALSE otherwise (e.g., if any TLV differs,
* is missing, or if the TLVs are not well-formed).
*/
bool otDatasetTlvsCompare(const otOperationalDatasetTlvs *aDatasetTlvsA, const otOperationalDatasetTlvs *aDatasetTlvsB);
/**
* Converts a given Operational Dataset to `otOperationalDatasetTlvs`.
*
@@ -600,6 +633,24 @@ void otDatasetConvertToTlvs(const otOperationalDataset *aDataset, otOperationalD
*/
otError otDatasetUpdateTlvs(const otOperationalDataset *aDataset, otOperationalDatasetTlvs *aDatasetTlvs);
/**
* Indicates whether or not a given Operational Dataset (in TLVs format) affects connectivity.
*
* A Dataset affects connectivity if it contains a different Channel, PAN ID, Mesh Local Prefix, Network Key, or
* Security Policy than the current values in use.
*
* The following security policy changes are considered to affect connectivity:
* - Disabling routers (R bit: 1 to 0).
* - Enabling non-CCM routers (NCR bit: 0 to 1).
* - Increasing the version threshold for routing (VR field).
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aDatasetTlvs A pointer to Operational Dataset TLVs.
*
* @returns TRUE if @p aDatasetTlvs affects connectivity, FALSE otherwise.
*/
bool otDatasetAffectsConnectivity(otInstance *aInstance, const otOperationalDatasetTlvs *aDatasetTlvs);
/**
* @}
*/
+1 -1
View File
@@ -52,7 +52,7 @@ extern "C" {
*
* @note This number versions both OpenThread platform and user APIs.
*/
#define OPENTHREAD_API_VERSION (580)
#define OPENTHREAD_API_VERSION (605)
/**
* @addtogroup api-instance
+71 -3
View File
@@ -264,17 +264,59 @@ enum
OT_IP6_PROTO_DST_OPTS = 60, ///< Destination Options for IPv6
};
/**
* Initializes the IPv6 interface and its external address pools.
*
* Requires `OPENTHREAD_CONFIG_IP6_INIT_EXT_ADDR_POOL_ENABLE`.
*
* It provides the memory buffers for the external unicast and multicast address pools and must be called before
* enabling the IPv6 interface.
*
* The provided memory buffers MUST persist and remain valid as long as the OpenThread instance is initialized.
* OpenThread will use these provided buffers to manage the pools of externally added unicast and multicast
* addresses (i.e., those added via `otIp6AddUnicastAddress()` and `otIp6SubscribeMulticastAddress()`).
*
* This function can only be called once. Subsequent calls will return `OT_ERROR_ALREADY`.
*
* The `OPENTHREAD_CONFIG_IP6_INIT_EXT_ADDR_POOL_ENABLE` feature and this function allow the external unicast/multicast
* address pools to be configured at run-time after OpenThread instance initialization, rather than build-time.
* When this feature is disabled, the build-time configs `OPENTHREAD_CONFIG_IP6_MAX_EXT_UCAST_ADDRS` and
* `OPENTHREAD_CONFIG_IP6_MAX_EXT_MCAST_ADDRS` specify the pool sizes used by the OpenThread stack.
*
* This feature allows the OpenThread stack to be compiled as a library without specifying the address pool sizes.
* It delegates the configuration of the pools to the next layer, allowing the OpenThread stack to be integrated into
* various projects without requiring a new OpenThread stack configuration to be built.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aUnicastAddrPool A pointer to an array of `otNetifAddress`.
* @param[in] aUnicastAddrPoolSize The number of entries in @p aUnicastAddrPool.
* @param[in] aMulticastAddrPool A pointer to an array of `otNetifMulticastAddress`.
* @param[in] aMulticastAddrPoolSize The number of entries in @p aMulticastAddrPool.
*
* @retval OT_ERROR_NONE Successfully initialized the IPv6 interface.
* @retval OT_ERROR_ALREADY The IPv6 interface is already initialized.
*/
otError otIp6Init(otInstance *aInstance,
otNetifAddress *aUnicastAddrPool,
uint16_t aUnicastAddrPoolSize,
otNetifMulticastAddress *aMulticastAddrPool,
uint16_t aMulticastAddrPoolSize);
/**
* Brings the IPv6 interface up or down.
*
* Call this to enable or disable IPv6 communication.
*
* When `OPENTHREAD_CONFIG_IP6_INIT_EXT_ADDR_POOL_ENABLE` is enabled, `otIp6Init()` MUST be called prior to calling
* this function. If it is not, this function will return `OT_ERROR_INVALID_STATE`.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aEnabled TRUE to enable IPv6, FALSE otherwise.
*
* @retval OT_ERROR_NONE Successfully brought the IPv6 interface up/down.
* @retval OT_ERROR_INVALID_STATE IPv6 interface is not available since device is operating in raw-link mode
* (applicable only when `OPENTHREAD_CONFIG_LINK_RAW_ENABLE` feature is enabled).
* (applicable only when `OPENTHREAD_CONFIG_LINK_RAW_ENABLE` feature is enabled),
* or not initialized under `OPENTHREAD_CONFIG_IP6_INIT_EXT_ADDR_POOL_ENABLE`.
*/
otError otIp6SetEnabled(otInstance *aInstance, bool aEnabled);
@@ -292,7 +334,8 @@ bool otIp6IsEnabled(otInstance *aInstance);
* Adds a Network Interface Address to the Thread interface.
*
* The passed-in instance @p aAddress is copied by the Thread interface. The Thread interface only
* supports a fixed number of externally added unicast addresses. See `OPENTHREAD_CONFIG_IP6_MAX_EXT_UCAST_ADDRS`.
* supports a fixed number of externally added unicast addresses. See `OPENTHREAD_CONFIG_IP6_MAX_EXT_UCAST_ADDRS`
* and `OPENTHREAD_CONFIG_IP6_INIT_EXT_ADDR_POOL_ENABLE`.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aAddress A pointer to a Network Interface Address.
@@ -339,7 +382,9 @@ bool otIp6HasUnicastAddress(otInstance *aInstance, const otIp6Address *aAddress)
* Subscribes the Thread interface to a Network Interface Multicast Address.
*
* The passed in instance @p aAddress will be copied by the Thread interface. The Thread interface only
* supports a fixed number of externally added multicast addresses. See `OPENTHREAD_CONFIG_IP6_MAX_EXT_MCAST_ADDRS`.
* supports a fixed number of externally added multicast addresses. See `OPENTHREAD_CONFIG_IP6_MAX_EXT_MCAST_ADDRS`
* and `OPENTHREAD_CONFIG_IP6_INIT_EXT_ADDR_POOL_ENABLE`.
*
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aAddress A pointer to an IP Address.
@@ -560,6 +605,29 @@ void otIp6RemoveAllUnsecurePorts(otInstance *aInstance);
*/
const uint16_t *otIp6GetUnsecurePorts(otInstance *aInstance, uint8_t *aNumEntries);
/**
* Sets whether to allow link-local unsecure IPv6 datagrams when the Thread role is disabled.
*
* Available only when `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE` is enabled. This is intended for testing. By default,
* this is disabled (i.e., unsecure traffic is always dropped regardless of the device's role).
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aAllow TRUE to allow, FALSE otherwise.
*/
void otIp6SetAllowUnsecureWhenDisabled(otInstance *aInstance, bool aAllow);
/**
* Indicates whether allowing link-local unsecure IPv6 datagrams when the Thread role is disabled is enabled.
*
* Available only when `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE` is enabled.
*
* @param[in] aInstance A pointer to an OpenThread instance.
*
* @retval TRUE Does allow unsecure IPv6 datagrams when the Thread role is disabled.
* @retval FALSE Does not allow unsecure IPv6 datagrams when the Thread role is disabled.
*/
bool otIp6IsUnsecureAllowedWhenDisabled(otInstance *aInstance);
/**
* Test if two IPv6 addresses are the same.
*
+52 -6
View File
@@ -39,6 +39,7 @@
#include <stdint.h>
#include <openthread/error.h>
#include <openthread/instance.h>
#include <openthread/platform/logging.h>
#include <openthread/platform/toolchain.h>
@@ -56,24 +57,69 @@ extern "C" {
*/
/**
* Returns the current log level.
* Returns the current log level for a given OpenThread instance.
*
* If dynamic log level feature `OPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE` is enabled, this function returns the
* currently set dynamic log level. Otherwise, this function returns the build-time configured log level.
* currently set dynamic log level:
* - In a single-instance configuration, it returns the instance's log level.
* - In a multi-instance configuration, it returns the instance-specific log level if it has been explicitly set
* (see `otSetLogLevel()`). Otherwise, it returns the global log level (see `otLoggingGetLevel()`).
*
* If the dynamic log level feature is not enabled, this function returns the build-time configured log level.
*
* @param[in] aInstance The OpenThread instance.
*
* @returns The log level.
*/
otLogLevel otGetLogLevel(otInstance *aInstance);
/**
* Sets the log level for a given OpenThread instance.
*
* @note This function requires `OPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE=1`.
*
* In a single-instance configuration, this function sets the log level for the instance.
*
* In a multi-instance configuration (`OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE`), if
* `OPENTHREAD_CONFIG_LOG_INSTANCE_AWARE_API_ENABLE` is not enabled, this function returns `OT_ERROR_NOT_CAPABLE`.
* When the log level is explicitly set on an instance, it overrides the global log level set using
* `otLoggingSetLevel()`.
*
* @param[in] aInstance The OpenThread instance.
* @param[in] aLogLevel The log level.
*
* @retval OT_ERROR_NONE Successfully updated the log level.
* @retval OT_ERROR_INVALID_ARGS Log level value is invalid.
* @retval OT_ERROR_NOT_CAPABLE Instance-aware logging is not enabled in a multi-instance configuration.
*/
otError otSetLogLevel(otInstance *aInstance, otLogLevel aLogLevel);
/**
* Returns the current global log level.
*
* In a single-instance configuration, this function behaves the same as `otGetLogLevel()`.
* In a multi-instance configuration, it returns the global log level which is used for all instances.
*
* @returns The global log level.
*/
otLogLevel otLoggingGetLevel(void);
/**
* Sets the log level.
* Sets the global log level.
*
* @note This function requires `OPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE=1`.
*
* @param[in] aLogLevel The log level.
* In a single-instance configuration, this function behaves the same as `otSetLogLevel()` (which is the recommended
* function to use).
*
* @retval OT_ERROR_NONE Successfully updated log level.
* @retval OT_ERROR_INVALID_ARGS Log level value is invalid.
* In a multi-instance configuration, it sets the global log level which is used by all instances. The log level can
* be explicitly set on a specific instance using `otSetLogLevel()`, which will then be used instead of the global
* value.
*
* @param[in] aLogLevel The log level.
*
* @retval OT_ERROR_NONE Successfully updated the log level.
* @retval OT_ERROR_INVALID_ARGS Log level value is invalid.
*/
otError otLoggingSetLevel(otLogLevel aLogLevel);
+1 -1
View File
@@ -234,7 +234,7 @@ void otMessageSetLoopbackToHostAllowed(otMessage *aMessage, bool aAllowLoopbackT
* Indicates whether the given message may be looped back in a case of a multicast destination address.
*
* If @p aMessage is used along with an `otMessageInfo`, the `mMulticastLoop` field from `otMessageInfo` structure
* takes precedence and will be used instead of the the value set on @p aMessage.
* takes precedence and will be used instead of the value set on @p aMessage.
*
* This API is mainly intended for use along with `otIp6Send()` which expects an already prepared IPv6 message.
*
+1 -1
View File
@@ -73,7 +73,7 @@ typedef struct otBorderRouterConfig
bool mOnMesh : 1; ///< Whether this prefix is considered on-mesh.
bool mStable : 1; ///< Whether this configuration is considered Stable Network Data.
bool mNdDns : 1; ///< Whether this border router can supply DNS information via ND.
bool mDp : 1; ///< Whether prefix is a Thread Domain Prefix (added since Thread 1.2).
bool mDp : 1; ///< Reserved (previously Thread Domain Prefix flag).
uint16_t mRloc16; ///< The border router's RLOC16 (value ignored on config add).
} otBorderRouterConfig;
+28
View File
@@ -425,6 +425,20 @@ const char *otThreadGetVendorSwVersion(otInstance *aInstance);
*/
const char *otThreadGetVendorAppUrl(otInstance *aInstance);
/**
* Represents an unspecified Vendor OUI.
*/
#define OT_THREAD_UNSPECIFIED_VENDOR_OUI (0xffffffff)
/**
* Get the vendor OUI-24
*
* @param[in] aInstance A pointer to an OpenThread instance.
*
* @returns The vendor OUI-24 value in hex format, or `OT_THREAD_UNSPECIFIED_VENDOR_OUI` is not specified.
*/
uint32_t otThreadGetVendorOui(otInstance *aInstance);
/**
* Set the vendor name string.
*
@@ -494,6 +508,20 @@ otError otThreadSetVendorSwVersion(otInstance *aInstance, const char *aVendorSwV
*/
otError otThreadSetVendorAppUrl(otInstance *aInstance, const char *aVendorAppUrl);
/**
* Set the vendor OUI-24.
*
* Requires `OPENTHREAD_CONFIG_NET_DIAG_VENDOR_INFO_SET_API_ENABLE`.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aVendorOui The vendor OUI-24 value in Hexadecimal representation (e.g., OUI 64-16-66 is represented as
* `0x641666`). Must be a 24-bit value.
*
* @retval OT_ERROR_NONE Successfully set the vendor OUI.
* @retval OT_ERROR_INVALID_ARGS @p aVendorOui is not a valid 24-bit value.
*/
otError otThreadSetVendorOui(otInstance *aInstance, uint32_t aVendorOui);
/**
* Callback function pointer to notify when a Network Diagnostic Reset request message is received for the
* `OT_NETWORK_DIAGNOSTIC_TLV_NON_PREFERRED_CHANNELS` TLV.
+44 -31
View File
@@ -74,10 +74,10 @@ extern "C" {
#define OT_BLE_ADV_INTERVAL_MAX 0x4000
/**
* Default interval for advertising packet (ms).
* Default interval for advertising packet in OT_BLE_ADV_INTERVAL_UNIT units (100 ms).
*/
#define OT_BLE_ADV_INTERVAL_DEFAULT 100
#define OT_BLE_ADV_INTERVAL_DEFAULT 160
/**
* Unit used to calculate interval duration (0.625ms).
@@ -104,13 +104,13 @@ extern "C" {
#define OT_BLE_ATT_MTU_DEFAULT 23
/**
* Default power value for BLE.
* Default Tx power value for BLE in dBm.
*/
#define OT_BLE_DEFAULT_POWER 0
/**
* TOBLE service UUID
* ToBLE service UUID (a GATT service UUID for Thread over BLE)
*/
#define OT_TOBLE_SERVICE_UUID 0xfffb
@@ -130,7 +130,7 @@ typedef struct otBleLinkCapabilities
*/
typedef struct otBleRadioPacket
{
uint8_t *mValue; ///< The value of an attribute
uint8_t *mValue; ///< Pointer to the packet data
uint16_t mLength; ///< Length of the @p mValue.
int8_t mPower; ///< Transmit/receive power in dBm.
} otBleRadioPacket;
@@ -171,18 +171,16 @@ otError otPlatBleDisable(otInstance *aInstance);
* @section Bluetooth Low Energy GAP.
***************************************************************************/
/**
* Gets BLE Advertising buffer.
* Gets a platform-provided buffer for BLE advertising data.
*
* @note This function shall be used only for BLE Peripheral role.
* Returned buffer should have enough space to fit max advertisement
* defined by specification.
* The platform must provide a buffer of at least @p OT_TCAT_ADVERTISEMENT_MAX_LEN bytes.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aAdvertisementData The formatted TCAT advertisement frame.
* @param[in] aAdvertisementLen The TCAT advertisement frame length.
* @param[in] aInstance The OpenThread instance structure.
* @param[out] aAdvertisementBuffer A pointer to be set to the platform-provided advertisement buffer.
*
* @retval OT_ERROR_NONE Advertising procedure has been started.
* @retval OT_ERROR_NO_BUFS No bufferspace available.
* @retval OT_ERROR_NONE Successfully retrieved the advertisement buffer.
* @retval OT_ERROR_NO_BUFS No buffer space available.
*/
otError otPlatBleGetAdvertisementBuffer(otInstance *aInstance, uint8_t **aAdvertisementBuffer);
@@ -190,13 +188,15 @@ otError otPlatBleGetAdvertisementBuffer(otInstance *aInstance, uint8_t **aAdvert
* Sets BLE Advertising data.
*
* @note This function shall be used only for BLE Peripheral role.
* It shall only be called while advertising is not active.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aAdvertisementData The formatted TCAT advertisement frame.
* @param[in] aAdvertisementLen The TCAT advertisement frame length.
* @param[in] aAdvertisementLen The length of the @p aAdvertisementData frame.
*
* @retval OT_ERROR_NONE Advertising procedure has been started.
* @retval OT_ERROR_NONE Advertising data set successfully.
* @retval OT_ERROR_INVALID_STATE BLE Device is in invalid state.
* @retval OT_ERROR_FAILED Setting of data failed.
* @retval OT_ERROR_INVALID_ARGS Invalid value has been supplied.
*/
otError otPlatBleGapAdvSetData(otInstance *aInstance, uint8_t *aAdvertisementData, uint16_t aAdvertisementLen);
@@ -205,12 +205,14 @@ otError otPlatBleGapAdvSetData(otInstance *aInstance, uint8_t *aAdvertisementDat
* Updates BLE Advertising data.
*
* @note This function shall be used only for BLE Peripheral role.
* It shall only be called while advertising is active.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aAdvertisementData The formatted TCAT advertisement frame.
* @param[in] aAdvertisementLen The TCAT advertisement frame length.
* @param[in] aAdvertisementLen The length of the @p aAdvertisementData frame.
*
* @retval OT_ERROR_NONE Advertising procedure has been started.
* @retval OT_ERROR_NONE Advertising data updated successfully.
* @retval OT_ERROR_INVALID_STATE BLE Device is in invalid state.
* @retval OT_ERROR_FAILED Update of data failed.
* @retval OT_ERROR_INVALID_ARGS Invalid value has been supplied.
*/
@@ -222,11 +224,15 @@ otError otPlatBleGapAdvUpdateData(otInstance *aInstance, uint8_t *aAdvertisement
* The BLE device shall use undirected advertising with no filter applied.
* A single BLE Advertising packet must be sent on all advertising
* channels (37, 38 and 39).
* The advertising shall remain active until either otPlatBleGapAdvStop() is
* called or a BLE Central Device connects (otPlatBleGapOnConnected()).
* The BLE platform is not obliged to exactly match the requested interval
* between subsequent advertising packets: it is a requested/desired value.
*
* @note This function shall be used only for BLE Peripheral role.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aInterval The interval between subsequent advertising packets
* @param[in] aInterval The requested interval between subsequent advertising packets
* in OT_BLE_ADV_INTERVAL_UNIT units.
* Shall be within OT_BLE_ADV_INTERVAL_MIN and
* OT_BLE_ADV_INTERVAL_MAX range or OT_BLE_ADV_INTERVAL_DEFAULT
@@ -251,8 +257,8 @@ otError otPlatBleGapAdvStart(otInstance *aInstance, uint16_t aInterval);
otError otPlatBleGapAdvStop(otInstance *aInstance);
/**
* The BLE driver calls this method to notify OpenThread that a BLE Central Device has
* been connected.
* The BLE driver calls this function to notify OpenThread that a BLE Central Device has
* been connected. The BLE driver MUST stop advertising before calling this function.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aConnectionId The identifier of the open connection.
@@ -260,8 +266,9 @@ otError otPlatBleGapAdvStop(otInstance *aInstance);
extern void otPlatBleGapOnConnected(otInstance *aInstance, uint16_t aConnectionId);
/**
* The BLE driver calls this method to notify OpenThread that the BLE Central Device
* has been disconnected.
* The BLE driver calls this function to notify OpenThread that the BLE Central Device
* has been disconnected. The BLE driver MUST NOT start advertising before or after this
* call: this is controlled explicitly via otPlatBleGapAdvStart().
*
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aConnectionId The identifier of the closed connection.
@@ -272,7 +279,11 @@ extern void otPlatBleGapOnDisconnected(otInstance *aInstance, uint16_t aConnecti
* Disconnects BLE connection.
*
* The BLE device shall use the Remote User Terminated Connection (0x13) reason
* code when disconnecting from the peer BLE device..
* code when disconnecting from the peer BLE device.
*
* This function only triggers the disconnection procedure. When OT_ERROR_NONE is returned,
* the platform MUST report completion of the disconnection asynchronously, by invoking
* otPlatBleGapOnDisconnected().
*
* @param[in] aInstance The OpenThread instance structure.
*
@@ -297,7 +308,7 @@ otError otPlatBleGapDisconnect(otInstance *aInstance);
otError otPlatBleGattMtuGet(otInstance *aInstance, uint16_t *aMtu);
/**
* The BLE driver calls this method to notify OpenThread that ATT_MTU has been updated.
* The BLE driver calls this function to notify OpenThread that ATT_MTU has been updated.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aMtu The updated ATT_MTU value. It MUST be >=OT_BLE_ATT_MTU_MIN.
@@ -315,7 +326,7 @@ extern void otPlatBleGattOnMtuUpdate(otInstance *aInstance, uint16_t aMtu);
*
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aHandle The handle of the attribute to be indicated.
* @param[in] aPacket A pointer to the packet contains value to be indicated.
* @param[in] aPacket A pointer to the packet containing the value to be indicated.
*
* @retval OT_ERROR_NONE ATT Handle Value Indication has been sent.
* @retval OT_ERROR_INVALID_STATE BLE Device is in invalid state.
@@ -325,29 +336,31 @@ extern void otPlatBleGattOnMtuUpdate(otInstance *aInstance, uint16_t aMtu);
otError otPlatBleGattServerIndicate(otInstance *aInstance, uint16_t aHandle, const otBleRadioPacket *aPacket);
/**
* The BLE driver calls this method to notify OpenThread that an ATT Write Request
* The BLE driver calls this function to notify OpenThread that an ATT Write Request
* packet has been received.
*
* @note This function shall be used only for GATT Server.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aHandle The handle of the attribute to be written.
* @param[in] aPacket A pointer to the packet contains value to be written to the attribute.
* @param[in] aPacket A pointer to the packet containing the value to be written to the attribute.
*/
extern void otPlatBleGattServerOnWriteRequest(otInstance *aInstance, uint16_t aHandle, const otBleRadioPacket *aPacket);
/**
* Function to retrieve from platform BLE link capabilities.
* Retrieve BLE link capabilities from the platform.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[out] aBleLinkCapabilities The pointer to retrieve the BLE ling capabilities.
* @param[out] aBleLinkCapabilities The pointer to retrieve the BLE link capabilities into.
*/
void otPlatBleGetLinkCapabilities(otInstance *aInstance, otBleLinkCapabilities *aBleLinkCapabilities);
/**
* Function to retrieve from platform multiradio support of BLE and IEEE.
* Check if the platform has multi-radio support for BLE and IEEE 802.15.4.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aInstance The OpenThread instance structure.
*
* @returns TRUE if the platform supports simultaneous BLE and IEEE 802.15.4 operation, FALSE otherwise.
*/
bool otPlatBleSupportsMultiRadio(otInstance *aInstance);
/**
+16 -2
View File
@@ -123,6 +123,9 @@ typedef struct otCryptoKey
* @struct otCryptoContext
*
* Stores the context object for platform APIs.
*
* If `OPENTHREAD_CONFIG_CRYPTO_PLATFORM_ALLOCS_CONTEXT` is enabled, the platform allocates and populates this.
* Otherwise OpenThread core allocates and populates this.
*/
typedef struct otCryptoContext
{
@@ -325,6 +328,9 @@ void otPlatCryptoFree(void *aPtr);
* @retval OT_ERROR_FAILED Failed to initialize HMAC operation.
* @retval OT_ERROR_INVALID_ARGS @p aContext was NULL
*
* @note If `OPENTHREAD_CONFIG_CRYPTO_PLATFORM_ALLOCS_CONTEXT` is enabled, @p aContext is populated by the platform.
* Otherwise OpenThread core allocates and populates it.
*
* @note The platform driver shall point the context to the correct object such as psa_mac_operation_t or
* mbedtls_md_context_t.
*/
@@ -389,6 +395,9 @@ otError otPlatCryptoHmacSha256Finish(otCryptoContext *aContext, uint8_t *aBuf, s
* @retval OT_ERROR_INVALID_ARGS @p aContext was NULL
* @retval OT_ERROR_NO_BUFS Cannot allocate the context.
*
* @note If `OPENTHREAD_CONFIG_CRYPTO_PLATFORM_ALLOCS_CONTEXT` is enabled, @p aContext is populated by the platform.
* Otherwise OpenThread core allocates and populates it.
*
* @note The platform driver shall point the context to the correct object such as psa_key_id
* or mbedtls_aes_context_t.
*/
@@ -435,10 +444,13 @@ otError otPlatCryptoAesFree(otCryptoContext *aContext);
*
* @param[in] aContext Context for HKDF operation.
*
* @retval OT_ERROR_NONE Successfully Initialised AES operation.
* @retval OT_ERROR_FAILED Failed to Initialise AES operation.
* @retval OT_ERROR_NONE Successfully Initialised HKDF operation.
* @retval OT_ERROR_FAILED Failed to Initialise HKDF operation.
* @retval OT_ERROR_INVALID_ARGS @p aContext was NULL
*
* @note If `OPENTHREAD_CONFIG_CRYPTO_PLATFORM_ALLOCS_CONTEXT` is enabled, @p aContext is populated by the platform.
* Otherwise OpenThread core allocates and populates it.
*
* @note The platform driver shall point the context to the correct object such as psa_key_derivation_operation_t
* or HmacSha256::Hash
*/
@@ -499,6 +511,8 @@ otError otPlatCryptoHkdfDeinit(otCryptoContext *aContext);
* @retval OT_ERROR_FAILED Failed to initialise SHA-256 operation.
* @retval OT_ERROR_INVALID_ARGS @p aContext was NULL
*
* @note If `OPENTHREAD_CONFIG_CRYPTO_PLATFORM_ALLOCS_CONTEXT` is enabled, @p aContext is populated by the platform.
* Otherwise OpenThread core allocates and populates it.
*
* @note The platform driver shall point the context to the correct object such as psa_hash_operation_t
* or mbedtls_sha256_context.
+2 -3
View File
@@ -53,8 +53,7 @@ extern "C" {
typedef struct otPlatDsoConnection otPlatDsoConnection;
/**
* Can be used by DSO platform implementation to get the the OpenThread instance associated with a
* connection instance.
* Can be used by DSO platform implementation to get the OpenThread instance associated with a connection instance.
*
* @param[in] aConnection A pointer to the DSO connection.
*
@@ -124,7 +123,7 @@ extern void otPlatDsoHandleConnected(otPlatDsoConnection *aConnection);
* Passes the ownership of the @p aMessage to the DSO platform layer, and the platform implementation is
* expected to free the message once it is no longer needed.
*
* The @p aMessage contains the DNS message (starting with DNS header). Note that it does not contain the the length
* The @p aMessage contains the DNS message (starting with DNS header). Note that it does not contain the length
* field that is needed when sending over TLS/TCP transport. The platform layer MUST therefore include the length
* field when passing the message to TLS/TCP layer.
*
+16 -12
View File
@@ -47,6 +47,15 @@
extern "C" {
#endif
/**
* @addtogroup plat-infra-if
*
* @brief
* This module includes the platform abstraction for the adjacent infrastructure network interface.
*
* @{
*/
#define OT_PLAT_INFRA_IF_MAX_LINK_LAYER_ADDR_LENGTH 16 ///< Maximum InfraIf Link-layer address length.
/**
@@ -58,30 +67,23 @@ typedef struct otPlatInfraIfLinkLayerAddress
uint8_t mLength; ///< The address length (number of bytes).
} otPlatInfraIfLinkLayerAddress;
/**
* @addtogroup plat-infra-if
*
* @brief
* This module includes the platform abstraction for the adjacent infrastructure network interface.
*
* @{
*/
/**
* Tells whether an infra interface has the given IPv6 address assigned.
*
* @param[in] aInstance The OpenThread instance.
* @param[in] aInfraIfIndex The index of the infra interface.
* @param[in] aAddress The IPv6 address.
*
* @returns TRUE if the infra interface has given IPv6 address assigned, FALSE otherwise.
*/
bool otPlatInfraIfHasAddress(uint32_t aInfraIfIndex, const otIp6Address *aAddress);
bool otPlatInfraIfHasAddress(otInstance *aInstance, uint32_t aInfraIfIndex, const otIp6Address *aAddress);
/**
* Sends an ICMPv6 Neighbor Discovery message on given infrastructure interface.
*
* See RFC 4861: https://tools.ietf.org/html/rfc4861.
*
* @param[in] aInstance The OpenThread instance.
* @param[in] aInfraIfIndex The index of the infrastructure interface this message is sent to.
* @param[in] aDestAddress The destination address this message is sent to.
* @param[in] aBuffer The ICMPv6 message buffer. The ICMPv6 checksum is left zero and the
@@ -94,7 +96,8 @@ bool otPlatInfraIfHasAddress(uint32_t aInfraIfIndex, const otIp6Address *aAddres
* @retval OT_ERROR_NONE Successfully sent the ICMPv6 message.
* @retval OT_ERROR_FAILED Failed to send the ICMPv6 message.
*/
otError otPlatInfraIfSendIcmp6Nd(uint32_t aInfraIfIndex,
otError otPlatInfraIfSendIcmp6Nd(otInstance *aInstance,
uint32_t aInfraIfIndex,
const otIp6Address *aDestAddress,
const uint8_t *aBuffer,
uint16_t aBufferLength);
@@ -145,6 +148,7 @@ extern otError otPlatInfraIfStateChanged(otInstance *aInstance, uint32_t aInfraI
*
* OpenThread will call this method periodically to monitor the presence or change of NAT64 prefix.
*
* @param[in] aInstance The OpenThread instance.
* @param[in] aInfraIfIndex The index of the infrastructure interface to discover the NAT64 prefix.
*
* @retval OT_ERROR_NONE Successfully requested NAT64 prefix discovery.
@@ -155,7 +159,7 @@ extern otError otPlatInfraIfStateChanged(otInstance *aInstance, uint32_t aInfraI
* discovery). The priority of the discovered prefix is lower than that of the prefix discovered via Router
* Advertisements PREF64 option (RFC 8781).
*/
otError otPlatInfraIfDiscoverNat64Prefix(uint32_t aInfraIfIndex);
otError otPlatInfraIfDiscoverNat64Prefix(otInstance *aInstance, uint32_t aInfraIfIndex);
/**
* The infra interface driver calls this method to notify OpenThread that
+41 -2
View File
@@ -35,6 +35,7 @@
#ifndef OPENTHREAD_PLATFORM_LOGGING_H_
#define OPENTHREAD_PLATFORM_LOGGING_H_
#include <openthread/instance.h>
#include <openthread/platform/toolchain.h>
#ifdef __cplusplus
@@ -140,6 +141,9 @@ typedef enum otLogRegion
/**
* Outputs logs.
*
* This platform API is used to output logs when the configuration `OPENTHREAD_CONFIG_LOG_INSTANCE_AWARE_API_ENABLE`
* is disabled. When the configuration is enabled, `otPlatLogOutput()` is used instead.
*
* Note that the support for log region is removed. The OT core will always emit all logs with `OT_LOG_REGION_CORE`
* as @p aLogRegion.
*
@@ -151,11 +155,31 @@ typedef enum otLogRegion
void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
OT_TOOL_PRINTF_STYLE_FORMAT_ARG_CHECK(3, 4);
/**
* Outputs a log line.
*
* This platform API is an alternative to `otPlatLog()` and is used when the configuration
* `OPENTHREAD_CONFIG_LOG_INSTANCE_AWARE_API_ENABLE` is enabled.
*
* Unlike `otPlatLog()`, this API also provides a pointer to the OpenThread instance (`otInstance*`) from which the
* log is generated. This is particularly helpful in a multi-instance setup to distinguish logs from different
* instances. Additionally, it provides the log line as a fully formatted null-terminated string instead of
* a format string and variable arguments.
*
* @param[in] aInstance A pointer to the OpenThread instance.
* @param[in] aLogLevel The log level.
* @param[in] aLogLine A pointer to the null-terminated string containing the log line.
*/
void otPlatLogOutput(otInstance *aInstance, otLogLevel aLogLevel, const char *aLogLine);
/**
* Handles OpenThread log level changes.
*
* This platform function is called whenever the OpenThread log level changes.
* This platform function is optional since an empty weak implementation has been provided.
* This platform function is optional. An empty weak implementation is provided by OpenThread core.
*
* This platform function is called whenever the OpenThread log level changes:
* - In a single-instance configuration, this is called when the log level changes.
* - In a multi-instance configuration, this is called when the global log level changes.
*
* @note Only applicable when `OPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE=1`.
*
@@ -163,6 +187,21 @@ void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat
*/
void otPlatLogHandleLevelChanged(otLogLevel aLogLevel);
/**
* Handles OpenThread instance-specific log level changes.
*
* This platform function is optional. An empty weak implementation is provided by OpenThread core.
*
* This platform function is called whenever the instance-specific log level changes:
* - In a single-instance configuration, this is called along with `otPlatLogHandleLevelChanged()`.
* - In a multi-instance configuration, if `OPENTHREAD_CONFIG_LOG_INSTANCE_AWARE_API_ENABLE` is used, this is called
* when the instance-specific log level changes.
*
* @param[in] aInstance A pointer to the OpenThread instance.
* @param[in] aLogLevel The new OpenThread log level for the instance.
*/
void otPlatLogHandleLogLevelChanged(otInstance *aInstance, otLogLevel aLogLevel);
/**
* @}
*/
+1 -1
View File
@@ -359,7 +359,7 @@ typedef struct otRadioFrame
* If `mIsHeaderUpdated` is not set, then the frame counter and key CSL IE not set in the frame by
* OpenThread core and it is the responsibility of the radio platform to assign them. The platform
* must update the frame header (assign counter and CSL IE values) before sending the frame over the air,
* however if the the transmission gets aborted and the frame is never sent over the air (e.g., channel
* however if the transmission gets aborted and the frame is never sent over the air (e.g., channel
* access error) the platform may choose to not update the header. If the platform updates the header,
* it must also set this flag before passing the frame back from the `otPlatRadioTxDone()` callback.
*/
+439
View File
@@ -0,0 +1,439 @@
/*
* 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.
*/
/**
* @file
* @brief
* This file includes the abstraction for the platform TCP
*/
#ifndef OPENTHREAD_PLATFORM_TCP_H_
#define OPENTHREAD_PLATFORM_TCP_H_
#include <stdbool.h>
#include <stdint.h>
#include <openthread/error.h>
#include <openthread/instance.h>
#include <openthread/ip6.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @addtogroup plat-tcp
*
* @brief
* This module includes the platform abstraction for TCP connections and listeners.
*
* All APIs in this module are applicable only when `OPENTHREAD_CONFIG_PLATFORM_TCP_ENABLE` feature is enabled.
*
* @{
*/
/**
* Represents platform-specific data associated with a connection or a listener.
*
* This union is provided to add flexibility for the platform. A platform can choose to store a file descriptor
* (e.g., an `int` for a POSIX socket) or a pointer to an arbitrary context or state structure needed by the
* platform implementation.
*
* The OpenThread stack guarantees that the `otPlatTcpPlatformData` is fully cleared (all bytes set to zero) when a
* new listener or connection instance is initialized.
*
* For an `otPlatTcpListener`, the `otPlatTcpEnableListener()` call provides an opportunity for the platform to allocate
* or update this information. The OpenThread stack guarantees that `otPlatTcpDisableListener()` will be invoked on any
* previously enabled listener, providing a deterministic point for the platform implementation to perform cleanup
* (e.g., deallocating memory or context structures).
*
* For an `otPlatTcpConnection`, the `otPlatTcpConnect()` call or the `otPlatTcpAccept()` callback indicate when a new
* connection instance is provided, allowing the platform data to be initialized. The platform is responsible for
* cleaning up this data either before invoking `otPlatTcpHandleDisconnected()` (which invalidates the connection) or
* from an `otPlatTcpAbort()` call. The OpenThread stack guarantees that it will eventually disconnect or abort any
* active connection, ensuring a reliable cleanup path.
*/
typedef union
{
int mDescriptor; ///< A value (like a file descriptor).
void *mContext; ///< Pointer to arbitrary platform data.
} otPlatTcpPlatformData;
/**
* Represents a TCP listener.
*
* The OpenThread core owns and manages the `otPlatTcpListener` instances. The platform should track the pointers
* to these instances and use them when invoking the callbacks. The `otPlatTcpListener *` can be viewed as
* a "descriptor" or "handle" to the listener.
*/
typedef struct otPlatTcpListener
{
otPlatTcpPlatformData mData; ///< Platform implementation specific data.
} otPlatTcpListener;
/**
* Represents a TCP connection.
*
* The OpenThread core owns and manages the `otPlatTcpConnection` instances. The platform should track the pointers
* to these instances and pass them when invoking the `otPlatTcpHandle*` callbacks. The `otPlatTcpConnection *` can
* be viewed as a "descriptor" or "handle" to the connection.
*
* The `otPlatTcpConnection` instance remains valid as long as the connection is active.
*/
typedef struct otPlatTcpConnection
{
otPlatTcpPlatformData mData; ///< Platform implementation specific data.
} otPlatTcpConnection;
/**
* Represents a TCP socket address.
*/
typedef struct otPlatTcpSockAddr
{
otSockAddr mSockAddr; ///< The socket address (IP address and port number). Use IPv4-mapped IPv6 for IPv4.
uint32_t mIfIndex; ///< Interface index. Zero indicates any/unspecified.
} otPlatTcpSockAddr;
/**
* Defines the reason for a TCP connection disconnection.
*/
typedef enum otPlatTcpDisconnectReason
{
OT_PLAT_TCP_DISCONNECT_REASON_CLOSED, ///< Connection was gracefully closed.
OT_PLAT_TCP_DISCONNECT_REASON_TIMEOUT, ///< Connection timed out (e.g., failed to connect or keepalive failure).
OT_PLAT_TCP_DISCONNECT_REASON_REFUSED, ///< Connection was refused by the peer (RST received during handshake).
OT_PLAT_TCP_DISCONNECT_REASON_RESET, ///< Connection was reset by the peer (RST received on established conn).
OT_PLAT_TCP_DISCONNECT_REASON_ERROR, ///< Connection was aborted due to other errors.
} otPlatTcpDisconnectReason;
/**
* Enables a TCP listener.
*
* The platform should start listening for incoming TCP connections on the provided @p aLocalSockAddr. When an
* incoming connection request is received, the platform must invoke the `otPlatTcpAccept()` callback to accept the
* request.
*
* The @p aLocalSockAddr specifies the local interface, address, and port to bind to. Importantly, the port number
* within @p aLocalSockAddr must not be zero. The IP address may be unspecified (all zeros) to indicate that the
* listener should accept connections on any local address.
*
* @param[in] aListener The TCP listener.
* @param[in] aLocalSockAddr The local socket address to listen on.
*
* @retval OT_ERROR_NONE Successfully enabled or disabled the listener.
* @retval OT_ERROR_ALREADY Already listening on the same port/address.
* @retval OT_ERROR_FAILED Failed to enable the listener.
*/
otError otPlatTcpEnableListener(otPlatTcpListener *aListener, const otPlatTcpSockAddr *aLocalSockAddr);
/**
* Disables a TCP listener.
*
* The platform should stop listening for incoming connections on the socket associated with the listener.
* Any incoming connection requests that have not yet been accepted should be discarded.
*
* @param[in] aListener The TCP listener.
*/
void otPlatTcpDisableListener(otPlatTcpListener *aListener);
/**
* Callback to accept an incoming TCP connection request on an active listener.
*
* This function is implemented and provided by the OpenThread stack for the platform to use.
*
* The callback returns a pointer to an `otPlatTcpConnection` for the new connection. If the callback returns NULL,
* the incoming connection is rejected.
*
* @param[in] aListener The TCP listener.
* @param[in] aPeerSockAddr The peer's socket address.
*
* @returns A pointer for the newly accepted connection, or NULL to reject the connection request.
*/
extern otPlatTcpConnection *otPlatTcpAccept(otPlatTcpListener *aListener, const otPlatTcpSockAddr *aPeerSockAddr);
/**
* Initiates a TCP connection to a peer.
*
* The platform should initiate a TCP connection to the @p aPeerSockAddr.
*
* The @p aLocalSockAddr specifies the local address and port to bind to before connecting. It can be NULL if the
* OpenThread stack does not specify a preference. If provided, fields within @p aLocalSockAddr may still be left
* unspecified (e.g., the IP address can be all zeros, or the port can be zero). In all such cases, the platform
* and the underlying TCP stack should automatically select an appropriate local IP address and/or an ephemeral port.
*
* If `OT_ERROR_NONE` is returned (indicating successful initialization of the connection process), the platform must
* subsequently report the status. Upon successful connection establishment, the platform must invoke the
* `otPlatTcpHandleConnected` callback. If it fails to establish the connection, the `otPlatTcpHandleDisconnected`
* callback must be called to indicate the failure.
*
* @param[in] aConn The TCP connection.
* @param[in] aPeerSockAddr The peer's socket address.
* @param[in] aLocalSockAddr The local socket address. Can be NULL.
*
* @retval OT_ERROR_NONE Successfully initiated the connection.
* @retval OT_ERROR_FAILED Failed to initiate the connection.
*/
otError otPlatTcpConnect(otPlatTcpConnection *aConn,
const otPlatTcpSockAddr *aPeerSockAddr,
const otPlatTcpSockAddr *aLocalSockAddr);
/**
* Indicates whether the TCP connection is currently in the connecting state.
*
* This function is provided by the OpenThread stack. The platform can use it to determine if a TCP connection is still
* waiting for the TCP handshake to complete.
*
* @param[in] aConn The TCP connection.
*
* @retval TRUE The connection is currently in the connecting state.
* @retval FALSE The connection is not in the connecting state.
*/
extern bool otPlatTcpIsConnecting(otPlatTcpConnection *aConn);
/**
* Callback to notify the connection establishment.
*
* This callback is implemented and provided by the OpenThread stack. It must be invoked by the platform to indicate
* that the TCP handshake is complete and that the connection is now established.
*
* The platform must call this after a successful call to `otPlatTcpConnect()` when the connection is established.
* For incoming connection requests (on an `otPlatTcpListener`), the platform must call this after the
* `otPlatTcpAccept()` callback returns successfully and when the connection is established.
*
* @param[in] aConn The TCP connection.
*/
extern void otPlatTcpHandleConnected(otPlatTcpConnection *aConn);
/**
* Notifies the platform that there is pending data for transmission.
*
* This function is called by the OpenThread stack when it has new data for transmission. After this call, the platform
* should indicate when it is ready to accept the data by invoking the `otPlatTcpHandleTxReady()` callback.
*
* The platform can also use `otPlatTcpIsTxPending()` to check if there is pending data for transmission.
*
* It is permissible for the platform implementation to invoke the `otPlatTcpHandleTxReady()` callback directly from
* within `otPlatTcpNotifyTxPending()` before returning, if the underlying TCP transmit buffer is already available.
* The OpenThread stack will handle this correctly.
*
* @param[in] aConn The TCP connection.
*/
void otPlatTcpNotifyTxPending(otPlatTcpConnection *aConn);
/**
* Indicates whether the TCP connection has pending data for transmission.
*
* This function is provided by the OpenThread stack. The platform can use it to check if there is any pending data
* for transmission over the TCP connection.
*
* @param[in] aConn The TCP connection.
*
* @retval TRUE The connection has pending transmit data.
* @retval FALSE The connection does not have pending transmit data.
*/
extern bool otPlatTcpIsTxPending(otPlatTcpConnection *aConn);
/**
* Callback to notify that the platform is ready to accept more transmit data.
*
* This function is implemented and provided by the OpenThread stack for the platform to use.
*
* The platform should invoke this callback when it is ready to accept more data for transmission over the TCP
* connection, in response to a prior `otPlatTcpNotifyTxPending()` call. Upon being called, the OpenThread stack will
* use `otPlatTcpSend()` to provide the pending TX data to the platform. The stack may call `otPlatTcpSend()` multiple
* times during the execution of this callback.
*
* @param[in] aConn The TCP connection.
*/
extern void otPlatTcpHandleTxReady(otPlatTcpConnection *aConn);
/**
* Sends data over an active TCP connection.
*
* This function is called by the OpenThread stack to provide data for the platform to transmit. The data is provided
* in a buffer. The platform should copy as much data as it can from the given buffer into its underlying platform
* transmit buffer.
*
* The provided @p aBuffer is temporary. The platform must not store the pointer or assume the content remains valid
* after this function returns. All required data must be copied during this call.
*
* The OpenThread stack typically invokes this function from the `otPlatTcpHandleTxReady()` callback. However, the
* platform implementation must not assume this and should support being called at any time. If there is no space
* available to accept any data, the platform can return zero.
*
* The OpenThread stack may call this function multiple times back-to-back to provide all queued transmit content
* in chunks. The platform should be prepared to handle consecutive calls efficiently.
*
* @param[in] aConn The TCP connection.
* @param[in] aBuffer A pointer to the buffer containing the data to send.
* @param[in] aLength The length (in bytes) of the data in the buffer.
*
* @returns The actual number of bytes accepted for transmission.
*/
uint16_t otPlatTcpSend(otPlatTcpConnection *aConn, const uint8_t *aBuffer, uint16_t aLength);
/**
* Callback to notify the reception of data on a connection.
*
* This function is implemented and provided by the OpenThread stack for the platform to use.
*
* The platform invokes this callback to provide received data to the OpenThread stack. The provided @p aBuffer
* only needs to remain valid for the duration of this call. The OpenThread stack will process and copy the
* bytes as needed, and will not retain the @p aBuffer pointer after the function returns.
*
* Since TCP is a stream protocol, data can arrive in arbitrarily sized chunks. The platform does not need to
* buffer or reassemble these; it can invoke this callback immediately as data is received, even if it is expecting
* more data. The OpenThread stack handles all stream-level behavior, processing, and retention of the
* received data. This helps simplify the platform implementation.
*
* On certain platforms (such as standard POSIX), a return value of 0 from `read()` or `recv()` indicates an
* End-of-File (EOF) or graceful closure by the peer. The platform implementation must check for this condition and
* report it by invoking `otPlatTcpHandleDisconnected()` with the reason set to `OT_PLAT_TCP_DISCONNECT_REASON_CLOSED`.
* Importantly, calling `otPlatTcpHandleReceive()` with `aLength` set to zero does not signify a graceful closure in
* the `otPlatTcp` APIs; such a call is treated as a no-op receive event by the OpenThread stack and is ignored.
*
* @param[in] aConn The TCP connection.
* @param[in] aBuffer A pointer to the buffer containing the received data. Must not be NULL if @p aLength > 0.
* @param[in] aLength The length (in bytes) of the received data.
*/
extern void otPlatTcpHandleReceive(otPlatTcpConnection *aConn, const uint8_t *aBuffer, uint16_t aLength);
/**
* Gracefully closes the TCP connection.
*
* This function initiates a graceful closure of the connection. The platform should transmit any remaining data
* before performing the standard TCP connection termination.
*
* Once the connection is fully disconnected, or if it is already closed, or if an error occurs during the close
* operation, the platform must indicate this by invoking the `otPlatTcpHandleDisconnected` callback.
*
* The platform must always call `otPlatTcpHandleDisconnected()` to report the final outcome of the connection.
* It is permissible for the platform implementation to invoke this callback directly from within `otPlatTcpClose()`
* before returning. The OpenThread stack will handle this correctly.
*
* @param[in] aConn The TCP connection.
*/
void otPlatTcpClose(otPlatTcpConnection *aConn);
/**
* Aborts the TCP connection.
*
* This function forcefully terminates the connection. Any unsent data is discarded.
*
* After this call, the platform must forget the @p aConn. Importantly, it must not invoke any callbacks using the
* @p aConn any longer, including `otPlatTcpHandleDisconnected`. This effectively indicates to the platform that the
* OpenThread core is de-allocating the @p aConn instance and it is no longer valid.
*
* @param[in] aConn The TCP connection.
*/
void otPlatTcpAbort(otPlatTcpConnection *aConn);
/**
* Callback to notify the connection disconnection.
*
* This function is implemented and provided by the OpenThread stack for the platform to use.
*
* This callback should be invoked by the platform when it fails to establish a connection, when an established
* connection is successfully closed (by both endpoints), when it times out, or is reset or aborted.
*
* After this callback is invoked, the `otPlatTcpConnection` instance is no longer valid. The platform must not use it
* in any future callbacks.
*
* @param[in] aConn The TCP connection.
* @param[in] aReason The reason for the disconnection.
*/
extern void otPlatTcpHandleDisconnected(otPlatTcpConnection *aConn, otPlatTcpDisconnectReason aReason);
/**
* Gets the OpenThread instance associated with a given TCP connection.
*
* This function is provided by OpenThread core. Platform implementations can use it to get the OpenThread instance
* associated with an active `otPlatTcpConnection`.
*
* @param[in] aConn The TCP connection.
*
* @returns The OpenThread instance.
*/
extern otInstance *otPlatTcpGetInstanceForConnection(otPlatTcpConnection *aConn);
/**
* Gets the OpenThread instance associated with a given TCP listener.
*
* This function is provided by OpenThread core. Platform implementations can use it to get the OpenThread instance
* associated with an active `otPlatTcpListener`.
*
* @param[in] aListener The TCP listener.
*
* @returns The OpenThread instance.
*/
extern otInstance *otPlatTcpGetInstanceForListener(otPlatTcpListener *aListener);
/**
* Iterates through the active TCP listeners.
*
* This function can be used to iterate over all currently active TCP listeners associated with the OpenThread
* instance. It allows platform implementations to process or manage listeners without needing to maintain their own
* list of active listeners.
*
* The iteration is guaranteed to remain consistent even if callbacks (e.g., `otPlatTcpAccept`) are invoked during the
* process.
*
* @param[in] aInstance The OpenThread instance.
* @param[in] aPrevListener A pointer to the previous listener, or `NULL` to start the iteration from the beginning.
*
* @returns A pointer to the next listener, or `NULL` if there are no more listeners.
*/
extern otPlatTcpListener *otPlatTcpIterateListeners(otInstance *aInstance, otPlatTcpListener *aPrevListener);
/**
* Iterates through the active TCP connections.
*
* This function can be used to iterate over all currently active TCP connections associated with the OpenThread
* instance. It allows platform implementations to process or manage connections without needing to maintain their own
* list of active connections.
*
* The iteration is guaranteed to remain consistent and safe even if callbacks are invoked during the process. For
* example, if a connection is reported as disconnected via `otPlatTcpHandleDisconnected` during iteration, the
* OpenThread stack ensures that the connection entry remains valid until the iteration is completed.
*
* @param[in] aInstance The OpenThread instance.
* @param[in] aPrevConn A pointer to the previous connection, or `NULL` to start the iteration from the beginning.
*
* @returns A pointer to the next connection, or `NULL` if there are no more connections.
*/
extern otPlatTcpConnection *otPlatTcpIterateConnections(otInstance *aInstance, otPlatTcpConnection *aPrevConn);
/**
* @}
*/
#ifdef __cplusplus
} // extern "C"
#endif
#endif // OPENTHREAD_PLATFORM_TCP_H_
+122 -32
View File
@@ -75,6 +75,58 @@ extern "C" {
#define OT_TCAT_MAX_DEVICEID_SIZE 64 ///< TCAT max size of device ID.
#define OT_TCAT_ENABLE_MAX 600 ///< TCAT_ENABLE_MAX, default max TMF TCAT enable time, in seconds.
/**
* Represents TCAT command TLV type.
*/
typedef enum otTcatCommandTlvType
{
// Command Class General
OT_TCAT_TLV_RESPONSE_WITH_STATUS = 0x01, ///< TCAT response with status value TLV
OT_TCAT_TLV_RESPONSE_WITH_PAYLOAD = 0x02, ///< TCAT response with payload TLV
OT_TCAT_TLV_RESPONSE_EVENT = 0x03, ///< TCAT response event TLV (reserved)
OT_TCAT_TLV_GET_NETWORK_NAME = 0x08, ///< TCAT network name query TLV
OT_TCAT_TLV_DISCONNECT = 0x09, ///< TCAT disconnect request TLV
OT_TCAT_TLV_PING = 0x0A, ///< TCAT ping request TLV
OT_TCAT_TLV_GET_DEVICE_ID = 0x0B, ///< TCAT device ID query TLV
OT_TCAT_TLV_GET_EXTENDED_PAN_ID = 0x0C, ///< TCAT extended PAN ID query TLV
OT_TCAT_TLV_GET_PROVISIONING_URL = 0x0D, ///< TCAT provisioning URL query TLV
OT_TCAT_TLV_PRESENT_PSKD_HASH = 0x10, ///< TCAT rights elevation request TLV using PSKd hash
OT_TCAT_TLV_PRESENT_PSKC_HASH = 0x11, ///< TCAT rights elevation request TLV using PSKc hash
OT_TCAT_TLV_PRESENT_INSTALL_CODE_HASH = 0x12, ///< TCAT rights elevation TLV using install code
OT_TCAT_TLV_REQUEST_RANDOM_CHALLENGE = 0x13, ///< TCAT random number challenge query TLV
// Command Class Commissioning
OT_TCAT_TLV_SET_ACTIVE_OPERATIONAL_DATASET = 0x20, ///< TCAT active operational dataset TLV
OT_TCAT_TLV_SET_ACTIVE_OPERATIONAL_DATASET_ALT = 0x21, ///< TCAT active dataset alt #1 TLV (reserved)
OT_TCAT_TLV_GET_COMMISSIONER_CERTIFICATE = 0x25, ///< TCAT commissioner certificate query TLV
OT_TCAT_TLV_GET_DIAGNOSTIC_TLVS = 0x26, ///< TCAT diagnostics TLVs query TLV
OT_TCAT_TLV_START_THREAD_INTERFACE = 0x27, ///< TCAT start thread interface request TLV
OT_TCAT_TLV_STOP_THREAD_INTERFACE = 0x28, ///< TCAT stop thread interface request TLV
// Command Class Extraction
OT_TCAT_TLV_GET_ACTIVE_OPERATIONAL_DATASET = 0x40, ///< TCAT active operational dataset query TLV
OT_TCAT_TLV_GET_ACTIVE_OPERATIONAL_DATASET_ALT = 0x41, ///< TCAT active dataset alt #1 query TLV (reserved)
// Command Class Decommissioning
OT_TCAT_TLV_DECOMMISSION = 0x60, ///< TCAT decommission request TLV
// Command Class Application
OT_TCAT_TLV_GET_APPLICATION_LAYERS = 0x80, ///< TCAT get application layers request TLV
OT_TCAT_TLV_SEND_APPLICATION_DATA_1 = 0x81, ///< TCAT send application data 1 TLV
OT_TCAT_TLV_SEND_APPLICATION_DATA_2 = 0x82, ///< TCAT send application data 2 TLV
OT_TCAT_TLV_SEND_APPLICATION_DATA_3 = 0x83, ///< TCAT send application data 3 TLV
OT_TCAT_TLV_SEND_APPLICATION_DATA_4 = 0x84, ///< TCAT send application data 4 TLV
OT_TCAT_TLV_SERVICE_NAME_UDP = 0x89, ///< TCAT service name UDP sub-TLV (not used as a command)
OT_TCAT_TLV_SERVICE_NAME_TCP = 0x8A, ///< TCAT service name TCP sub-TLV (not used as a command)
OT_TCAT_TLV_SEND_VENDOR_SPECIFIC_DATA = 0x9F, ///< TCAT send vendor specific command or data TLV
// Command Class CCM
OT_TCAT_TLV_SET_LDEV_ID_OPERATIONAL_CERT = 0xA0, ///< TCAT set LDevID certificate TLV (reserved)
OT_TCAT_TLV_SET_LDEV_ID_PRIVATE_KEY = 0xA1, ///< TCAT set LDevID certificate private key TLV (reserved)
OT_TCAT_TLV_SET_DOMAIN_CA_CERT = 0xA2, ///< TCAT set domain CA certificate TLV (reserved)
} otTcatCommandTlvType;
/**
* Represents TCAT status code.
*/
@@ -153,35 +205,6 @@ typedef struct otTcatGeneralDeviceId
uint8_t mDeviceId[OT_TCAT_MAX_DEVICEID_SIZE];
} otTcatGeneralDeviceId;
/**
* This structure represents a TCAT vendor information.
*
* The content of this structure MUST persist and remain unchanged while a TCAT session is running.
*/
typedef struct otTcatVendorInfo
{
const char *mProvisioningUrl; ///< Provisioning URL path string
const char *mVendorName; ///< Vendor name string
const char *mVendorModel; ///< Vendor model string
const char *mVendorSwVersion; ///< Vendor software version string
const char *mVendorData; ///< Vendor specific data string
const char *mPskdString; ///< Vendor managed pre-shared key for device
const char *mInstallCode; ///< Vendor managed install code string
const otTcatAdvertisedDeviceId
*mAdvertisedDeviceIds; /** Vendor managed advertised device ID array.
Array is terminated like C string with OT_TCAT_DEVICE_ID_EMPTY */
const otTcatGeneralDeviceId *mGeneralDeviceId; /** Vendor managed general device ID array.
(if NULL: device ID is set to EUI-64 in binary format) */
const char *mApplicationServiceName[OT_TCAT_APPLICATION_LAYER_MAX_COUNT]; /** Array with application service names
as C string with maximum length
OT_TCAT_SERVICE_NAME_MAX_LENGTH or
NULL if not supported */
bool mApplicationServiceIsTcp[OT_TCAT_APPLICATION_LAYER_MAX_COUNT]; /** Array with boolean values indicating
if the service is of TCP type (otherwise
UDP) */
} otTcatVendorInfo;
/**
* Pointer to call when application data or vendor-specific data was received over a TCAT TLS connection.
* The application may generate a response to an incoming TCAT application data packet. The TCAT agent
@@ -201,9 +224,12 @@ typedef void (*otHandleTcatApplicationDataReceive)(otInstance *aIn
void *aContext);
/**
* Pointer to call to notify the completion of a network join/leave operation performed under
* guidance of a TCAT Commissioner.
* Pointer to call to notify of a network join/leave operation initiated under guidance of a TCAT Commissioner.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aIsJoin True if the operation was a network join (OT_TCAT_TLV_START_THREAD_INTERFACE),
* false if it was a network leave (OT_TCAT_TLV_STOP_THREAD_INTERFACE or
* OT_TCAT_TLV_DECOMMISSION).
* @param[in] aError OT_ERROR_NONE if the network join/leave operation was successfully started.
* OT_ERROR_INVALID_STATE if network join was requested but network credentials
* were missing or incomplete.
@@ -213,7 +239,71 @@ typedef void (*otHandleTcatApplicationDataReceive)(otInstance *aIn
* credential mismatch.
* @param[in] aContext A pointer to arbitrary context information.
*/
typedef void (*otHandleTcatJoin)(otError aError, void *aContext);
typedef void (*otHandleTcatJoin)(otInstance *aInstance, bool aIsJoin, otError aError, void *aContext);
/**
* Pointer to call to control if a TCAT TLV of a specific type is supported. The application may allow
* or reject processing of a received TCAT command based on an application defined policy.
* If no handler is defined, all received TCAT commands will be allowed if the respective command class
* is authorized. If a handler is defined and returns false, the TCAT command will be rejected with status
* OT_TCAT_STATUS_UNSUPPORTED. If the handler returns true, the TCAT command will be allowed if the respective
* command class is authorized.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aTlvType A TLV type to be authorized.
* @param[in] aContext A pointer to arbitrary context information.
*
* @returns a boolean value indicating whether the TLV type is supported, based on current policy.
*/
typedef bool (*otHandleTcatTlvSupport)(otInstance *aInstance, otTcatCommandTlvType aTlvType, void *aContext);
/**
* This structure represents a TCAT vendor information.
*
* The content of this structure MUST persist and remain unchanged while a TCAT session is running.
*/
typedef struct otTcatVendorInfo
{
const char *mProvisioningUrl; ///< Provisioning URL path string
const char *mVendorName; ///< Vendor name string
const char *mVendorModel; ///< Vendor model string
const char *mVendorSwVersion; ///< Vendor software version string
const char *mVendorData; ///< Vendor specific data string
const char *mPskdString; ///< Vendor managed pre-shared key for device
const char *mInstallCode; ///< Vendor managed install code string
/**
* Vendor managed advertised device ID array. Array is terminated like C string with OT_TCAT_DEVICE_ID_EMPTY.
*/
const otTcatAdvertisedDeviceId *mAdvertisedDeviceIds;
/**
* Vendor managed general device ID array (if NULL: device ID is set to EUI-64 in binary format)
*/
const otTcatGeneralDeviceId *mGeneralDeviceId;
/**
* Array with application service names as C string with maximum length OT_TCAT_SERVICE_NAME_MAX_LENGTH or NULL if
* not supported.
*/
const char *mApplicationServiceName[OT_TCAT_APPLICATION_LAYER_MAX_COUNT];
/**
* Array with boolean values indicating if the service is of TCP type (otherwise UDP).
*/
bool mApplicationServiceIsTcp[OT_TCAT_APPLICATION_LAYER_MAX_COUNT];
bool mKeepActiveAfterJoining; ///< Continue advertising after thread interface has joined a network
/**
* Prevent activating advertising indefinitely after the TCAT command OT_TCAT_TLV_STOP_THREAD_INTERFACE or
* OT_TCAT_TLV_DECOMMISSION has been received.
*/
bool mDoNotActivateAfterLeaving;
otHandleTcatTlvSupport mTlvSupportHandler; ///< Optional pointer to a function to control TCAT TLV support
} otTcatVendorInfo;
/**
* @}
-50
View File
@@ -628,38 +628,6 @@ const char *otThreadGetDomainName(otInstance *aInstance);
*/
otError otThreadSetDomainName(otInstance *aInstance, const char *aDomainName);
/**
* Sets or clears the Interface Identifier manually specified for the Thread Domain Unicast Address.
*
* Available when `OPENTHREAD_CONFIG_DUA_ENABLE` is enabled.
*
* @note Only available since Thread 1.2.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aIid A pointer to the Interface Identifier to set or NULL to clear.
*
* @retval OT_ERROR_NONE Successfully set/cleared the Interface Identifier.
* @retval OT_ERROR_INVALID_ARGS The specified Interface Identifier is reserved.
*
* @sa otThreadGetFixedDuaInterfaceIdentifier
*/
otError otThreadSetFixedDuaInterfaceIdentifier(otInstance *aInstance, const otIp6InterfaceIdentifier *aIid);
/**
* Gets the Interface Identifier manually specified for the Thread Domain Unicast Address.
*
* Available when `OPENTHREAD_CONFIG_DUA_ENABLE` is enabled.
*
* @note Only available since Thread 1.2.
*
* @param[in] aInstance A pointer to an OpenThread instance.
*
* @returns A pointer to the Interface Identifier which was set manually, or NULL if none was set.
*
* @sa otThreadSetFixedDuaInterfaceIdentifier
*/
const otIp6InterfaceIdentifier *otThreadGetFixedDuaInterfaceIdentifier(otInstance *aInstance);
/**
* Gets the thrKeySequenceCounter.
*
@@ -1072,24 +1040,6 @@ void otThreadSendAddressNotification(otInstance *aInstance,
otIp6Address *aTarget,
otIp6InterfaceIdentifier *aMlIid);
/**
* Sends a Proactive Backbone Notification (PRO_BB.ntf) message on the Backbone link.
*
* Is only available when `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE` is enabled.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aTarget The target address of the PRO_BB.ntf message.
* @param[in] aMlIid The ML-IID of the PRO_BB.ntf message.
* @param[in] aTimeSinceLastTransaction Time since last transaction (in seconds).
*
* @retval OT_ERROR_NONE Successfully sent PRO_BB.ntf on backbone link.
* @retval OT_ERROR_NO_BUFS If insufficient message buffers available.
*/
otError otThreadSendProactiveBackboneNotification(otInstance *aInstance,
otIp6Address *aTarget,
otIp6InterfaceIdentifier *aMlIid,
uint32_t aTimeSinceLastTransaction);
/**
* Notifies other nodes in the network (if any) and then stops Thread protocol operation.
*
+20 -6
View File
@@ -153,12 +153,15 @@ uint16_t otThreadGetMaxAllowedChildren(otInstance *aInstance);
otError otThreadSetMaxAllowedChildren(otInstance *aInstance, uint16_t aMaxChildren);
/**
* Indicates whether or not the device is router-eligible.
* Indicates whether or not the device is allowed to take router or leader roles.
*
* A device is allowed to become a router if it is a Full Thread Device (FTD), is currently configured to be
* router-eligible (see `otThreadSetRouterEligible(true)`), and the active Security Policy permits routers.
*
* @param[in] aInstance A pointer to an OpenThread instance.
*
* @retval TRUE If device is router-eligible.
* @retval FALSE If device is not router-eligible.
* @retval TRUE If the router role is allowed.
* @retval FALSE If the router role is not allowed.
*/
bool otThreadIsRouterEligible(otInstance *aInstance);
@@ -177,14 +180,16 @@ bool otThreadIsRouterEligible(otInstance *aInstance);
otError otThreadSetRouterEligible(otInstance *aInstance, bool aEligible);
/**
* Set the preferred Router Id.
* Sets the preferred Router Id.
*
* Requires `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE`.
*
* Upon becoming a router/leader the node attempts to use this Router Id. If the preferred Router Id is not set or if
* it can not be used, a randomly generated router id is picked. This property can be set only when the device role is
* either detached or disabled.
*
* @note This API is reserved for testing and demo purposes only. Changing settings with
* this API will render a production application non-compliant with the Thread Specification.
* @note This API is reserved for testing and demo purposes only. Changing settings with this API will render a
* production application non-compliant with the Thread Specification.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aRouterId The preferred Router Id.
@@ -624,6 +629,15 @@ otError otThreadGetRouterInfo(otInstance *aInstance, uint16_t aRouterId, otRoute
*/
otError otThreadGetNextCacheEntry(otInstance *aInstance, otCacheEntryInfo *aEntryInfo, otCacheEntryIterator *aIterator);
/**
* Clears the EID cache.
*
* Intended for testing only.
*
* @param[in] aInstance A pointer to an OpenThread instance.
*/
void otThreadClearEidCache(otInstance *aInstance);
/**
* Get the Thread PSKc
*
-1
View File
@@ -54,7 +54,6 @@ build_nrf52840()
"-DOT_DIAGNOSTIC=ON"
"-DOT_DNSSD_SERVER=ON"
"-DOT_DNS_CLIENT=ON"
"-DOT_DUA=ON"
"-DOT_ECDSA=ON"
"-DOT_FULL_LOGS=ON"
"-DOT_JAM_DETECTION=ON"
+5 -13
View File
@@ -158,31 +158,23 @@ build_all_features()
# Build Thread 1.4 with full features
reset_source
CFLAGS="${cppflags[*]} ${CFLAGS}" CXXFLAGS="${cppflags[*]} ${CXXFLAGS}" \
"$(dirname "$0")"/cmake-build simulation "${options[@]}" -DOT_DUA=ON
"$(dirname "$0")"/cmake-build simulation "${options[@]}"
# Build Thread 1.4 with external heap and msg pool using heap
reset_source
CFLAGS="${cppflags[*]} ${CFLAGS} -DOPENTHREAD_CONFIG_MESSAGE_USE_HEAP_ENABLE=1" \
CXXFLAGS="${cppflags[*]} ${CXXFLAGS} -DOPENTHREAD_CONFIG_MESSAGE_USE_HEAP_ENABLE=1" \
"$(dirname "$0")"/cmake-build simulation "${options[@]}" -DOT_DUA=ON
"$(dirname "$0")"/cmake-build simulation "${options[@]}"
# Build Thread 1.4 with full features and no log
reset_source
CFLAGS="${cppflags[*]} ${CFLAGS}" CXXFLAGS="${cppflags[*]} ${CXXFLAGS}" \
"$(dirname "$0")"/cmake-build simulation "${options[@]}" -DOT_DUA=ON -DOT_LOG_OUTPUT=NONE
"$(dirname "$0")"/cmake-build simulation "${options[@]}" -DOT_LOG_OUTPUT=NONE
# Build Thread 1.4 with full features and full logs
reset_source
CFLAGS="${cppflags[*]} ${CFLAGS}" CXXFLAGS="${cppflags[*]} ${CXXFLAGS}" \
"$(dirname "$0")"/cmake-build simulation "${options[@]}" -DOT_DUA=ON -DOT_FULL_LOGS=ON
# Build Thread 1.4 Backbone Router without DUA ND Proxying
reset_source
"$(dirname "$0")"/cmake-build simulation "${options[@]}" -DOT_BACKBONE_ROUTER_DUA_NDPROXYING=OFF
# Build Thread 1.4 Backbone Router without Multicast Routing
reset_source
"$(dirname "$0")"/cmake-build simulation "${options[@]}" -DOT_BACKBONE_ROUTER_MULTICAST_ROUTING=OFF
"$(dirname "$0")"/cmake-build simulation "${options[@]}" -DOT_FULL_LOGS=ON
# Build with Vendor Extension
reset_source
@@ -196,7 +188,7 @@ build_all_features()
# Build Thread 1.4 with full features and OT_ASSERT=OFF
reset_source
"$(dirname "$0")"/cmake-build simulation "${options[@]}" -DOT_DUA=ON -DOT_ASSERT=OFF
"$(dirname "$0")"/cmake-build simulation "${options[@]}" -DOT_ASSERT=OFF
# Build with RAM settings
reset_source
+1
View File
@@ -64,6 +64,7 @@ test_ipv6()
OT_NODE_TYPE=rcp OT_SIMULATION_LOCAL_HOST=$IFACE_NAME $EXPECT_TEST
OT_NODE_TYPE=rcp OT_SIMULATION_LOCAL_HOST=$IP6ADDR $EXPECT_TEST
OT_NODE_TYPE=rcp OT_SIMULATION_LOCAL_HOST=::1 $EXPECT_TEST
}
test_ipv4()
+1 -1
View File
@@ -125,7 +125,7 @@ build_nrf52840()
git archive "${sha}" | tar x -C "${OT_TMP_DIR}/${folder}/openthread"
if [ ! -e "${OT_TMP_DIR}/${folder}/openthread/examples/config/${config_name}" ]; then
# Check if the the config headers are not present, copy from
# Check if the config headers are not present, copy from
# the main sha.
case "$1" in
br)
+1 -53
View File
@@ -67,7 +67,7 @@ OT_CMAKE_NINJA_TARGET=${OT_CMAKE_NINJA_TARGET-}
OT_SRCDIR="$(cd "$(dirname "$0")"/.. && pwd)"
readonly OT_SRCDIR
OT_PLATFORMS=(simulation posix android-ndk)
OT_PLATFORMS=(simulation posix)
readonly OT_PLATFORMS
OT_CLEAN_INTERMEDIATES="${OT_CLEAN_INTERMEDIATES-${GITHUB_ACTION-}}"
@@ -166,58 +166,6 @@ main()
)
case "${platform}" in
android-ndk)
if [ -z "${NDK-}" ]; then
echo "
The 'NDK' environment variable needs to point to the Android NDK toolchain.
Please ensure the NDK is downloaded and extracted then try to run this script again
For example:
NDK=/opt/android-ndk-r25c ./script/cmake-build-android
You can download the NDK at https://developer.android.com/ndk/downloads
"
exit 1
fi
NDK_CMAKE_TOOLCHAIN_FILE="${NDK?}/build/cmake/android.toolchain.cmake"
if [ ! -f "${NDK_CMAKE_TOOLCHAIN_FILE}" ]; then
echo "
Could not fild the Android NDK CMake toolchain file
- NDK=${NDK}
- NDK_CMAKE_TOOLCHAIN_FILE=${NDK_CMAKE_TOOLCHAIN_FILE}
"
exit 2
fi
local_options+=(
"-DOT_LOG_OUTPUT=PLATFORM_DEFINED"
# Add Android NDK flags
"-DOT_ANDROID_NDK=1"
"-DCMAKE_TOOLCHAIN_FILE=${NDK?}/build/cmake/android.toolchain.cmake"
# Android API needs to be >= android-24 for `getifsaddrs()`
"-DANDROID_PLATFORM=android-24"
# Store thread settings in the CWD when executing ot-cli or ot-daemon
'-DOT_POSIX_SETTINGS_PATH="./thread"'
)
# Rewrite platform to posix
platform="posix"
# Check if OT_DAEMON or OT_APP_CLI flags are needed
if [[ ${OT_CMAKE_NINJA_TARGET[*]} =~ "ot-daemon" ]] || [[ ${OT_CMAKE_NINJA_TARGET[*]} =~ "ot-ctl" ]]; then
local_options+=("-DOT_DAEMON=ON")
elif [[ ${OT_CMAKE_NINJA_TARGET[*]} =~ "ot-cli" ]]; then
local_options+=("-DOT_APP_CLI=ON")
fi
options+=("${local_options[@]}")
;;
posix)
local_options+=(
"-DOT_TCP=OFF"
+2 -1
View File
@@ -65,7 +65,8 @@ try_clone()
shift
git clone "$@" 2>&1
else
dest_dir="$(git clone "$@" 2>&1 | tee | cut -d\' -f2)"
dest_dir="$(LC_ALL=C git clone "$@" 2>&1 | tee /dev/stderr | sed -n "s/^Cloning into '\([^']*\)'.*/\1/p")"
dest_dir="${dest_dir%%$'\n'*}"
cd "${dest_dir}"
apply_dependencies
-1
View File
@@ -112,7 +112,6 @@ OT_CLANG_TIDY_BUILD_OPTS=(
'-DOT_DNS_UPSTREAM_QUERY=ON'
"-DOT_DNSSD_DISCOVERY_PROXY=ON"
'-DOT_DNSSD_SERVER=ON'
'-DOT_DUA=ON'
'-DOT_MLR=ON'
'-DOT_ECDSA=ON'
'-DOT_HISTORY_TRACKER=ON'
+1 -5
View File
@@ -125,7 +125,6 @@ build_simulation()
fi
if [[ ${version} != "1.1" ]]; then
options+=("-DOT_DUA=ON")
options+=("-DOT_MLR=ON")
fi
@@ -184,7 +183,6 @@ build_posix()
)
if [[ ${version} != "1.1" ]]; then
options+=("-DOT_DUA=ON")
options+=("-DOT_MLR=ON")
options+=("-DOT_LINK_METRICS_INITIATOR=ON")
options+=("-DOT_LINK_METRICS_SUBJECT=ON")
@@ -346,14 +344,12 @@ do_build_otbr_docker()
"-DOT_ANYCAST_LOCATOR=ON"
"-DOT_COVERAGE=ON"
"-DOT_DNS_CLIENT=ON"
"-DOT_DUA=ON"
"-DOT_MLR=ON"
"-DOT_NETDATA_PUBLISHER=ON"
"-DOT_SLAAC=ON"
"-DOT_SRP_CLIENT=ON"
"-DOT_FULL_LOGS=ON"
"-DOT_UPTIME=ON"
"-DOTBR_DUA_ROUTING=ON"
"-DOTBR_DHCP6_PD=ON"
)
local args=(
@@ -395,7 +391,7 @@ do_build_otbr_docker()
(
if [[ -z ${LOCAL_OTBR_DIR} ]]; then
./script/git-tool clone https://github.com/openthread/ot-br-posix.git --depth 1 "${otbrdir}"
./script/git-tool clone https://github.com/openthread/ot-br-posix.git --depth 1 --recurse-submodules --shallow-submodules "${otbrdir}"
else
rsync -r \
--exclude=third_party/openthread/repo \
+1
View File
@@ -30,6 +30,7 @@ import("../../etc/gn/openthread.gni")
openthread_cli_sources = [
"cli.cpp",
"cli.hpp",
"cli_api.cpp",
"cli_ba.cpp",
"cli_ba.hpp",
"cli_bbr.cpp",
+1
View File
@@ -33,6 +33,7 @@ set(COMMON_INCLUDES
set(COMMON_SOURCES
cli.cpp
cli_api.cpp
cli_ba.cpp
cli_bbr.cpp
cli_br.cpp
+5 -62
View File
@@ -50,7 +50,6 @@ Done
- [discover](#discover-channel)
- [dns](#dns-config)
- [domainname](#domainname)
- [dua](#dua-iid)
- [eidcache](#eidcache)
- [eui64](#eui64)
- [extaddr](#extaddr)
@@ -174,30 +173,6 @@ BBR Primary: None
Done
```
### bbr mgmt dua \<status\|coap-code\> [meshLocalIid]
Configure the response status for DUA.req with meshLocalIid in payload. Without meshLocalIid, simply respond any coming DUA.req next with the specified status or COAP code.
Only for testing/reference device.
known status value:
- 0: ST_DUA_SUCCESS
- 1: ST_DUA_REREGISTER
- 2: ST_DUA_INVALID
- 3: ST_DUA_DUPLICATE
- 4: ST_DUA_NO_RESOURCES
- 5: ST_DUA_BBR_NOT_PRIMARY
- 6: ST_DUA_GENERAL_FAILURE
- 160: COAP code 5.00
```bash
> bbr mgmt dua 1 2f7c235e5025a2fd
Done
> bbr mgmt dua 160
Done
```
### bbr mgmt mlr listener
Show the Multicast Listeners.
@@ -421,7 +396,7 @@ Requires the `OPENTHREAD_CONFIG_BORDER_AGENT_MESHCOP_SERVICE_ENABLE` feature.
The name can also be configured using the `OPENTHREAD_CONFIG_BORDER_AGENT_MESHCOP_SERVICE_BASE_NAME` configuration option (which is the recommended way to specify this name). This CLI command (and its corresponding API) is provided for projects where the name needs to be set after device initialization and at run-time.
Per the Thread specification, the service instance should be a user-friendly name identifying the device model or product. A recommended format is "VendorName ProductName". To construct the full name and ensure name uniqueness, the OpenThread Border Agent module will append the Extended Address of the device (as 16-character hex digits) to the given base name. Note that the same name will be used for the ephemeral key service `_meshcop-e._udp` when the ephemeral key feature is enabled and used.
Per the Thread specification, the service instance should be a user-friendly name identifying the device model or product. A recommended format is "VendorName ProductName". To construct the full name and ensure name uniqueness, the OpenThread Border Agent module appends a suffix (e.g., " #XXXX" where "XXXX" represents the last two bytes of the device's Extended Address in hex) to the given base name. If a name conflict is detected on the network, an additional index may be appended (e.g., " #XXXX (1)"). Note that the same name will be used for the ephemeral key service `_meshcop-e._udp` when the ephemeral key feature is enabled and used.
```bash
ba servicebasename OpenThreadBorderAgent
@@ -1536,11 +1511,10 @@ The generated output encompasses the following information:
- Version
- Current state
- Uptime and attach time
- Channel
- PAN IDs, extended MAC address, and RLOC16
- Extended MAC address and RLOC16
- Active Operational Dataset (redacted)
- Unicast and multicast IPv6 address list
- Network Data
- Partition ID
- Leader Data
- Buffer info
- Network statistics
@@ -1960,34 +1934,6 @@ Set the Thread Domain Name for Thread 1.2 device.
Done
```
### dua iid
Get the Interface Identifier manually specified for Thread Domain Unicast Address on Thread 1.2 device.
```bash
> dua iid
0004000300020001
Done
```
### dua iid \<iid\>
Set the Interface Identifier manually specified for Thread Domain Unicast Address on Thread 1.2 device.
```bash
> dua iid 0004000300020001
Done
```
### dua iid clear
Clear the Interface Identifier manually specified for Thread Domain Unicast Address on Thread 1.2 device.
```bash
> dua iid clear
Done
```
### eidcache
Print the EID-to-RLOC cache entries.
@@ -2557,7 +2503,7 @@ Locate the closest destination of an anycast address (i.e., find the destination
`OPENTHREAD_CONFIG_TMF_ANYCAST_LOCATOR_ENABLE` is required.
The closest destination is determined based on the the current routing table and path costs within the Thread mesh.
The closest destination is determined based on the current routing table and path costs within the Thread mesh.
Locate the leader using its anycast address:
@@ -3597,7 +3543,7 @@ Done
### prefix
Get the prefix list in the local Network Data. Note: For the Thread 1.2 border router with backbone capability, the local Domain Prefix would be listed as well (with flag `D`), with preceding `-` if backbone functionality is disabled.
Get the prefix list in the local Network Data.
```bash
> prefix
@@ -3610,8 +3556,6 @@ Done
Add a valid prefix to the Network Data.
Note: The Domain Prefix flag (`D`) is only available for Thread 1.2.
- p: Preferred flag
- a: Stateless IPv6 Address Autoconfiguration flag
- d: DHCPv6 IPv6 Address Configuration flag
@@ -3620,7 +3564,6 @@ Note: The Domain Prefix flag (`D`) is only available for Thread 1.2.
- o: On Mesh flag
- s: Stable flag
- n: Nd Dns flag
- D: Domain Prefix flag
- prf: Default router preference, which may be 'high', 'med', or 'low'.
```bash
-1
View File
@@ -430,7 +430,6 @@ Peer BRs are other devices within the Thread mesh that provide external IP conne
- It has added at least one external route entry.
- It has added at least one prefix entry with both the default-route and on-mesh flags set.
- It has added at least one domain prefix (with both the domain and on-mesh flags set).
The list of peer BRs specifically excludes the current device, even if it is itself acting as a BR.
-1
View File
@@ -466,7 +466,6 @@ The flags are as follows:
- `o`: On Mesh flag
- `s`: Stable flag
- `n`: Nd Dns flag
- `D`: Domain Prefix flag
Print the history as a table.
-2
View File
@@ -283,7 +283,6 @@ Publish an on-mesh prefix entry.
- o: On Mesh flag
- s: Stable flag
- n: Nd Dns flag
- D: Domain Prefix flag (only available for Thread 1.2).
- prf: Preference, which may be 'high', 'med', or 'low'.
```bash
@@ -352,7 +351,6 @@ On-mesh prefixes are listed under `Prefixes` header:
- o: On Mesh flag
- s: Stable flag
- n: Nd Dns flag
- D: Domain Prefix flag (only available for Thread 1.2).
- Preference `high`, `med`, or `low`
- RLOC16 of device which added the on-mesh prefix
+273 -204
View File
@@ -49,6 +49,7 @@
#include <openthread/dataset_ftd.h>
#include <openthread/diag.h>
#include <openthread/dns.h>
#include <openthread/heap.h>
#include <openthread/icmp6.h>
#include <openthread/nat64.h>
#include <openthread/ncp.h>
@@ -70,14 +71,14 @@
namespace ot {
namespace Cli {
Interpreter *Interpreter::sInterpreter = nullptr;
static OT_DEFINE_ALIGNED_VAR(sInterpreterRaw, sizeof(Interpreter), uint64_t);
Interpreter::Interpreter(Instance *aInstance, otCliOutputCallback aCallback, void *aContext)
: OutputImplementer(aCallback, aContext)
, Utils(aInstance, *this)
, mCommandIsPending(false)
, mInternalDebugCommand(false)
#if OPENTHREAD_CONFIG_CLI_PROMPT_ENABLE
, mPromptEnabled(true)
#endif
, mTimer(*aInstance, HandleTimer, this)
#if OPENTHREAD_FTD || OPENTHREAD_MTD
#if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
@@ -163,7 +164,9 @@ void Interpreter::OutputResult(otError aError)
{
if (aError != OT_ERROR_NONE)
{
OutputLine("Error %u: %s", aError, otThreadErrorToString(aError));
// For internal debug commands, prepending `*` to prevent cli client from treating this as a fatal error and
// exit.
OutputLine("* Error %u: %s", aError, otThreadErrorToString(aError));
}
ExitNow();
@@ -394,24 +397,35 @@ otError Interpreter::ProcessUserCommands(Arg aArgs[])
otError Interpreter::SetUserCommands(const otCliCommand *aCommands, uint8_t aLength, void *aContext)
{
otError error = OT_ERROR_FAILED;
otError error = OT_ERROR_NONE;
for (UserCommandsEntry &entry : mUserCommands)
{
if (entry.mCommands == aCommands)
{
// Ignore if already registered.
ExitNow();
}
if (entry.mCommands == nullptr)
{
entry.mCommands = aCommands;
entry.mLength = aLength;
entry.mContext = aContext;
error = OT_ERROR_NONE;
break;
ExitNow();
}
}
error = OT_ERROR_NO_BUFS;
exit:
return error;
}
#if OPENTHREAD_CONFIG_CLI_PROMPT_ENABLE
void Interpreter::SetPromptConfig(bool aEnabled) { mPromptEnabled = aEnabled; }
#endif
#if OPENTHREAD_FTD || OPENTHREAD_MTD
/**
@@ -737,6 +751,12 @@ void Interpreter::OutputBorderAgentTxtDataInfo(uint8_t aIndentSize, const otBord
OutputLine(aIndentSize, "ModelName: %s", aInfo.mModelName);
}
if (aInfo.mHasVendorOui)
{
OutputLine(aIndentSize, "VendorOui: %02X-%02X-%02X", aInfo.mVendorOui[0], aInfo.mVendorOui[1],
aInfo.mVendorOui[2]);
}
if (aInfo.mHasStateBitmap)
{
uint8_t indent = aIndentSize + kIndentSize;
@@ -1082,70 +1102,6 @@ template <> otError Interpreter::Process<Cmd("domainname")>(Arg aArgs[])
return ProcessGetSet(aArgs, otThreadGetDomainName, otThreadSetDomainName);
}
#if OPENTHREAD_CONFIG_DUA_ENABLE
template <> otError Interpreter::Process<Cmd("dua")>(Arg aArgs[])
{
otError error = OT_ERROR_NONE;
/**
* @cli dua iid
* @code
* dua iid
* 0004000300020001
* Done
* @endcode
* @par api_copy
* #otThreadGetFixedDuaInterfaceIdentifier
*/
if (aArgs[0] == "iid")
{
if (aArgs[1].IsEmpty())
{
const otIp6InterfaceIdentifier *iid = otThreadGetFixedDuaInterfaceIdentifier(GetInstancePtr());
if (iid != nullptr)
{
OutputBytesLine(iid->mFields.m8);
}
}
/**
* @cli dua iid (set,clear)
* @code
* dua iid 0004000300020001
* Done
* @endcode
* @code
* dua iid clear
* Done
* @endcode
* @cparam dua iid @ca{iid|clear}
* `dua iid clear` passes a `nullptr` to #otThreadSetFixedDuaInterfaceIdentifier.
* Otherwise, you can pass the `iid`.
* @par api_copy
* #otThreadSetFixedDuaInterfaceIdentifier
*/
else if (aArgs[1] == "clear")
{
error = otThreadSetFixedDuaInterfaceIdentifier(GetInstancePtr(), nullptr);
}
else
{
otIp6InterfaceIdentifier iid;
SuccessOrExit(error = aArgs[1].ParseAsHexString(iid.mFields.m8));
error = otThreadSetFixedDuaInterfaceIdentifier(GetInstancePtr(), &iid);
}
}
else
{
error = OT_ERROR_INVALID_COMMAND;
}
exit:
return error;
}
#endif // OPENTHREAD_CONFIG_DUA_ENABLE
#endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
/**
@@ -2918,35 +2874,53 @@ void Interpreter::OutputEidCacheEntry(const otCacheEntryInfo &aEntry)
OutputNewLine();
}
/**
* @cli eidcache
* @code
* eidcache
* fd49:caf4:a29f:dc0e:97fc:69dd:3c16:df7d 2000 cache canEvict=1 transTime=0 eid=fd49:caf4:a29f:dc0e:97fc:69dd:3c16:df7d
* fd49:caf4:a29f:dc0e:97fc:69dd:3c16:df7f fffe retry canEvict=1 timeout=10 retryDelay=30
* Done
* @endcode
* @par
* Returns the EID-to-RLOC cache entries.
* @sa otThreadGetNextCacheEntry
*/
template <> otError Interpreter::Process<Cmd("eidcache")>(Arg aArgs[])
{
OT_UNUSED_VARIABLE(aArgs);
otError error = OT_ERROR_NONE;
otCacheEntryIterator iterator;
otCacheEntryInfo entry;
ClearAllBytes(iterator);
while (true)
/**
* @cli eidcache
* @code
* eidcache
* fd49:caf4:a29f:dc0e:97fc:69dd:3c16:df7d 2000 cache canEvict=1 transTime=0
* eid=fd49:caf4:a29f:dc0e:97fc:69dd:3c16:df7d fd49:caf4:a29f:dc0e:97fc:69dd:3c16:df7f fffe retry
* canEvict=1 timeout=10 retryDelay=30 Done
* @endcode
* @par
* Returns the EID-to-RLOC cache entries.
* @sa otThreadGetNextCacheEntry
*/
if (aArgs[0].IsEmpty())
{
SuccessOrExit(otThreadGetNextCacheEntry(GetInstancePtr(), &entry, &iterator));
OutputEidCacheEntry(entry);
}
otCacheEntryIterator iterator;
otCacheEntryInfo entry;
ClearAllBytes(iterator);
while (true)
{
SuccessOrExit(otThreadGetNextCacheEntry(GetInstancePtr(), &entry, &iterator));
OutputEidCacheEntry(entry);
}
}
/**
* @cli eidcache clear
* @code
* eidcache clear
* Done
* @endcode
* @par api_copy
* #otThreadClearEidCache
*/
else if (aArgs[0] == "clear")
{
otThreadClearEidCache(GetInstancePtr());
}
else
{
error = OT_ERROR_INVALID_ARGS;
}
exit:
return OT_ERROR_NONE;
return error;
}
#endif
@@ -3030,13 +3004,13 @@ template <> otError Interpreter::Process<Cmd("log")>(Arg aArgs[])
* @endcode
* @par
* Get the log level.
* @sa otLoggingGetLevel
* @sa otGetLogLevel
*/
if (aArgs[0] == "level")
{
if (aArgs[1].IsEmpty())
{
OutputLine("%d", otLoggingGetLevel());
OutputLine("%u", otGetLogLevel(GetInstancePtr()));
}
else
{
@@ -3050,12 +3024,12 @@ template <> otError Interpreter::Process<Cmd("log")>(Arg aArgs[])
* Done
* @endcode
* @par api_copy
* #otLoggingSetLevel
* #otSetLogLevel
* @cparam log level @ca{level}
*/
VerifyOrExit(aArgs[2].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
SuccessOrExit(error = aArgs[1].ParseAsUint8(level));
error = otLoggingSetLevel(static_cast<otLogLevel>(level));
error = otSetLogLevel(GetInstancePtr(), static_cast<otLogLevel>(level));
#else
error = OT_ERROR_INVALID_ARGS;
#endif
@@ -3177,20 +3151,6 @@ template <> otError Interpreter::Process<Cmd("fake")>(Arg aArgs[])
SuccessOrExit(error = aArgs[3].ParseAsHexString(mlIid.mFields.m8));
otThreadSendAddressNotification(GetInstancePtr(), &destination, &target, &mlIid);
}
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
else if (aArgs[0] == "/b/ba")
{
otIp6Address target;
otIp6InterfaceIdentifier mlIid;
uint32_t timeSinceLastTransaction;
SuccessOrExit(error = aArgs[1].ParseAsIp6Address(target));
SuccessOrExit(error = aArgs[2].ParseAsHexString(mlIid.mFields.m8));
SuccessOrExit(error = aArgs[3].ParseAsUint32(timeSinceLastTransaction));
error = otThreadSendProactiveBackboneNotification(GetInstancePtr(), &target, &mlIid, timeSinceLastTransaction);
}
#endif
exit:
return error;
@@ -3316,6 +3276,12 @@ template <> otError Interpreter::Process<Cmd("ifconfig")>(Arg aArgs[])
{
SuccessOrExit(error = otIp6SetEnabled(GetInstancePtr(), false));
}
#if OPENTHREAD_CONFIG_IP6_INIT_EXT_ADDR_POOL_ENABLE && OPENTHREAD_CONFIG_CLI_IFCONFIG_INIT_ENABLE
else if (aArgs[0] == "init")
{
error = ProcessIfconfigInit(aArgs + 1);
}
#endif
else
{
ExitNow(error = OT_ERROR_INVALID_ARGS);
@@ -3325,6 +3291,60 @@ exit:
return error;
}
#if OPENTHREAD_CONFIG_IP6_INIT_EXT_ADDR_POOL_ENABLE && OPENTHREAD_CONFIG_CLI_IFCONFIG_INIT_ENABLE
otError Interpreter::ProcessIfconfigInit(Arg aArgs[])
{
/**
* @cli ifconfig init
* @code
* ifconfig init 5 6
* Done
* @endcode
* @cparam ifconfig @ca{unicast-addr-pool-size} @ca{multicast-addr-pool-size}
* @par
* This command is intended for testing purposes only and requires `OPENTHREAD_CONFIG_CLI_IFCONFIG_INIT_ENABLE`
* and `OPENTHREAD_CONFIG_IP6_INIT_EXT_ADDR_POOL_ENABLE`.
* @par api_copy
* #otIp6Init
*/
otError error;
uint16_t unicastPoolSize;
uint16_t multicastPoolSize;
otNetifAddress *unicastPool = nullptr;
otNetifMulticastAddress *multicastPool = nullptr;
SuccessOrExit(error = aArgs[0].ParseAsUint16(unicastPoolSize));
SuccessOrExit(error = aArgs[1].ParseAsUint16(multicastPoolSize));
VerifyOrExit(aArgs[2].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
if (unicastPoolSize > 0)
{
unicastPool = static_cast<otNetifAddress *>(otHeapCAlloc(unicastPoolSize, sizeof(otNetifAddress)));
VerifyOrExit(unicastPool != nullptr, error = OT_ERROR_NO_BUFS);
}
if (multicastPoolSize > 0)
{
multicastPool =
static_cast<otNetifMulticastAddress *>(otHeapCAlloc(multicastPoolSize, sizeof(otNetifMulticastAddress)));
VerifyOrExit(multicastPool != nullptr, error = OT_ERROR_NO_BUFS);
}
SuccessOrExit(error = otIp6Init(GetInstancePtr(), unicastPool, unicastPoolSize, multicastPool, multicastPoolSize));
unicastPool = nullptr;
multicastPool = nullptr;
exit:
otHeapFree(unicastPool);
otHeapFree(multicastPool);
return error;
}
#endif // OPENTHREAD_CONFIG_IP6_INIT_EXT_ADDR_POOL_ENABLE && OPENTHREAD_CONFIG_CLI_IFCONFIG_INIT_ENABLE
template <> otError Interpreter::Process<Cmd("instanceid")>(Arg aArgs[])
{
/**
@@ -5430,9 +5450,6 @@ template <> otError Interpreter::Process<Cmd("prefix")>(Arg aArgs[])
* @endcode
* @par
* Get the prefix list in the local Network Data.
* @note For the Thread 1.2 border router with backbone capability, the local Domain Prefix
* is listed as well and includes the `D` flag. If backbone functionality is disabled, a dash
* `-` is printed before the local Domain Prefix.
* @par
* For more information about #otBorderRouterConfig flags, refer to @overview.
* @sa otBorderRouterGetNextOnMeshPrefix
@@ -5446,15 +5463,6 @@ template <> otError Interpreter::Process<Cmd("prefix")>(Arg aArgs[])
{
mNetworkData.OutputPrefix(config);
}
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
if (otBackboneRouterGetState(GetInstancePtr()) == OT_BACKBONE_ROUTER_STATE_DISABLED)
{
SuccessOrExit(otBackboneRouterGetDomainPrefix(GetInstancePtr(), &config));
OutputFormat("- ");
mNetworkData.OutputPrefix(config);
}
#endif
}
/**
* @cli prefix add
@@ -5542,7 +5550,7 @@ exit:
* Specifies the preferred router ID that the leader should provide when solicited.
* @sa otThreadSetPreferredRouterId
*/
#if OPENTHREAD_FTD
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
template <> otError Interpreter::Process<Cmd("preferrouterid")>(Arg aArgs[])
{
return ProcessSet(aArgs, otThreadSetPreferredRouterId);
@@ -6286,10 +6294,10 @@ template <> otError Interpreter::Process<Cmd("singleton")>(Arg aArgs[])
#if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
template <> otError Interpreter::Process<Cmd("sntp")>(Arg aArgs[])
{
otError error = OT_ERROR_NONE;
uint16_t port = OT_SNTP_DEFAULT_SERVER_PORT;
Ip6::MessageInfo messageInfo;
otSntpQuery query;
otError error = OT_ERROR_NONE;
uint16_t port = OT_SNTP_DEFAULT_SERVER_PORT;
otMessageInfo messageInfo;
otSntpQuery query;
/**
* @cli sntp query
@@ -6315,14 +6323,16 @@ template <> otError Interpreter::Process<Cmd("sntp")>(Arg aArgs[])
{
VerifyOrExit(!mSntpQueryingInProgress, error = OT_ERROR_BUSY);
ClearAllBytes(messageInfo);
if (!aArgs[1].IsEmpty())
{
SuccessOrExit(error = aArgs[1].ParseAsIp6Address(messageInfo.GetPeerAddr()));
SuccessOrExit(error = aArgs[1].ParseAsIp6Address(messageInfo.mPeerAddr));
}
else
{
// Use IPv6 address of default SNTP server.
SuccessOrExit(error = messageInfo.GetPeerAddr().FromString(OT_SNTP_DEFAULT_SERVER_IP));
SuccessOrExit(error = otIp6AddressFromString(OT_SNTP_DEFAULT_SERVER_IP, &messageInfo.mPeerAddr));
}
if (!aArgs[2].IsEmpty())
@@ -6330,9 +6340,8 @@ template <> otError Interpreter::Process<Cmd("sntp")>(Arg aArgs[])
SuccessOrExit(error = aArgs[2].ParseAsUint16(port));
}
messageInfo.SetPeerPort(port);
query.mMessageInfo = static_cast<const otMessageInfo *>(&messageInfo);
messageInfo.mPeerPort = port;
query.mMessageInfo = &messageInfo;
SuccessOrExit(error = otSntpClientQuery(GetInstancePtr(), &query, &Interpreter::HandleSntpResponse, this));
@@ -6794,14 +6803,11 @@ template <> otError Interpreter::Process<Cmd("debug")>(Arg aArgs[])
"uptime",
#endif
"attachtime",
"channel",
"panid",
"extpanid",
"dataset active -ns",
"ipaddr -v",
"ipmaddr",
"netdata show",
"netdata show -x",
"partitionid",
"leaderdata",
"bufferinfo",
"netstat",
@@ -7004,6 +7010,32 @@ template <> otError Interpreter::Process<Cmd("unsecureport")>(Arg aArgs[])
OutputNewLine();
}
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
/**
* @cli unsecureport allwhendisabled
* @code
* unsecureport allwhendisabled
* Disabled
* Done
* @endcode
* @par api_copy
* #otIp6IsUnsecureAllowedWhenDisabled
*/
else if (aArgs[0] == "allwhendisabled")
{
/**
* @cli unsecureport allwhendisabled (enable, disable)
* @code
* unsecureport allwhendisabled enable
* Done
* @endcode
* @cparam unsecureport allwhendisabled @ca{enable|disable}
* @par api_copy
* #otIp6SetAllowUnsecureWhenDisabled
*/
error = ProcessEnableDisable(aArgs + 1, otIp6IsUnsecureAllowedWhenDisabled, otIp6SetAllowUnsecureWhenDisabled);
}
#endif // OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
else
{
error = OT_ERROR_INVALID_COMMAND;
@@ -7553,6 +7585,53 @@ template <> otError Interpreter::Process<Cmd("vendor")>(Arg aArgs[])
error = ProcessGetSet(aArgs, otThreadGetVendorAppUrl, otThreadSetVendorAppUrl);
#endif
}
/**
* @cli vendor oui
* @code
* vendor oui
* B4-A6-61
* Done
* @endcode
* @par api_copy
* #otThreadGetVendorOui
*/
else if (aArgs[0] == "oui")
{
if (aArgs[1].IsEmpty())
{
uint32_t oui = otThreadGetVendorOui(GetInstancePtr());
if (oui == OT_THREAD_UNSPECIFIED_VENDOR_OUI)
{
OutputLine("unspecified");
}
else
{
OutputLine("%02X-%02X-%02X", static_cast<uint8_t>((oui >> 16) & 0xff),
static_cast<uint8_t>((oui >> 8) & 0xff), static_cast<uint8_t>(oui & 0xff));
}
error = OT_ERROR_NONE;
}
else
{
#if OPENTHREAD_CONFIG_NET_DIAG_VENDOR_INFO_SET_API_ENABLE
/**
* @cli vendor oui (set)
* @code
* vendor oui 0xb4a661
* Done
* @endcode
* @par api_copy
* #otThreadSetVendorOui
* @cparam vendor oui @ca{oui}
*/
error = ProcessSet(aArgs + 1, otThreadSetVendorOui);
#else
error = OT_ERROR_INVALID_ARGS;
#endif
}
}
return error;
}
@@ -7724,13 +7803,12 @@ void Interpreter::HandleDiagnosticGetResponse(otError aError,
const otMessageInfo *aMessageInfo,
void *aContext)
{
static_cast<Interpreter *>(aContext)->HandleDiagnosticGetResponse(
aError, aMessage, static_cast<const Ip6::MessageInfo *>(aMessageInfo));
static_cast<Interpreter *>(aContext)->HandleDiagnosticGetResponse(aError, aMessage, aMessageInfo);
}
void Interpreter::HandleDiagnosticGetResponse(otError aError,
const otMessage *aMessage,
const Ip6::MessageInfo *aMessageInfo)
void Interpreter::HandleDiagnosticGetResponse(otError aError,
const otMessage *aMessage,
const otMessageInfo *aMessageInfo)
{
uint8_t buf[16];
uint16_t bytesToPrint;
@@ -8351,17 +8429,57 @@ void Interpreter::HandleWakeupResult(otError aError) { OutputResult(aError); }
#endif // OPENTHREAD_FTD || OPENTHREAD_MTD
void Interpreter::Initialize(otInstance *aInstance, otCliOutputCallback aCallback, void *aContext)
{
Instance *instance = static_cast<Instance *>(aInstance);
size_t Interpreter::GetSize(void) { return sizeof(Interpreter); }
Interpreter::sInterpreter = new (&sInterpreterRaw) Interpreter(instance, aCallback, aContext);
Interpreter *Interpreter::Init(void *aBuffer,
size_t aSize,
otInstance *aInstance,
otCliOutputCallback aCallback,
void *aContext)
{
Interpreter *interpreter = nullptr;
Instance *instance = static_cast<Instance *>(aInstance);
VerifyOrExit(aSize >= sizeof(Interpreter));
interpreter = new (aBuffer) Interpreter(instance, aCallback, aContext);
exit:
return interpreter;
}
#if OPENTHREAD_CONFIG_CLI_STATIC_INTERPRETER_ENABLE
Interpreter *Interpreter::sInterpreter = nullptr;
static OT_DEFINE_ALIGNED_VAR(sInterpreterRaw, sizeof(Interpreter), uint64_t);
void Interpreter::Init(otInstance *aInstance, otCliOutputCallback aCallback, void *aContext)
{
sInterpreter = Init(&sInterpreterRaw, sizeof(sInterpreterRaw), aInstance, aCallback, aContext);
}
#endif
void Interpreter::Finalize(void)
{
mTimer.Stop();
#if (OPENTHREAD_FTD || OPENTHREAD_MTD) && OPENTHREAD_CONFIG_CLI_REGISTER_IP6_RECV_CALLBACK
otIp6SetReceiveCallback(GetInstancePtr(), nullptr, nullptr);
#endif
#if OPENTHREAD_CONFIG_DIAG_ENABLE
otDiagSetOutputCallback(GetInstancePtr(), nullptr, nullptr);
#endif
this->~Interpreter();
}
void Interpreter::OutputPrompt(void)
{
#if OPENTHREAD_CONFIG_CLI_PROMPT_ENABLE
static const char sPrompt[] = "> ";
static const char kPrompt[] = "> ";
VerifyOrExit(mPromptEnabled);
// The `OutputFormat()` below is adding the prompt which is not
// part of any command output, so we set the `EmittingCommandOutput`
@@ -8369,9 +8487,12 @@ void Interpreter::OutputPrompt(void)
// log (under `OPENTHREAD_CONFIG_CLI_LOG_INPUT_OUTPUT_ENABLE`).
SetEmittingCommandOutput(false);
OutputFormat("%s", sPrompt);
OutputFormat("%s", kPrompt);
SetEmittingCommandOutput(true);
#endif // OPENTHREAD_CONFIG_CLI_PROMPT_ENABLE
exit:
return;
#endif
}
void Interpreter::HandleTimer(Timer &aTimer)
@@ -8474,9 +8595,6 @@ otError Interpreter::ProcessCommand(Arg aArgs[])
#if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
CmdEntry("domainname"),
#endif
#if OPENTHREAD_CONFIG_DUA_ENABLE
CmdEntry("dua"),
#endif
#if OPENTHREAD_FTD
CmdEntry("eidcache"),
#endif
@@ -8578,7 +8696,7 @@ otError Interpreter::ProcessCommand(Arg aArgs[])
#endif
CmdEntry("platform"),
CmdEntry("pollperiod"),
#if OPENTHREAD_FTD
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
CmdEntry("preferrouterid"),
#endif
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
@@ -8701,54 +8819,5 @@ otError Interpreter::ProcessCommand(Arg aArgs[])
return error;
}
extern "C" void otCliInit(otInstance *aInstance, otCliOutputCallback aCallback, void *aContext)
{
Interpreter::Initialize(aInstance, aCallback, aContext);
#if OPENTHREAD_CONFIG_CLI_VENDOR_COMMANDS_ENABLE && OPENTHREAD_CONFIG_CLI_MAX_USER_CMD_ENTRIES > 1
otCliVendorSetUserCommands();
#endif
}
extern "C" void otCliInputLine(char *aBuf) { Interpreter::GetInterpreter().ProcessLine(aBuf); }
extern "C" otError otCliSetUserCommands(const otCliCommand *aUserCommands, uint8_t aLength, void *aContext)
{
return Interpreter::GetInterpreter().SetUserCommands(aUserCommands, aLength, aContext);
}
extern "C" void otCliOutputBytes(const uint8_t *aBytes, uint8_t aLength)
{
Interpreter::GetInterpreter().OutputBytes(aBytes, aLength);
}
extern "C" void otCliOutputFormat(const char *aFmt, ...)
{
va_list aAp;
va_start(aAp, aFmt);
Interpreter::GetInterpreter().OutputFormatV(aFmt, aAp);
va_end(aAp);
}
extern "C" void otCliAppendResult(otError aError) { Interpreter::GetInterpreter().OutputResult(aError); }
extern "C" void otCliPlatLogv(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, va_list aArgs)
{
OT_UNUSED_VARIABLE(aLogLevel);
OT_UNUSED_VARIABLE(aLogRegion);
VerifyOrExit(Interpreter::IsInitialized());
// CLI output is being used for logging, so we set the flag
// `EmittingCommandOutput` to false indicate this.
Interpreter::GetInterpreter().SetEmittingCommandOutput(false);
Interpreter::GetInterpreter().OutputFormatV(aFormat, aArgs);
Interpreter::GetInterpreter().OutputNewLine();
Interpreter::GetInterpreter().SetEmittingCommandOutput(true);
exit:
return;
}
} // namespace Cli
} // namespace ot
+69 -12
View File
@@ -86,10 +86,13 @@
#include "common/type_traits.hpp"
#include "instance/instance.hpp"
typedef struct otCliInterpreter
{
} otCliInterpreter;
namespace ot {
/**
* @namespace ot::Cli
*
* @brief
* This namespace contains definitions for the CLI interpreter.
@@ -104,7 +107,7 @@ extern "C" void otCliOutputFormat(const char *aFmt, ...);
/**
* Implements the CLI interpreter.
*/
class Interpreter : public OutputImplementer, public Utils
class Interpreter : public otCliInterpreter, public OutputImplementer, public Utils
{
#if OPENTHREAD_FTD || OPENTHREAD_MTD
friend class Ba;
@@ -122,6 +125,8 @@ class Interpreter : public OutputImplementer, public Utils
friend class SrpClient;
friend class SrpServer;
#endif
friend class Utils;
friend void otCliPlatLogv(otLogLevel, otLogRegion, const char *, va_list);
friend void otCliAppendResult(otError aError);
friend void otCliOutputBytes(const uint8_t *aBytes, uint8_t aLength);
@@ -137,34 +142,65 @@ public:
*/
explicit Interpreter(Instance *aInstance, otCliOutputCallback aCallback, void *aContext);
#if OPENTHREAD_CONFIG_CLI_STATIC_INTERPRETER_ENABLE
/**
* Returns a reference to the interpreter object.
* Returns a reference to the static CLI interpreter.
*
* @returns A reference to the interpreter object.
* @returns A reference to the static CLI interpreter.
*/
static Interpreter &GetInterpreter(void)
{
OT_ASSERT(sInterpreter != nullptr);
return *sInterpreter;
}
/**
* Initializes the Console interpreter.
* Initializes the static CLI interpreter.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aCallback A pointer to a callback method.
* @param[in] aContext A pointer to a user context.
*/
static void Initialize(otInstance *aInstance, otCliOutputCallback aCallback, void *aContext);
static void Init(otInstance *aInstance, otCliOutputCallback aCallback, void *aContext);
/**
* Returns whether the interpreter is initialized.
* Returns whether the static CLI interpreter is initialized.
*
* @returns Whether the interpreter is initialized.
*/
static bool IsInitialized(void) { return sInterpreter != nullptr; }
#endif // OPENTHREAD_CONFIG_CLI_STATIC_INTERPRETER_ENABLE
/**
* Gets the size of the CLI interpreter object.
*
* @returns The size of the CLI interpreter object in bytes.
*/
static size_t GetSize(void);
/**
* Initializes a CLI interpreter.
*
* @param[in] aBuffer A pointer to a memory buffer for the CLI interpreter.
* @param[in] aSize The size of the memory buffer.
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aCallback A callback method called to process CLI output.
* @param[in] aContext A user context pointer.
*
* @returns A pointer to the initialized CLI interpreter, or `nullptr` if @p aSize is too small.
*/
static Interpreter *Init(void *aBuffer,
size_t aSize,
otInstance *aInstance,
otCliOutputCallback aCallback,
void *aContext);
/**
* Finalizes the CLI interpreter.
*/
void Finalize(void);
/**
* Interprets a CLI command.
*
@@ -177,15 +213,28 @@ public:
*
* @param[in] aCommands A pointer to an array with user commands.
* @param[in] aLength @p aUserCommands length.
* @param[in] aContext @p aUserCommands length.
* @param[in] aContext Context to use when invoking the command handler.
*
* @retval OT_ERROR_NONE Successfully updated command table with commands from @p aCommands.
* @retval OT_ERROR_FAILED No available UserCommandsEntry to register requested user commands.
* @retval OT_ERROR_NONE Successfully updated command table with commands from @p aCommands.
* @retval OT_ERROR_NO_BUFS No available `UserCommandsEntry` to register the requested user commands.
*/
otError SetUserCommands(const otCliCommand *aCommands, uint8_t aLength, void *aContext);
#if OPENTHREAD_CONFIG_CLI_PROMPT_ENABLE
/**
* Configures whether or not the CLI interpreter outputs prompt string.
*
* It is enabled by default.
*
* @param[in] aEnabled TRUE to enable outputting prompt, FALSE to disable.
*/
void SetPromptConfig(bool aEnabled);
#endif
protected:
#if OPENTHREAD_CONFIG_CLI_STATIC_INTERPRETER_ENABLE
static Interpreter *sInterpreter;
#endif
private:
static constexpr uint8_t kIndentSize = 4;
@@ -228,6 +277,11 @@ private:
#if OPENTHREAD_FTD
void OutputEidCacheEntry(const otCacheEntryInfo &aEntry);
#endif
#if OPENTHREAD_CONFIG_IP6_INIT_EXT_ADDR_POOL_ENABLE && OPENTHREAD_CONFIG_CLI_IFCONFIG_INIT_ENABLE
otError ProcessIfconfigInit(Arg aArgs[]);
#endif
#if OPENTHREAD_CONFIG_TMF_ANYCAST_LOCATOR_ENABLE
static void HandleLocateResult(void *aContext,
otError aError,
@@ -255,7 +309,7 @@ private:
static void HandleLinkPcapReceive(const otRadioFrame *aFrame, bool aIsTx, void *aContext);
#if OPENTHREAD_CONFIG_TMF_NETDIAG_CLIENT_ENABLE
void HandleDiagnosticGetResponse(otError aError, const otMessage *aMessage, const Ip6::MessageInfo *aMessageInfo);
void HandleDiagnosticGetResponse(otError aError, const otMessage *aMessage, const otMessageInfo *aMessageInfo);
static void HandleDiagnosticGetResponse(otError aError,
otMessage *aMessage,
const otMessageInfo *aMessageInfo,
@@ -348,6 +402,9 @@ private:
UserCommandsEntry mUserCommands[kMaxUserCommandEntries];
bool mCommandIsPending;
bool mInternalDebugCommand;
#if OPENTHREAD_CONFIG_CLI_PROMPT_ENABLE
bool mPromptEnabled;
#endif
TimerMilliContext mTimer;
+128
View File
@@ -0,0 +1,128 @@
/*
* Copyright (c) 2016-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.
*/
/**
* @file
* This file implements the CLI public APIs.
*/
#include <openthread/cli.h>
#include "cli.hpp"
namespace ot {
namespace Cli {
extern "C" size_t otCliInterpreterGetSize(void) { return Interpreter::GetSize(); }
extern "C" otCliInterpreter *otCliInterpreterInit(void *aBuffer,
size_t aSize,
otInstance *aInstance,
otCliOutputCallback aCallback,
void *aContext)
{
return Interpreter::Init(aBuffer, aSize, aInstance, aCallback, aContext);
}
#if OPENTHREAD_CONFIG_CLI_PROMPT_ENABLE
extern "C" void otCliInterpreterSetPromptConfig(otCliInterpreter *aInterpreter, bool aEnable)
{
static_cast<Interpreter *>(aInterpreter)->SetPromptConfig(aEnable);
}
#endif
extern "C" void otCliInterpreterInputLine(otCliInterpreter *aInterpreter, char *aLine)
{
static_cast<Interpreter *>(aInterpreter)->ProcessLine(aLine);
}
extern "C" void otCliInterpreterFinalize(otCliInterpreter *aInterpreter)
{
static_cast<Interpreter *>(aInterpreter)->Finalize();
}
//---------------------------------------------------------------------------------------------------------------------
#if OPENTHREAD_CONFIG_CLI_STATIC_INTERPRETER_ENABLE
extern "C" void otCliInit(otInstance *aInstance, otCliOutputCallback aCallback, void *aContext)
{
Interpreter::Init(aInstance, aCallback, aContext);
#if OPENTHREAD_CONFIG_CLI_VENDOR_COMMANDS_ENABLE && OPENTHREAD_CONFIG_CLI_MAX_USER_CMD_ENTRIES > 1
otCliVendorSetUserCommands();
#endif
}
extern "C" otCliInterpreter *otCliGetStaticInterpreter(void) { return &Interpreter::GetInterpreter(); }
extern "C" void otCliInputLine(char *aLine) { Interpreter::GetInterpreter().ProcessLine(aLine); }
extern "C" otError otCliSetUserCommands(const otCliCommand *aUserCommands, uint8_t aLength, void *aContext)
{
return Interpreter::GetInterpreter().SetUserCommands(aUserCommands, aLength, aContext);
}
extern "C" void otCliOutputBytes(const uint8_t *aBytes, uint8_t aLength)
{
Interpreter::GetInterpreter().OutputBytes(aBytes, aLength);
}
extern "C" void otCliOutputFormat(const char *aFmt, ...)
{
va_list args;
va_start(args, aFmt);
Interpreter::GetInterpreter().OutputFormatV(aFmt, args);
va_end(args);
}
extern "C" void otCliAppendResult(otError aError) { Interpreter::GetInterpreter().OutputResult(aError); }
extern "C" void otCliPlatLogv(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, va_list aArgs)
{
OT_UNUSED_VARIABLE(aLogLevel);
OT_UNUSED_VARIABLE(aLogRegion);
VerifyOrExit(Interpreter::IsInitialized());
// CLI output is being used for logging, so we set the flag
// `EmittingCommandOutput` to false indicate this.
Interpreter::GetInterpreter().SetEmittingCommandOutput(false);
Interpreter::GetInterpreter().OutputFormatV(aFormat, aArgs);
Interpreter::GetInterpreter().OutputNewLine();
Interpreter::GetInterpreter().SetEmittingCommandOutput(true);
exit:
return;
}
#endif // OPENTHREAD_CONFIG_CLI_STATIC_INTERPRETER_ENABLE
} // namespace Cli
} // namespace ot
-49
View File
@@ -174,55 +174,6 @@ template <> otError Bbr::Process<Cmd("mgmt")>(Arg aArgs[])
ExitNow(error = OT_ERROR_INVALID_COMMAND);
}
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE && OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
/**
* @cli bbr mgmt dua
* @code
* bbr mgmt dua 1 2f7c235e5025a2fd
* Done
* @endcode
* @code
* bbr mgmt dua 160
* Done
* @endcode
* @cparam bbr mgmt dua @ca{status|coap-code} [@ca{meshLocalIid}]
* For `status` or `coap-code`, use:
* * 0: ST_DUA_SUCCESS
* * 1: ST_DUA_REREGISTER
* * 2: ST_DUA_INVALID
* * 3: ST_DUA_DUPLICATE
* * 4: ST_DUA_NO_RESOURCES
* * 5: ST_DUA_BBR_NOT_PRIMARY
* * 6: ST_DUA_GENERAL_FAILURE
* * 160: COAP code 5.00
* @par
* With the `meshLocalIid` included, this command configures the response status
* for the next DUA registration. Without `meshLocalIid`, respond to the next
* DUA.req with the specified `status` or `coap-code`.
* @par
* Available when `OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE` is enabled.
* @sa otBackboneRouterConfigNextDuaRegistrationResponse
*/
if (aArgs[0] == "dua")
{
uint8_t status;
otIp6InterfaceIdentifier *mlIid = nullptr;
otIp6InterfaceIdentifier iid;
SuccessOrExit(error = aArgs[1].ParseAsUint8(status));
if (!aArgs[2].IsEmpty())
{
SuccessOrExit(error = aArgs[2].ParseAsHexString(iid.mFields.m8));
mlIid = &iid;
VerifyOrExit(aArgs[3].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
}
otBackboneRouterConfigNextDuaRegistrationResponse(GetInstancePtr(), mlIid, status);
ExitNow();
}
#endif // OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE && OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
#if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
if (aArgs[0] == "mlr")
{
+1 -2
View File
@@ -670,7 +670,6 @@ template <> otError Br::Process<Cmd("peers")>(Arg aArgs[])
* Data entries:
* - It has added at least one external route entry.
* - It has added at least one prefix entry with both the default-route and on-mesh flags set.
* - It has added at least one domain prefix (with both the domain and on-mesh flags set).
* The list of peer BRs specifically excludes the current device, even if its is itself acting as a BR.
* Info per BR entry:
* - RLOC16 of the BR
@@ -1200,7 +1199,7 @@ template <> otError Br::Process<Cmd("counters")>(Arg aArgs[])
otError error = OT_ERROR_NONE;
VerifyOrExit(aArgs[0].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
Interpreter::GetInterpreter().OutputBorderRouterCounters();
GetInterpreter().OutputBorderRouterCounters();
exit:
return error;
+28 -9
View File
@@ -47,6 +47,21 @@
#endif
#endif
/**
* @def OPENTHREAD_CONFIG_CLI_STATIC_INTERPRETER_ENABLE
*
* Define as 1 to enable the static CLI interpreter.
*
* This configuration option enables the static CLI interpreter, allowing the CLI module to statically allocate and
* provide a single interpreter instance.
*
* This is intended to provide backward compatibility with the original `otCli*` APIs. It can be disabled to save RAM
* if the static CLI interpreter is not needed.
*/
#ifndef OPENTHREAD_CONFIG_CLI_STATIC_INTERPRETER_ENABLE
#define OPENTHREAD_CONFIG_CLI_STATIC_INTERPRETER_ENABLE 1
#endif
/**
* @def OPENTHREAD_CONFIG_CLI_MAX_LINE_LENGTH
*
@@ -69,6 +84,19 @@
#define OPENTHREAD_CONFIG_CLI_BLE_SECURE_ENABLE 1
#endif
/**
* @def OPENTHREAD_CONFIG_CLI_IFCONFIG_INIT_ENABLE
*
* Indicates whether or not the CLI `ifconfig init` command to be supported.
*
* This is applicable when `OPENTHREAD_CONFIG_IP6_INIT_EXT_ADDR_POOL_ENABLE` is used.
*
* The `ifconfig init` is intended for testing purposes only.
*/
#ifndef OPENTHREAD_CONFIG_CLI_IFCONFIG_INIT_ENABLE
#define OPENTHREAD_CONFIG_CLI_IFCONFIG_INIT_ENABLE 0
#endif
/**
* @def OPENTHREAD_CONFIG_CLI_TCP_ENABLE
*
@@ -187,13 +215,4 @@
#define OPENTHREAD_CONFIG_CLI_REGISTER_IP6_RECV_CALLBACK 0
#endif
/**
* @def OPENTHREAD_CONFIG_CLI_BLE_SECURE_ENABLE
*
* Define to 1 to enable BLE secure support.
*/
#ifndef OPENTHREAD_CONFIG_CLI_BLE_SECURE_ENABLE
#define OPENTHREAD_CONFIG_CLI_BLE_SECURE_ENABLE 0
#endif
#endif // OT_CLI_CLI_CONFIG_H_
+2 -3
View File
@@ -437,8 +437,6 @@ exit:
//----------------------------------------------------------------------------------------------------------------------
void Dns::OutputResult(otError aError) { Interpreter::GetInterpreter().OutputResult(aError); }
otError Dns::GetDnsConfig(Arg aArgs[], otDnsQueryConfig *&aConfig)
{
// This method gets the optional DNS config from `aArgs[]`.
@@ -454,7 +452,8 @@ otError Dns::GetDnsConfig(Arg aArgs[], otDnsQueryConfig *&aConfig)
VerifyOrExit(!aArgs[0].IsEmpty(), aConfig = nullptr);
SuccessOrExit(error = ParseToIp6Address(GetInstancePtr(), aArgs[0], aConfig->mServerSockAddr.mAddress, nat64Synth));
SuccessOrExit(error = ParseOrSynthesizeIp6Address(aArgs[0], aConfig->mServerSockAddr.mAddress, nat64Synth));
if (nat64Synth)
{
OutputFormat("Synthesized IPv6 DNS server address: ");
-1
View File
@@ -101,7 +101,6 @@ private:
template <CommandId kCommandId> otError Process(Arg aArgs[]);
#if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
void OutputResult(otError aError);
otError GetDnsConfig(Arg aArgs[], otDnsQueryConfig *&aConfig);
const char *DnsConfigServiceModeToString(otDnsServiceMode aMode) const;
otError ParseDnsServiceMode(const Arg &aArg, otDnsServiceMode &aMode) const;
-3
View File
@@ -1305,7 +1305,6 @@ void History::OutputRxTxEntryTableFormat(const otHistoryTrackerMessageInfo &aInf
* * `o`: On mesh flag.
* * `s`: Stable flag.
* * `n`: Nd Dns flag.
* * `D`: Domain prefix flag.
* * Pref: Preference. Values can be either `high`, `med`, or `low`.
* * RLOC16
* @sa otHistoryTrackerIterateOnMeshPrefixHistory
@@ -2026,8 +2025,6 @@ void History::HandleNetInfo(otError aError, const otHistoryTrackerNetworkInfo *a
OutputResult(aError);
}
void History::OutputResult(otError aError) { Interpreter::GetInterpreter().OutputResult(aError); }
#endif // #if OPENTHREAD_CONFIG_HISTORY_TRACKER_CLIENT_ENABLE
otError History::Process(Arg aArgs[])
-1
View File
@@ -101,7 +101,6 @@ private:
void OutputNetInfoEntry(bool aIsList, const otHistoryTrackerNetworkInfo &aInfo, uint32_t aEntryAge);
#if OPENTHREAD_CONFIG_HISTORY_TRACKER_CLIENT_ENABLE
void OutputResult(otError aError);
otError ParseQueryArgs(Arg aArgs[],
bool &aIsList,
uint16_t &aRloc16,
-2
View File
@@ -594,8 +594,6 @@ const char *LinkMetrics::LinkMetricsStatusToStr(otLinkMetricsStatus aStatus)
return str;
}
void LinkMetrics::OutputResult(otError aError) { Interpreter::GetInterpreter().OutputResult(aError); }
} // namespace Cli
} // namespace ot
-2
View File
@@ -115,8 +115,6 @@ private:
const char *LinkMetricsStatusToStr(otLinkMetricsStatus aStatus);
void OutputResult(otError aError);
bool mQuerySync : 1;
bool mConfigForwardTrackingSeriesSync : 1;
bool mConfigEnhAckProbingSync : 1;
+8
View File
@@ -41,6 +41,14 @@
#if OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_APP
#if OPENTHREAD_CONFIG_LOG_INSTANCE_AWARE_API_ENABLE
extern "C" OT_TOOL_WEAK void otPlatLogOutput(otInstance *aInstance, otLogLevel aLogLevel, const char *aLogLine)
{
OT_UNUSED_VARIABLE(aInstance);
otPlatLog(aLogLevel, OT_LOG_REGION_CORE, "%s", aLogLine);
}
#endif
extern "C" OT_TOOL_WEAK void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
{
va_list ap;
+1 -1
View File
@@ -456,7 +456,7 @@ void Mdns::HandleRegisterationDone(otMdnsRequestId aRequestId, otError aError)
if (mWaitingForCallback && (aRequestId == mRequestId))
{
mWaitingForCallback = false;
Interpreter::GetInterpreter().OutputResult(aError);
GetInterpreter().OutputResult(aError);
}
else
{

Some files were not shown because too many files have changed in this diff Show More