Thread topology data: no API path for parent-child relationships

I'm building a HomeKit app that discovers Thread devices and visualizes the mesh topology. I can detect device roles (Router vs End Device via characteristic 0x0703) and identify Border Routers (via _meshcop._udp), but I cannot determine which Router is the parent of a given End Device. Any Thread device can act as a Router (a Nanoleaf bulb, an Eve plug, not just HomePods), and End Devices attach to these Routers as children. That parent-child relationship is what I'm trying to map, but there's no RLOC16, neighbor table, or parent identifier exposed through any available API.

I've tested every path I can find. Here's what I've tried on a network with 44 Thread devices and 6 Border Routers:

What works (partially)

  • HAP Thread Management Service (0x0701) gives me the device role from characteristic 0x0703, the OpenThread version from 0x0706, and node capabilities from 0x0702. That's the complete set of characteristics on that service. None of them contain RLOC16, parent Router, or neighbor data. This service also only exists on HAP-native Thread devices. My 20 Matter-over-Thread devices (Aqara, Eve Door, SmartWings, Onvis S4) don't have it at all.

  • MeshCoP Bonjour (_meshcop._udp) identifies Border Routers and the network name/Extended PAN ID. No topology data about other mesh nodes.

What doesn't work

  • ThreadNetwork framework (THClient) - retrieveAllCredentials() returns error Code 3 because the app can't access credentials stored by Apple Home. Even if it worked, THCredentials only contains network config (name, PAN ID, channel), not topology.

  • Direct CoAP queries - Border Routers don't route traffic from WiFi to Thread management ports. Mesh-local addresses aren't reachable. No Thread NWInterface in Network.framework.

  • Network.framework - No visibility into the Thread mesh from the WiFi side.

The only remaining path I can see (but it's not practical)

  • Matter cluster 0x0035 (Thread Network Diagnostics) appears to have exactly what I need: RLOC16, NeighborTable with isChild boolean, RouteTable. I haven't implemented this because it requires commissioning each device individually onto my app's own Matter fabric via Multi-Admin. That's 21 separate user-initiated pairing actions on my network. I can't ask end users to do that.

The core issue

Every Thread Router (whether it's a HomePod acting as a Border Router or a Nanoleaf bulb acting as a mesh Router) knows its own children and neighbors. The Border Routers also maintain route tables covering the mesh backbone. This data exists on the user's own devices but none of it is exposed to third-party apps.

Even something minimal would help. HMAccessory already exposes matterNodeID as a cross-protocol identifier. Exposing RLOC16 the same way would be enough, since parent-child relationships are encoded in the address itself (ParentRLOC = ChildRLOC & 0xFC00).

Has anyone found another approach I'm missing?

Thanks in advance for any pointers.

Has anyone found another approach I'm missing?

I'm not aware of any API that would (directly) get you the information you're looking for. The information itself is only directly "needed" within the Thread network itself, so there hasn't really been any reason to expose it (assuming the device has it at all). I'm not sure how likely this is to change, but if you haven't already, I would encourage you to file a bug on this and then post the bug number back here.

Having said that, there might be an alternative approach, because this:

HMAccessory already exposes matterNodeID as a cross-protocol identifier.

...was NOT added to simply be a cross-protocol identifier. The real reason it was added was to allow developers to send Matter commands through our ecosystem pairing, using the flow I described in this forum post.

I haven't tried this particular cluster:

Matter cluster 0x0035 (Thread Network Diagnostics) appears to have exactly what I need: RLOC16, NeighborTable with isChild boolean, RouteTable.

...but, in theory, it should be possible, though a bit cumbersome, using the flow from the post above.

And, yes, that would remove the need for this:

I haven't implemented this because it requires commissioning each device individually onto my app's own Matter fabric via Multi-Admin.

...as everything is actually going through our ecosystem, not a new/seperate ecosystem pairing.

Finally, one note here:

That's 21 separate user-initiated pairing actions on my network. I can't ask end users to do that.

Speaking entirely for myself and having had some unpleasant issues dealing with Thread, this isn't necessarily as crazy as it sounds. Many of these issues tend to be relatively "targeted", so the user may only need to pair the accessories they're actually interested in at the time, not the "full" accessory set. Frankly, I'd love a nice tool that exposed this data in a useful way, particularly for macOS (if you're taking feature requests).

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Thread topology data: no API path for parent-child relationships
 
 
Q