openthread-br: locate the RCP dongle through otbr-rcp - #30276
openthread-br: locate the RCP dongle through otbr-rcp#30276LorbusChris wants to merge 4 commits into
Conversation
Switch from a pinned commit to the 2026.08.0 release tag (the latest release). Drop the two local patches whose fixes are upstream since 2026.07.0: - 101-rest-Permit-to-externally-provide-cJSON-library.patch - 102-openwrt-fix-LuCI-icons.patch Adjust CMAKE_OPTIONS for the proxy rework that arrived with 2026.07.0. That release added OT core Advertising and Discovery Proxies that default on whenever OTBR_MDNS is set and are mutually exclusive with the legacy POSIX proxies, so forcing OTBR_SRP_ADVERTISING_PROXY=ON and OTBR_DNSSD_DISCOVERY_PROXY=ON now fails configure with "Only one Advertising Proxy can be enabled." Drop both flags to adopt the OT core proxies, matching upstream's default build. Also drop OTBR_DUA_ROUTING, which is no longer a recognized option. Set OTBR_VENDOR_NAME and OTBR_PRODUCT_NAME. 2026.07.0 removed the built-in defaults that border_agent.hpp used to supply, so otbr-agent now exits with "Vendor name must be set." unless they are given at compile time or on the command line. They are set to OpenThread and BorderRouter, the values those defaults had, rather than to anything OpenWrt specific. The pair also forms the MeshCoP service instance name, as "<vendor> <product>", which is the name shown when adding the border router in a Thread client and the one already-paired clients have recorded. Keeping the previous values means upgrading does not rename anyone's border router. It also leaves OTBR_NAME at OpenThread_BorderRouter, which is what it defaulted to. Pass OTBR_VERSION=$(PKG_VERSION). Left alone, otbr-agent --version reports the upstream CMake project version (0.3.0), which is unrelated to the version this package is built from, so the generic version check fails -- as it already does on master, independently of this update. OTBR_VERSION overrides that string at configure time, so the binary reports the version it was packaged as and the check passes with no override script. luci-app-openthread installs no executables, so the generic checks have nothing to probe there and need no override either. Add a test.sh as the functional smoke test: it exercises both binaries, which also covers their runtime library closure. ot-ctl is probed with -h because it has no version option at this release (openthread/openthread#13424 adds one, but the bundled openthread predates it). The segfault on unrecognized long options that earlier made -h the only safe probe is fixed in the openthread this release bundles (openthread/openthread#13423). The mDNS provider is left unchanged here; a follow-up commit switches it to OpenThread's internal implementation. Signed-off-by: Christian Glombek <c.glombek@cosa.systems> Assisted-By: Claude Fable 5
As of the 2026.07.0 update, otbr-agent's REST API defaults to listening on 127.0.0.1, so remote clients (e.g. Home Assistant on another host) can no longer reach it. Add rest_listen_address and rest_listen_port proto options and pass them through to otbr-agent when set; leaving them unset keeps the secure loopback-only default. Also drop the leftover unused 'foobar' proto config option. Signed-off-by: Christian Glombek <c.glombek@cosa.systems> Assisted-By: Claude Fable 5
Switch OTBR_MDNS from mDNSResponder to openthread, drop the mdnsd and mDNSResponder dependencies, and remove the proto handler's mdnsd service check, which would otherwise refuse to start otbr-agent now that mdnsd is no longer installed. This follows upstream, which made the internal implementation the default in openthread/ot-br-posix#2996 and uses it in its own OpenWrt example package, and it lets otbr-agent share a router with umdns, which is what advertises the router's procd-registered services (ssh, samba and the like) and resolves <hostname>.local. The two can coexist because they never contend for a name: OpenThread's mDNS names its host after the Thread extended address, while umdns keeps <hostname>.local. Both bind UDP 5353 with SO_REUSEADDR and each answers only for its own records. mDNSResponder instead takes its name from gethostname(), so it and umdns race for the same name, and the loser either stops announcing without logging anywhere procd captures or, if neither notices, both keep claiming it. That is the conflict with a running mdnsd noted in openwrt#29784. Border router discovery is unaffected: in this mode OpenThread's own border agent registers the _meshcop._udp service (its OPENTHREAD_CONFIG_BORDER_AGENT_MESHCOP_SERVICE_ENABLE follows OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE), and OTBR's publisher is disabled by design, so clients such as Home Assistant still find the border router. Note that OpenThread's mDNS serves a single interface, the one given by the backbone_network option, so Thread service records are announced on that network only. Signed-off-by: Christian Glombek <c.glombek@cosa.systems> Assisted-By: Claude Opus 4.8
Formality Check: Suggestions AvailableWe checked this pull request against the contribution guidelines. Here is what needs your attention:
|
openwrt-ai
left a comment
There was a problem hiding this comment.
Reviewed the four commits on this branch; the notes below are all on the last one (896a913), since the first three are #30091's. All four commit messages match what their diffs actually do.
Nothing here looks like a merge blocker. The two worth a decision before merge are the rcp_firmware_update default, which is opt-out in the code but documented as opt-in and now reachable from configs that never mentioned an RCP at all, and the eval of otbr-rcp stdout, which hands the documented firmware-handler plugin API a root shell in netifd's proto handler. The uart_flow_control default is a question rather than a finding. The rest are a doc/behaviour mismatch and two nits.
PKG_RELEASE is left to the formality bot.
Generated by Claude Code
The protocol handler required a hand-written radio_url, so pointing the border router at its dongle meant knowing which ttyACM the kernel had picked, and a replug that renumbered the device broke the interface until someone edited the config. Bring over the otbr-rcp wrapper from the matter-openwrt packaging: when no radio_url is set, the handler resolves the dongle by its USB properties (a cdc_acm interface on a device whose product string names OpenThread), with an rcp option to pin a bus position or a fixed serial device, and optional firmware install and update through handler plugins. Discovery runs in the setup phase rather than under the launched command, since a flash can take minutes and must not race the bounded wait for the agent's ubus object. Firmware install and update are off by default: flashing is an explicit act, and with the radio no longer required to be named, a configuration that mentions no RCP at all now reaches this path. The one value the handler needs is picked out of otbr-rcp's output rather than evaluated, since otbr-rcp sources every firmware handler plugin and stdout from one of those would otherwise run as root in the proto handler. A missing dongle fails setup with the restart block every failure needs, netifd retrying immediately and without backoff otherwise. The USB hotplug handler brings such interfaces up again when a device binds, keyed on the recorded RCP_NOT_FOUND error so interfaces an administrator took down on purpose stay down. An explicit radio_url keeps today's behaviour. Assisted-By: Claude Fable 5 Signed-off-by: Christian Glombek <c.glombek@cosa.systems>
896a913 to
98a7d04
Compare
Should land after #30091, whose commits this branch includes until it merges; the change here is the last commit only.
The protocol handler required a hand-written
radio_url, so pointing the border router at its dongle meant knowing which ttyACM the kernel had picked, and a replug that renumbered the device broke the interface until someone edited the config.Bring over the
otbr-rcpwrapper from the matter-openwrt packaging: when noradio_urlis set, the handler resolves the dongle by its USB properties (a cdc_acm interface on a device whose product string names OpenThread), with anrcpoption to pin a bus position or a fixed serial device, and optional firmware install and update through handler plugins. Discovery runs in the setup phase rather than under the launched command, since a flash can take minutes and must not race the bounded wait for the agent's ubus object.A missing dongle fails setup with the restart block every failure needs, netifd retrying immediately and without backoff otherwise. The USB hotplug handler brings such interfaces up again when a device binds, keyed on the recorded RCP_NOT_FOUND error so interfaces an administrator took down on purpose stay down. An explicit
radio_urlkeeps today's behaviour and overrides all of this.rcp '/dev/ttyACM0'rcp '2-1'rcp 'any'(default)uart_baudrate,uart_flow_controlrcp_firmware_updateThe wrapper's canonical home is project-chip/matter-openwrt, where its selection invariants are under review in project-chip/matter-openwrt#57; this copy mirrors that state and follows it. The same commit ships in the Turris OS packaging of this package. A LuCI follow-up exposing these options exists and opens once this lands (branch).
Testing
Package builds in the openwrt SDK (x86_64) with the full patch stack; both shell files pass
sh -n. The identical commit runs on Turris Omnia hardware via the Turris OS packaging.