Simplicity SDK 2026.6.0 - #205
Conversation
Bump Z-Wave version
|
CC @burmistrzak. I've also added the Z2M config tweaks in |
|
Reviewed against the local Simplicity SDK 2025.12.3 headers, the Full review — click to expandScopeDraft PR, all firmware targets build green (SkyConnect / Yellow / ZBT-2 NCP + router + RCP, ZWA-2, bootloaders). Gecko SDK 4.5.0 → Simplicity SDK 2025.12.3 for Zigbee NCP; SSDK bump for Thread RCP and Z-Wave. Supersedes #182. Verified each behavioral change rather than just reading the diff. Behavioral changes — all grounded in the Nerivec forkThe
Host side — covered by bellows
One open question
Confirmed good — no action
Verdict: no correctness blockers; the config is well-grounded in the Nerivec fork. The single substantive reviewer question is the |
Looking good! I assume you searched by hand for all these Z2M optimizations? |
Sure, go for it!
There's only one spot to look so it's not much of a search 😅. But you can always diff the intermediate SLCP + configs as a last resort, since they will contain the final config for the generated build tree. |
Sweet! Finally blinking lights and a fresh SDK! 😄
Duh! Checking the SLCP again, I totally misread the various conditions @Nerivec uses... |
| - id: zigbee_trust_center_keepalive | ||
| - id: zigbee_poll_control_client | ||
| - id: zigbee_bdb_3dot1_rejoin_algorithm | ||
| - id: zigbee_bdb_3dot1_trust_center_extension |
There was a problem hiding this comment.
According to Silabs, zigbee_bdb_3dot1_trust_center_extension should be disabled here.
A new BDB 3.1 Trust Center Extension component has been added to perform necessary Zigbee 4.0 behavior for trust centers. This component handles auto-discovery of devices that join the network. The component will send binding requests to any end devices that support the Poll Control cluster, as mandated by the BDB specifications. This component is only necessary for Zigbee 4.0 trust centers or coordinators.
There was a problem hiding this comment.
zigbee_router.slcp is essentially just the zigbee_z4_light.slcp project distributed with Simplicity SDK, just with some extensions added in. In earlier SDKs we based it on zigbee_z3_light.slcp but I've migrated it to the Zigbee 4.0 example router project in this PR.
There was a problem hiding this comment.
Yeah, that zigbee_z4_light.slcp example is a bit odd because it's a fancy dual role device.
The light acts as a dual role coordinator/router, which can either form a Zigbee 4.0 network or join (as a router) a Zigbee 4.0 network.
So for a router that simply joins an existing network, said component is not necessary.
|
Something's not right with 2015.12.x Z4 support for NCP. In my initial testing (with ZC having Also, can't add the new |
|
Thanks Nerivec — "not complete" holds up. tl;dr: the NCP is still R22, R23 DLK is unimplemented host-side in both bellows and Z2M/herdsman, and the join failure looks like a disabled-in-production TC path that DLK can't recover from once it's underway. 👇 Full breakdown — click to expand
Verified:
Join failure — from tracing the commissioning + BDB TC-link-key state machines. Per R23.2, DLK is optional/negotiated (§4.9.3: Key Request is the universal
So a Z4 joiner with no install code launches DLK, the TC dead-ends on the disabled anonymous path, and the joiner times out with no recovery — which fits "the ZC isn't replying, missing a code path." Z3 devices are unaffected (no DLK TLV → classic path directly). Caveat: whether your TC times out vs. sends an explicit reject, and whether an app-layer steering retry exists above the stack lib, needs a packet capture — but the gated anonymous dead-end and the no-fallback-once-DLK-is-underway are both in the binary. Net: the missing piece is host-side R23 DLK commissioning (absent in both bellows and Z2M) plus an enabled secret path on the TC (install code, or the gated anonymous one) — not the firmware bump. |
Yes, that's my impression as well. I don't think missing Z4 support on NCP is a deal breaker, at least for the moment. Bugfixes for Z3 and ZGP are way more important, IMHO. |
| //------------------------------------------------------------------------------ | ||
| // Multicast override (XNCP_FEATURE_MEMBER_OF_ALL_GROUPS) | ||
| //------------------------------------------------------------------------------ | ||
|
|
||
| bool __wrap_sli_zigbee_am_multicast_member(EmberMulticastId multicastId) | ||
| bool __wrap_sli_zigbee_am_multicast_member(xncp_multicast_id_t multicastId) | ||
| { | ||
| (void)multicastId; | ||
| // Ignore all binding and multicast table logic, we want all group packets | ||
| return true; | ||
| } | ||
|
|
There was a problem hiding this comment.
@puddly I believe that's the modification you were talking about?
At the moment, Z2M doesn't understand this behavior and @Nerivec is (rightfully) a bit hesitant about adding support.
Is there a good reason for overriding the default?
There was a problem hiding this comment.
It's a bit annoying to have to pre-register groups to appease the firmware. If you don't know the group ID in advance, you won't receive the packet. TI, deCONZ, etc. firmwares don't require this rigamarole and (rightfully) pass through all received packets.
I spoke to SiLabs about this and they're not interested in adding a wildcard value so this is the hack that we use. It can coexist with the existing multicast registration system if we increase the table size but it's simpler to just skip it outright, since it's unnecessary with this patch.
There was a problem hiding this comment.
I spoke to SiLabs about this and they're not interested in adding a wildcard value so this is the hack that we use.
Welp... Can't wait for the day we're able to move the entire Zigbee stack to the host and go full RCP. 🙏
It can coexist with the existing multicast registration system if we increase the table size but it's simpler to just skip it outright, since it's unnecessary with this patch.
Does ZHA expect said patch is always present or do you check before skipping registration?
There was a problem hiding this comment.
It's checked for and skipped if the feature is supported by the coordinator: https://github.com/zigpy/bellows/blob/cd3378f08b2a1275b02244c78079148faec4fe4c/bellows/zigbee/application.py#L248-L252
For other firmware builds, zigpy and bellows register the groups where we expect to receive packets.
There was a problem hiding this comment.
Yeah... I can now see where @Nerivec's hesitation was coming from:
While the ember driver in zigbee-herdsman has support for xncp, it's mostly uncharted territory. 😬
Implementing these custom xncp commands would however improve compatibility with stock NC firmware and free users from having to flash their new ZBT-2 with different firmware to get the best Z2M experience.
There was a problem hiding this comment.
I don't think compatibility is really a concern here, the two firmware builds are functionally identical save for a few table sizes. The only reason compatibility was even brought up in the past was because our multicast table was unintentionally a little small, something that is easily fixable in a future update. The tweak I added to disable firmware multicast filtering coexists cleanly with applications that still expect to manage the multicast table manually.
There was a problem hiding this comment.
Ok, so there wouldn't be any tangible benefits (for Z2M users) if we were to support your xncp extensions on our end?
It's fine by me, just wanted to make sure the the out-of-the-box experience is seamless, regardless of Zigbee implementation. 😊
There was a problem hiding this comment.
Only as tangible as you make them 😄.
- I use
get_mfg_token_overrideto override the board name and model of adapters by specifyingXNCP_MFG_BOARD_NAMEin the manifest YAML. MG21 Sonoff adapters, for example, didn't program a board or manufacturer name inUSERDATAin the factory. With this, you can just set it within the config and provide user-friendly strings via firmware. get_build_stringprovides a way to include a build string, to show when a firmware was built. We show it as part of the version string.get_flow_control_typecan be used to detect mismatches between the flow control expected by the firmware and the host-side serial config.get_chip_infotells you RAM size and the exact part number for the chip. ZHA uses this to set different software concurrency limits for MG21 and MG24/MG26 adapters.set_route_table_entryandget_route_table_entryare used by ZHA to back up and restore the route table at runtime, allowing for quickly restoring the Zigbee network state and bypassing the firmware route discovery storm on startup.- I'll eventually be adding a more self-contained packet sending command that will help reduce the number of serial round trips, speeding things up.
I very deliberately wrote the SiLabs firmware builder for the community. It's 100% generic and uses simple YAML config files specifically to allow the Zigbee community to generate good firmware for the endlessly growing list of adapters on the market. I build all of the Nabu Casa adapter firmwares out in the open for this very reason and keep all of the NC hardware-specific stuff isolated from the "core".
Personally, "stock" firmware for me doesn't exist, especially once you have control over the build. I added these XNCP commands to deal with SiLabs bugs and limitations and I think all of the extensions that we have are pretty useful. IMO, Z2M would find them as beneficial as ZHA does and I would greatly prefer to use an API that both projects can benefit from instead of fracturing the ecosystem.
There was a problem hiding this comment.
Only as tangible as you make them 😄.
🤓🫶
set_route_table_entryandget_route_table_entryare used by ZHA to back up and restore the route table at runtime, allowing for quickly restoring the Zigbee network state and bypassing the firmware route discovery storm on startup.
This is actually pretty huge! 🤩
Personally, "stock" firmware for me doesn't exist, especially once you have control over the build. I added these XNCP commands to deal with SiLabs bugs and limitations and I think all of the extensions that we have are pretty useful. IMO, Z2M would find them as beneficial as ZHA does and I would greatly prefer to use an API that both projects can benefit from instead of fracturing the ecosystem.
You're right, a minimal firmware is probably "worse" in some aspects because it doesn't include those mitigations. 😬
I'm in favor of implementing support for your XNCP extensions in ZH. @Nerivec Thoughts?
|
Ok, compiling the firmware via Docker worked well and I was able to successfully upgrade my ZBT-2 via However, the LED still stays off. Is that expected? I haven't cleared+restored NVM yet. Bootloader is at |
Yeah. For Zigbee, the LED pulses only as long as no network is formed. Once a network is formed, it stops and the LED turns off. OpenThread has no persistent state so the LED will start pulsing once a network stops running and then stop again once the network starts running. LED state is a bit hard to get right. It's been a low priority for the time being but I think we would need some NV3 storage mechanism (similar to the ZCL one) shared across both OpenThread and Zigbee firmware, along with an XNCP command (and whatever the OpenThread RCP equivalent is) to control the behavior. There already are commands to interact with the LEDs and the accelerometer but these won't persist if the coordinator is rebooted. |
Alright, thanks for confirming!
Sounds interesting, for sure. Also, here's a quick comparison between firmware builds (diff only):
|
| @@ -71,68 +71,79 @@ c_defines: | |||
| # should not use hardware flow control. | |||
| XNCP_FLOW_CONTROL_TYPE: usartHwFlowControlNone | |||
There was a problem hiding this comment.
@puddly Wait, there's no RTS/CTS between the host (Z2M/ZHA) and the ZBT-2? 😳
There was a problem hiding this comment.
The ZBT-2 uses an ESP32-S3 for the uart to usb connection. and the nature of that means the HW Flow is between the EFR32 and the ESP32 as the note says. It's similar to a network connected coordinator in that way - I use HW Flow for the mg24 devices I sell, but the socket:// is blind to that.
|
Quick status update:
Anything specific for me to test? |
Strange. In what way? |
burmistrzak
left a comment
There was a problem hiding this comment.
You basically made the exact same changes I did on my local fork! Only minor differences to be found. 😁
| EMBER_SOURCE_ROUTE_TABLE_SIZE: 200 | ||
| SL_ZIGBEE_APS_UNICAST_MESSAGE_COUNT: 128 | ||
| SL_ZIGBEE_BINDING_TABLE_SIZE: 32 | ||
| SL_ZIGBEE_BROADCAST_TABLE_SIZE: 64 |
There was a problem hiding this comment.
| SL_ZIGBEE_BROADCAST_TABLE_SIZE: 64 | |
| SL_ZIGBEE_BROADCAST_TABLE_SIZE: 32 |
Z2M default is 30, but I guess that's a matter of taste?
There was a problem hiding this comment.
I think I bumped it to allow more multicasts/group commands to fly around, since they're broadcasts. Z-Stack effectively disables this check so this tries to do the same.
There was a problem hiding this comment.
Its one complete braking change and is making all commercials devices blocking broadcast.
SL_ZIGBEE_DEFAULT_BROADCAST_TABLE_SIZE 15
The maximum number of broadcasts during a single broadcast timeout period. The minimum and default value is 15 and can only be changed on compatible Ember stacks. Be very careful when changing the broadcast table size as it affects timing of the broadcasts and the number of possible broadcasts. Additionally, this value must be universal for all devices in the network. Otherwise, a single router can overwhelm all its neighbors with more broadcasts than they can support. In general, this value should be left alone.
There was a problem hiding this comment.
I think for the coordinator device there isn't a good solution to group commands being spammed...
- If you 100% follow the spec, you really quickly run into the "network busy" error when the broadcast table gets full. This appears for some users really quickly even during normal use, especially when you have to send multiple group commands to control lights (i.e. one for color and one for brightness). Maybe it's a SiLabs bug?
- If you relax the filtering, you trade the "network busy" error for the network actually being busy due to a broadcast storm.
Both end up looking the same to an end user (devices don't work) and we had more users reporting issues with 15 than with 64.
There was a problem hiding this comment.
Z-Stack already has the limit basically disabled completely since at least 6 or 7 years: https://github.com/Koenkk/Z-Stack-firmware/blob/58dda33d834ef09132427cb41721d7d68e11a7a6/coordinator/Z-Stack_3.x.0/firmware.patch#L171-L173
I've been using a really high broadcast table size for years with SiLabs as well. Only the increased limit actually makes Zigbee groups somewhat useable in HA when changing the color by sliding it along the UI, for example.
There was a long discussion in the following HA Core issue and for most people, the increased broadcast table size was a positive improvement: home-assistant/core#86411 (comment)
There was a problem hiding this comment.
I have making one RP for Bellows zigpy/bellows#728.
Its up to puddly if hi like it or not and if hi like do the same with TI coordinators in zigpy.
The bad side is that is on the boarder to braking changes but as it was not one standard settings i think it shall being OK or it must being in (Z)HA braking changes.
My Standard ZHA config:
ezsp_config:
CONFIG_MAX_END_DEVICE_CHILDREN: 0
CONFIG_BROADCAST_TABLE_SIZE: 15
No direct children then they is only getting problems then the NCP is not replaying / having problems and building one star network if having hotting the TX power (as Decons is doing) or old Aqara sensors that can jumping.
compliant devices? All Zigbee commercial sold router devices shall have 15 in router table as long they is HA1.2 (i think its Zigbee PRO / 2007) or newer and user can overriding the system default in HA config (for ZHA) for fixing it if like broadcast storming the 15.4 and locking the mesh.
There was a problem hiding this comment.
I think it can being good going out with one recommendation for users that Zigbee Groups shall being used for On/Off/Toggle and scene switching (and Open/Close for my blinds) and not as adaptive lighting and for the last using HA groups that using unicast.
I think then its getting stable and very fast light switching and no routing problems but if having routing problems the user is knowing it with there spamming unicasts.
There was a problem hiding this comment.
No direct children then they is only getting problems then the NCP is not replaying / having problems and building one star network if having hotting the TX power (as Decons is doing) or old Aqara sensors that can jumping.
@MattWestb Yea, star topology should be avoided. Especially with high-gain adapters.
compliant devices? All Zigbee commercial sold router devices shall have 15 in router table as long they is HA1.2 (i think its Zigbee PRO / 2007) or newer and user can overriding the system default in HA config (for ZHA) for fixing it if like broadcast storming the 15.4 and locking the mesh.
The problem is that nothing prevents manufacturers from selling non-compliant devices with all sorts of weird defaults...
Certification is mandatory if you want to advertise your product as Zigbee Certified. However, a lot of popular brands (e.g. Bosch, Lumi) use the Zigbee protocol but haven't undergone certification.
There was a problem hiding this comment.
Somewhat related: Silabs published quite interesting data about their large test network.
There was a problem hiding this comment.
They have one old PDF but its good if like see how its working with real testing
https://www.silabs.com/documents/login/application-notes/an1138-zigbee-mesh-network-performance.pdf and interesting conclusions from the tests.
Also look on the AN1142 liked in the PDF for getting more of difference between Zigee/Thrad and BTMesh.
Also i have seen Espressif bringing up one thread network from factory state in under 2 minutes with 300 devices.
https://www.youtube.com/watch?v=0WXcu_r_lvQ
Edit: My link its the original an1138 that is updated in @burmistrzak post to EZSP 9.1
Edit 2:
They is describing the new broadcast and how its working with old devices (3 broadcast and out).
For Zigbee devices, a multicast message is forward- ed by a device only after a jitter of up to 64 milliseconds. Unless a repeat of a multicast message has been heard from all known neighbors, each node will transmit two repeats of the multicast message spaced by 500ms. This 500ms gap is observed in the performance data results presented in this AN.
https://docs.silabs.com/zigbee/9.1.0/zigbee-mesh-network-performance/01-introduction-and-background
@puddly Great tidbits! Thanks for sharing.
But it's enhanced USART, so it surly must be better in every aspect. 😜
Fantastic work! 🙌 |
Co-authored-by: burmistrzak <61958704+burmistrzak@users.noreply.github.com>
burmistrzak
left a comment
There was a problem hiding this comment.
With these patches applied, we should be on par with Nerivec's fork. 😄
| - id: toolchain_llvm_lto | ||
| condition: | ||
| - toolchain_llvm | ||
|
|
There was a problem hiding this comment.
| # Zigbee 4.0 | |
| - id: zigbee_r23_support | |
| - id: zigbee_dynamic_commissioning | |
Have them enabled on my end, seems to be fine.
I'm not sure this would qualify as full Z4 support, but it's a start.
There was a problem hiding this comment.
I played around with Zigbee 4.0 and...the results aren't very interesting as far as I can tell
There was a problem hiding this comment.
Anonymous DLK seems to have been explicitly disabled so the joining mode 99% of people use still leaks the network key to a passive attacker...
Wasn't that a huge selling point for Z4?
Another good reason to finally move the Zigbee stack to the host... 😅
@puddly Btw. you'll have to remove those two lines #205 (comment)
There was a problem hiding this comment.
Wasn't that a huge selling point for Z4?
I got it working by hacking the joining policy for both a router and a coordinator but this was removed in the spec itself as far as I can tell, not by SiLabs. Without both, it just didn't work. But this was on the earlier release, not 2026.6.0. I'll have to re-test it.
Another good reason to finally move the Zigbee stack to the host
Once I finish up ESP32 support for Ziggurat, the MG24 is next 😄 (SiLabs doesn't support Rust at all so I think it may be an uphill battle...)
There was a problem hiding this comment.
Once I finish up ESP32 support for Ziggurat, the MG24 is next 😄 (SiLabs doesn't support Rust at all so I think it may be an uphill battle...)
Huh, interesting!
So you're trying to use the ESP32-C6 as a RCP?
Why not OpenThread RCP, especially on the MG24?
There was a problem hiding this comment.
It's the whole ziggurat stack on the esp32 c6!
There was a problem hiding this comment.
The OpenThread RCP backend is all done, it's what I run at home 😄. The stack is small enough to fit entirely onto a C6, I'm hoping to eventually tie it into ESPHome so that it can be installed directly onto existing networked coordinators and sidestep OpenThread RCP-over-TCP latency issues.
There was a problem hiding this comment.
It's the whole ziggurat stack on the esp32 c6!
Holy smokes! 🤯
A completely open and memory-safe NCP firmware is actually a huge achievement.
Will be super interesting to see whether MG24 support is actually possible.
There was a problem hiding this comment.
The OpenThread RCP backend is all done, it's what I run at home 😄.
@puddly Would love to try this myself but we have a lot of ZGP switches and there's also no driver for Z2M yet.
AFAICT, it's a custom wire protocol over WebSocket?
The stack is small enough to fit entirely onto a C6, I'm hoping to eventually tie it into ESPHome so that it can be installed directly onto existing networked coordinators and sidestep OpenThread RCP-over-TCP latency issues.
Wow! A Rust-based ESPHome component is a first, no?
Not at the moment, unfortunately... Upgrading the firmware on the ESP32 is a bit of a hassle right now (especially for VM users) because it effectively unplugs the ESP32 and plugs in a new ESP32 with different VID and PID. We'd likely make this a one-time semi-manual upgrade to ESPHome firmware to make future upgrades more ergonomic. |
|
Follow-up review — deltas since the 2026.6.0 bump (prior review covered the earlier SSDK migration state) Re-reviewed the changes layered on since the last pass — the 2026.6.0 bump, EUSART migration, ARM64 zstd-GCC toolchain, LLVM plumbing, bootloader→SSDK migration, and the R23/R22 commits. Cross-checked config keys, enums and component structure against a local Simplicity SDK install. No correctness blockers; CI is green and the on-device testing in this thread is reassuring. Verified good
Two questions on the ZBT-2 bootloader (
Trivial: |
|
For the bot review:
|
@puddly I see. Well, at least the ESPHome aspect makes it worth the effort. Btw. regarding dogfooding the beta, is it safe to re-install the firmware via HA once it's released, or will I have to restore my network from backup? |
|
The beta will likely be byte-identical to the one you currently have running but I haven't run into a situation where I needed to erase the network, I reflash mine back and forth between major versions all the time. |
| SL_ZIGBEE_APS_UNICAST_MESSAGE_COUNT: 128 | ||
| SL_ZIGBEE_BINDING_TABLE_SIZE: 32 | ||
| SL_ZIGBEE_BROADCAST_TABLE_SIZE: 64 | ||
| SL_ZIGBEE_KEY_TABLE_SIZE: 12 |
There was a problem hiding this comment.
I'm still a bit puzzled by this parameter.
Silabs is providing conflicting information whether or not a key slot is required for each and every device joining via install code.
With the default key table size being 1 on the Z2M side, I was nevertheless able to hookup every Z3 device I have. So something isn't adding up here... 🤔
@puddly Do you happen to know more about that?
Edit: New Silabs example default is 20...
There was a problem hiding this comment.
I think this value mostly doesn't matter because both Z2M and ZHA/bellows use hashed link keys, so nothing needs to be stored per Z3 device. (TRUST_CENTER_USES_HASHED_LINK_KEY)
And I don't think the difference is whether a device is joined with an install-code or not – should just be about being a Zigbee 3 device or not (Z3 devices should always request a unique TC link key, older ones do not).
There was a problem hiding this comment.
To back the above up with the SDK source, and to note the one case where the size would matter 👇
What SL_ZIGBEE_KEY_TABLE_SIZE actually bounds (SiSDK sources)
What the table stores. SL_ZIGBEE_KEY_TABLE_SIZE sizes only the persistent application/link-key table — key type SL_ZB_SEC_MAN_KEY_TYPE_APP_LINK, "an indexed key table of size SL_ZIGBEE_KEY_TABLE_SIZE" (zigbee-security-manager-types.h); component default is 6. Joining doesn't consume it. Both the well-known-key ("quick join") and install-code/QR credentials are added to a separate transient table in RAM (SL_ZB_SEC_MAN_KEY_TYPE_TC_LINK_WITH_TIMEOUT), capacity SL_ZIGBEE_TRANSIENT_DEVICE_MGMT_MAX_CAPACITY = 64, expiring after max(SL_ZIGBEE_TRANSIENT_KEY_TIMEOUT_S = 300 s, network-open-time). So the join method only picks which transient credential is used — it never touches the persistent table. (This is why it's Z3-vs-legacy, not install-code-vs-not, as noted above.)
Why hashed link keys make the size a non-issue. With TRUST_CENTER_USES_HASHED_LINK_KEY (0x0084) the TC keeps a single root key and derives each device's TC link key on the fly by hashing it with the device EUI64 — nothing stored per device. It's documented ("a Root Key known only to the Trust Center… hashed with the IEEE Address of the destination device to create the actual Link Key", sl_zigbee_types.h; "There is only one of these keys in storage", zigbee-security-manager-types.h; have_link_key "always returns true if hashed link keys are used", zigbee-security-manager.h), and the derivation itself is in source: sli_zigbee_stack_sec_man_hmac_aes_mmo(context->eui64, …) for …DERIVED_KEY_TYPE_TC_HASHED_LINK_KEY (zigbee-security-manager-no-vault.c). SiLabs' own writeup literally calls it "a shortcut for unique link key storage on devices with constrained key table capacity" (Hashed Link Keys).
Both host stacks turn it on unconditionally on current firmware:
- bellows:
use_hashed_tclk = ezsp.ezsp_version > 4→ sets the bit inzha_security()(application.py/util.py); same for fresh form and restore-from-backup. - zigbee-herdsman: the bit is hardcoded into the
EmberInitialSecurityStatebitmask informNetwork(emberAdapter.ts), for both form and restore.
The one case where the size would matter — hashing off. If the TC used SL_ZIGBEE_ALLOW_TC_LINK_KEY_REQUEST_AND_GENERATE_NEW_KEY instead, each Z3 device gets a unique random key stored in the table; the enum comment warns "make sure that the link key table size is not zero as this can result in the newly generated key not being saved and communication breaking between the trust center and the nodes" (sl_zigbee_types.h). There the table has to hold ~one entry per Z3 device. (Legacy pre-R21 devices never run the request+verify handshake — ALLOW_HA_DEVICES_TO_STAY, default TRUE and marked "non-compliant", is what keeps them from being kicked on VERIFY_KEY_TIMEOUT, network-creator-security.c — so they establish no unique key and take no slot either way.)
What still uses the table regardless of hashing. The same table also backs stored application/SE link keys and R23 symmetric passphrases (stored as APP_LINK flagged KEY_TABLE_SYMMETRIC_PASSPHRASE = BIT 7, zigbee-security-manager.c) — worth keeping in mind here since this PR enables R23 + dynamic commissioning. Not populated by ordinary joins today, but it's why the accurate framing is "doesn't gate joins" rather than "unused."
One tradeoff: since hashed keys aren't persisted, there's no stored incoming APS frame counter per device — the article flags this as an APS-replay exposure, the flip side of "no per-device storage."
So 12 is fine and inconsequential for onboarding in the hashed config both stacks use; it'd only become a device-count ceiling if hashing were disabled.
Verified against Simplicity SDK 2025.12.3 — mechanism/doc wording is stable; I didn't re-confirm the exact default integers against 2026.6.0.
There was a problem hiding this comment.
@TheJulianJES Aha! Makes total sense now. 🙌
We might as well set it to 1 and reclaim a bit of memory?
There was a problem hiding this comment.
Bellow is hard coded to min 4 so if compiling the firmware with less it can making problems without gaining any benefits and i think 6 is better then its more standard.
If running MG2X some bites or ram is not a problem so its useless tweaking things that can braking some systems if not hawing any evidence its fixing some large problems.
ZHA / bellows is having many user running old hardware on EM35X and MG1X that is different then have very little ram and flash but they cant use this SDK so no problem.
There was a problem hiding this comment.
Lowering ?? 1 -> 4 is rising in my part of the universe.
I knowing ZHA / Bellows is using hashed tructcenter Link keys and i was one of the alfa tester then it was implemented for some years ago. Also the security setting is for my opinion not good then its not Zigbee 3 complainant then we is not forcing updating the TCLinkKey then joining devices (and denying if not doing it as per R18) and cant changing it in ZHAs config.
I wold like to see (wish full thinking from my side) that bellows is implementing what i was trying for some years ago but old chips cant handling it (to less ram) and its supporting unhashed TCLink Keys but Silabs was not supporting enough TCLK in GSDK (i think 128 was max) but is not fixed so it shall being possible. With 256 TCKL then its not problem migrating from TI and Deconz coordinators. But for users that not migrating and is ruining EZSP hashed is best then its making max devices in the mesh 64K that no other system can matching.
Puddly is the hash key stored in TCLK space ??
I think its very likely and also some temporary things like LL and HA09 (well known key) that is making the problems if setting it too low.
There was a problem hiding this comment.
Lowering ?? 1 -> 4 is rising in my part of the universe.
@MattWestb Lowering because the current value is still 12. 😉
I knowing ZHA / Bellows is using hashed tructcenter Link keys and i was one of the alfa tester then it was implemented for some years ago. Also the security setting is for my opinion not good then its not Zigbee 3 complainant then we is not forcing updating the TCLinkKey then joining devices (and denying if not doing it as per R18) and cant changing it in ZHAs config.
I wold like to see (wish full thinking from my side) that bellows is implementing what i was trying for some years ago but old chips cant handling it (to less ram) and its supporting unhashed TCLink Keys but Silabs was not supporting enough TCLK in GSDK (i think 128 was max) but is not fixed so it shall being possible. With 256 TCKL then its not problem migrating from TI and Deconz coordinators. But for users that not migrating and is ruining EZSP hashed is best then its making max devices in the mesh 64K that no other system can matching.
The most likely place we'll see individual keys be enabled is ziggurat because of the near unlimited capacity of the Zigbee-on-host architecture.
There was a problem hiding this comment.
I think we also keep around the extra unhashed key capacity for people migrating from TI coordinators. They use a different (insecure) algorithm for hashed link keys and must be migrated individually. Ziggurat supports both algorithms, in addition to manual key loading.
These sum to like 20 bytes per entry, so 200 bytes of NVRAM flash (I think they're not loaded into RAM)? I also am not sure what would happen to users who rely on the 12 slots if the table is suddenly truncated.
We have a lot of extra space (especially on MG24 coordinators) so there's IMO no real downside to keeping the table a little larger than it realistically needs to be.
There was a problem hiding this comment.
I think we also keep around the extra unhashed key capacity for people migrating from TI coordinators. They use a different (insecure) algorithm for hashed link keys and must be migrated individually. Ziggurat supports both algorithms, in addition to manual key loading.
I'm unreasonably hyped about ziggurat, ngl... 😅
These sum to like 20 bytes per entry, so 200 bytes of NVRAM flash (I think they're not loaded into RAM)? I also am not sure what would happen to users who rely on the 12 slots if the table is suddenly truncated.
@puddly Fair point.
We have a lot of extra space (especially on MG24 coordinators) so there's IMO no real downside to keeping the table a little larger than it realistically needs to be.
I guess those keys will have to be loaded in RAM at some point?
But I'm fine with leaving the 12 slots allocated.
There was a problem hiding this comment.
If not loaded i RAM its little strange then the keys is used for decoding frames in and out so i saying its 100% in RAM (one router is decrypting and encrypting every frame on the flay for every hope with the network key but the TCLK is also used then talking to devices). If the chip must read one key from flash and then decrypting is the latency to large for good operation (therefor most is using NCP and not RCP + host).
The large problem is if changing the TCLK in NVRAM its also must being changes in the flash. Sonoff was doing it one time and was getting many bricked devices and was hacking one OTA update of the NVRAM file for debricking the NCP (GBL update writing raw file to the flash).
Im very sad but i have not getting the ziggurat working (on the host side with MG21 RCP) but i like that Puddly dont drinking Java with C Python and is implanting that Silabs was trying and was not getting working OK with there Multi Protocol for some years ago. Its one great concept and was working very well with its limits and im sure we getting it working well on our hardware with puddlys help (not sure if ZGP is possible then was one of the problematic things like its still some discrepancy between Zigbee HA X and ZLL both implemented in Zigbee 3 and using the same definitions for different purposes).
Great work done @puddly and @burmistrzak !!
burmistrzak
left a comment
There was a problem hiding this comment.
Additional suggestions based on recent discussions. ✌️
| SL_ZIGBEE_APS_UNICAST_MESSAGE_COUNT: 64 | ||
| SL_ZIGBEE_BINDING_TABLE_SIZE: 32 | ||
| SL_ZIGBEE_BROADCAST_TABLE_SIZE: 64 | ||
| SL_ZIGBEE_KEY_TABLE_SIZE: 12 |
There was a problem hiding this comment.
| SL_ZIGBEE_KEY_TABLE_SIZE: 12 | |
| SL_ZIGBEE_KEY_TABLE_SIZE: 1 |
| SL_ZIGBEE_APS_UNICAST_MESSAGE_COUNT: 64 | ||
| SL_ZIGBEE_BINDING_TABLE_SIZE: 32 | ||
| SL_ZIGBEE_BROADCAST_TABLE_SIZE: 64 | ||
| SL_ZIGBEE_KEY_TABLE_SIZE: 12 |
There was a problem hiding this comment.
| SL_ZIGBEE_KEY_TABLE_SIZE: 12 | |
| SL_ZIGBEE_KEY_TABLE_SIZE: 1 |
| SL_ZIGBEE_APS_UNICAST_MESSAGE_COUNT: 128 | ||
| SL_ZIGBEE_BINDING_TABLE_SIZE: 32 | ||
| SL_ZIGBEE_BROADCAST_TABLE_SIZE: 64 | ||
| SL_ZIGBEE_KEY_TABLE_SIZE: 12 |
There was a problem hiding this comment.
| SL_ZIGBEE_KEY_TABLE_SIZE: 12 | |
| SL_ZIGBEE_KEY_TABLE_SIZE: 1 |
| XNCP_MFG_MANUF_NAME: '"Nabu Casa"' | ||
| XNCP_MFG_BOARD_NAME: '"Home Assistant Connect ZBT-2"' | ||
| XNCP_BUILD_STRING: template:"{now:%Y%m%d%H%M%S}" | ||
| XNCP_MANUAL_SOURCE_ROUTE_TABLE_SIZE: 200 |
There was a problem hiding this comment.
Shouldn't this match the size of SL_ZIGBEE_SOURCE_ROUTE_TABLE_SIZE or are the 54 additional entries a safety margin?
|
I've been running a custom build with the aforementioned suggestions without issues. Parameters changed:
|
|
I think this should be good to merge, at least as a first pass 😄. Everything works fine. The Silicon Labs OpenThread RCP firmware had one fun surprise left: Green Power packet filtering for |
| vendor: nabucasa | ||
|
|
||
| sdk_patches: | ||
| - disable_gp_rx_filter.patch |
There was a problem hiding this comment.
See my comment above (#205 (comment)). The GP filtering is currently breaking devices joins for RCP 😞.
There was a problem hiding this comment.
Woops! Was on the review page and totally missed it. 😅
Ok... Go on... 👀
What the actual …!?
THIS IS FINE. ☕️ @puddly Have you reported your findings to Silabs already? Why has vendor firmware always be so comically bad? |
burmistrzak
left a comment
There was a problem hiding this comment.
Long-term testing revealed no additional blocking issues in a large network.
So good to go from my side as well. 👌
|
I think we have one long and very good record of Silabs bugs in there Zigbee SDKs. And way we see much Silabs bugs ? |
Supersedes and builds upon #182.
This PR bumps all firmwares to the latest release of Simplicity SDK: Zigbee, Z-Wave, and Thread. We retain a bit of backwards/forwards compatibility code to allow our firmware extensions to still be used with Gecko SDK but these can be removed later.