GL-S200 Thread Devices Not Respod

Hi Bruce,

in attach the latest log, the issue appear between the 9:00 AM and the 10:00 AM of November 18.
The GL-S200 is connected to its own power supply through an UPS. The UPS is a 220VAC model and it have a new battery.
I also tried to power the GL-S200 using a different external power supply 220VAC to USB-C that unfortunately not solve the problem.
The issue appear only on the Thread network. The GL-S200 Wi-Fi and LAN connection work properly.

Thank you

logread.tar (187 KB)

Hello,

According to the R&D reply, please download and unzip this script in PC, upload it to the S200 path /root/, and execute it to check:

chmod +x /root/ot-rcp-test && ./root/ot-rcp-test

If there is an error in the inspection process, check /root/fatal_error_dmesg and /root/fatal_error_logread, and copy them to here:

cat /root/fatal_error_dmesg
cat /root/fatal_error_logread

Thanks!

Hi,

there isn’t a script in attach.
Please could you give me the download url?

Thank you

Kind regards

Sorry, the uploaded file is missing, please check the attachment:

ot-rcp-test.zip (596 Bytes)

Thank you for your quick response.

In attach the error logs.

Thank you

error_logs.zip (25.0 KB)

Hello,

Thanks for the log files!

After R&D analysis logs, we suspect that there may be a problem with the hardware of the S200.

Please contact our CS team cs@gl-inet.com via email to return or replace a new one. In the email, please cite this thread, leave the purchase order and a photo of device sticker.
And if possible, please let CS guys know the S200 to be returned to Shenzhen China, since we need to analyze this issue.

After sending the email, a unique ticket ID will be generated. Please inform me of this ID.
Thanks!

Hi,

I found the root cause of the problem. Here is the complete analysis and the proposed fixes.

Before anything else: the device is not defective, and 2.4GHz interference is not the cause. I want to save others from unnecessarily shipping their GL-S200 back.

I've been experiencing the same intermittent Thread device disconnections described in this thread. After gaining SSH access to the device and doing a thorough investigation, I was able to reproduce and identify the exact root cause.

What is actually happening

Every few weeks to months, gl-otbr-mgmt triggers a hardware reset of the Thread RCP (the Silicon Labs EFR32 radio chip) via GPIO. This tears down the entire Thread network. Most devices reconnect automatically within seconds, but sleepy end devices, which poll infrequently, fail to check in within the child supervision timeout (190 seconds) and are permanently declared offline by the OTBR. That is the disconnection event users are seeing.

This is not RF interference. This is a software-initiated hardware reset.

Evidence

When the disconnection occurred, logread showed this exact sequence:

Fri Apr  3 08:35:27 2026  user.notice  gl-ot-rcp-reset: RCP hardware reset ...
Fri Apr  3 08:35:28 2026  user.crit    otbr-agent[4562]: 49d.17:04:06.056 [C] P-SpinelDrive-: Software reset co-processor successfully
Fri Apr  3 08:35:28 2026  user.crit    otbr-agent[4562]: 49d.17:04:06.068 [C] P-RadioSpinel-: RCP => [C] Platform------: Reset info: 0x3 (EXT)
Fri Apr  3 08:35:28 2026  user.crit    otbr-agent[4562]: 49d.17:04:06.068 [C] P-RadioSpinel-: RCP => [C] Platform------: Extended Reset info: 0x301 (PIN)

The 49d.17:04:06 timestamp proves the RCP had been running continuously for 49 days before this reset. This is not a crash. Reset type 0x301 (PIN) is an externally-asserted hardware reset, the reset pin on the EFR32 was deliberately pulled low by the host CPU.

Five minutes later, a sleepy end device missed the supervision window and was declared offline:

Fri Apr  3 08:40:28 2026  daemon.info  gl-otbr-mgmt[2674]: child device offline: C6764DEEB2566306 0xc001

Root cause: the keep_refresh_enabled watchdog

The reset is triggered by a watchdog mechanism inside gl-otbr-mgmt, controlled by:

# uci show otbr | grep keep
otbr.otbr.keep_refresh_enabled='1'

When the watchdog fires (OT_EVENT_OTBR_WATCHDOG, ot_watchdog_tick), gl-otbr-mgmt calls /usr/bin/gl-ot-rcp-reset, which asserts GPIO pin 2 (configured as gpio_rst):

# /usr/bin/gl-ot-rcp-reset (relevant portion)
config_get gpio_rst otbr gpio_rst
echo 0 > /sys/class/gpio/gpio$gpio_rst/value
sleep 0.1
echo 1 > /sys/class/gpio/gpio$gpio_rst/value

This is confirmed by inspecting the otbr-agent binary, which embeds a direct reference to gl-ot-rcp-reset in its watchdog code path.

Why channel-switching seemed to help (previous posts in this thread)

Switching channels caused devices to temporarily lose and re-find the network, which appeared to "fix" things, but it was a coincidence. The underlying reset cycle continued unchanged.

Why the RF scan showed "interference"

Thread channel 26 on this device reads -80 dBm (essentially the noise floor, clean). Channel 11 showed -65 dBm, but that is an unrelated nearby WiFi network on 2.4 GHz channel 1, which does not affect Thread channel 26. The R&D team's interference diagnosis was based on misleading data.

System info

GL-S200, OpenWrt 21.02.2 (build Feb 16 2022)
RCP: SL-OPENTHREAD/2.5.1.0_GitHub-1fceb225b; EFR32; Aug 29 2024
Thread channel: 26 (noise floor: -80 dBm — clean)
WiFi channel:   6 (2.437 GHz — unrelated)

ot-ctl childsupervision interval     → 129 s
ot-ctl childsupervision checktimeout → 190 s

Proposed fixes for the GL-iNet development team

1. Temporarily extend child supervision timeout during RCP reset recovery
When gl-otbr-mgmt intentionally triggers an RCP reset, it knows the network is rebuilding. It should temporarily raise childsupervision checktimeout to 600–900 seconds for the reconnection window, then restore the original value. This gives sleepy end devices enough time to poll in and rejoin without being declared permanently offline.

2. Log the watchdog trigger condition
Currently there is no log entry explaining why the watchdog fired, only that it did. A message such as "RCP unresponsive for N seconds" or "spinel timeout after N retries" would make the event interpretable and help users and integrators distinguish a necessary recovery from a spurious trigger.

3. Attempt a software reset before the hardware PIN reset
A spinel CMD_RESET (software reset) is significantly less disruptive than a GPIO pin reset: it does not require the Thread network to fully rebuild and allows faster device rejoin. The watchdog should try a software reset first and only escalate to the hardware PIN reset if the software reset fails.

4. Emit a ubus event before and after the reset
Matter controllers (such as matterjs-server or Python Matter Server) maintain persistent session state for each Thread node. An abrupt RCP reset without notification forces the controller to rediscover all nodes, which is slow and can fail silently. A ubus event like otbr.rcp_reset { "reason": "watchdog", "phase": "before" | "after" } would allow the Matter controller to pause and resume cleanly.

I hope this analysis is useful to the team and to other users hitting this issue. Happy to provide additional logs or test any patches.

Thank you so much for your highly professional and detailed analysis!

You also found the watchdog program logic :gl_emoji_nice:

I have submitted this issue to R&D team; they will schedule it for a future release and fix the issue.

Many thanks!

Hello,

Apologies for reviving an old thread, but I was wondering if there was any news on when this potential update could happen? I am having similar issues with my S200 where I see frequent disconnects with my Ikea thread devices and my logs look very similar to what have been shared in here. So I am hoping that there is an update on the way which could help resolve this.

Hello,

Sincerely apologize for the slight delay in the S200 update schedule.
I have consulted with the relevant team, and we have decided to expedite the firmware update for the S200.
Confirmed that a beta version of the firmware will be released to address this issue.

Update:

The R&D team just released a beta build! We’ve reviewed @lumiere’s suggestions and tweaked the code accordingly.
Huge shoutout to @lumiere for the input!

Click here to download. Feel free to install the beta firmware and take it for a spin.

Hi everyone,

Thanks a lot for the update and for implementing the suggested changes.

I'll install the beta firmware, test it thoroughly, and share my feedback as soon as I've had a chance to evaluate it.

Hi,

Thanks for the beta firmware 4.7.0-0502 you shipped on 2026-07-24 as a proposed fix for the RCP reset / stale EID cache issue I described in my previous post. I installed it the same day and have been monitoring for ~70 hours.
Reporting back with results.

Summary: the disconnection bug still occurs, and reset frequency has increased significantly.


What the beta changed vs. what it did not

The beta updated only the OTBR host side (ot-br-posix/2024-06-03, newer than the previous build). The Silicon Labs EFR32 RCP firmware is unchanged:

# ot-ctl version
ot-br-posix/2024-06-03; POSIX; Feb 16 2022 20:29:10

# ot-ctl rcp version
SL-OPENTHREAD/2.5.1.0_GitHub-1fceb225b-v2024.242.09761-b994a40; EFR32; Aug 29 2024

RCP resets observed since installing the beta (~70 hours)

  ┌─────┬───────────────────┬─────────────────────┬────────────────────────┐
  │  #  │ Timestamp (local) │ RCP uptime at reset │  Delta from previous   │
  ├─────┼───────────────────┼─────────────────────┼────────────────────────┤
  │ 1   │ Jul 24 16:55:18   │ 00:01:25            │ (first boot, expected) │
  ├─────┼───────────────────┼─────────────────────┼────────────────────────┤
  │ 2   │ Jul 24 17:24:57   │ 00:31:04            │ +29 min                │
  ├─────┼───────────────────┼─────────────────────┼────────────────────────┤
  │ 3   │ Jul 24 17:29:08   │ 00:35:15            │ +4 min                 │
  ├─────┼───────────────────┼─────────────────────┼────────────────────────┤
  │ 4   │ Jul 24 17:30:54   │ 00:37:01            │ +2 min                 │
  ├─────┼───────────────────┼─────────────────────┼────────────────────────┤
  │ 5   │ Jul 26 01:06:45   │ 1d.08:12:52         │ +32 h                  │
  ├─────┼───────────────────┼─────────────────────┼────────────────────────┤
  │ 6   │ Jul 26 14:58:33   │ 1d.22:04:40         │ +14 h                  │
  ├─────┼───────────────────┼─────────────────────┼────────────────────────┤
  │ 7   │ Jul 27 03:23:12   │ 2d.10:29:18         │ +12 h                  │
  ├─────┼───────────────────┼─────────────────────┼────────────────────────┤
  │ 8   │ Jul 27 14:08:02   │ 2d.21:14:07         │ +11 h                  │
  └─────┴───────────────────┴─────────────────────┴────────────────────────┘

Seven spontaneous resets in ~70 hours, averaging one every ~10 hours. Before the beta, the same unit had ~49 days between resets. The beta appears to have made the situation worse, not better.

All reset log entries show the same pattern:

[W] P-RadioSpinel-: RCP failure detected
[C] P-RadioSpinel-: RCP => [C] Platform------: Reset info: 0x3 (EXT)
[C] P-RadioSpinel-: RCP => [C] Platform------: Extended Reset info: 0x301 (PIN)

Each reset produces the exact issue I described previously: the EID cache in the OTBR remains stale, and Thread devices become unreachable via IPv6 until either they spontaneously re-attach or the affected router is power-cycled.

Which of the two known reset paths is firing

  • Path 1 - gl-otbr-mgmt periodic watchdog reset (keep_refresh_enabled): NOT this. I still have otbr.otbr.keep_refresh_enabled='0' set via UCI (workaround from my previous post). Confirmed still effective on the beta.
  • Path 2 - otbr-agent on radio tx timeout: this is what's firing. otbr-agent calls /usr/bin/gl-ot-rcp-reset directly on radio unresponsiveness, independent of keep_refresh_enabled. All 8 resets are consistent with this path (PIN reset with RCP failure detected warning immediately before).

Configuration verification (current state)

To rule out anything unusual on my side, here is the exact current configuration:

# uci show otbr (relevant keys)
otbr.otbr.channel='26'
otbr.otbr.keep_refresh_enabled='0'      ← workaround from previous post, still active
otbr.otbr.txpower='10'                  ← reduced from 20 dBm as further mitigation
otbr.channel_monitor.disabled='1'
# crontab -l
(empty — no user scripts, no watchdog, nothing custom firing on the device)

# ot-ctl childsupervision interval
129
# ot-ctl childsupervision checktimeout
190

The 8 resets happened with this exact configuration in place. txpower='10' (about 25% of default power) does not prevent the failure, so this is clearly not RF congestion.

New diagnostic finding (may inform a lighter fix)

When the EID cache is stale post-reset, power-cycling only the affected Thread router is sufficient to restore forwarding, a full GL-S200 reboot is not required. After reset #8, one of the Thread routers in my mesh became unreachable via IPv6 from the host running my Matter controller. Power-cycling that single device restored its EID entry within ~30 s and the Matter controller re-established its CASE session without any GL-S200 intervention.

Diagnostic detail from ot-ctl eidcache before and after: the entry for that router was still present in the cache with canEvict=1, but IPv6 forwarding through it was not working. The re-attach cleared the problem.

This suggests a lighter fix on your side is possible: on RCP reset recovery, otbr-agent could proactively re-resolve address mappings for known routers instead of leaving cache entries in a marked-evictable state that continues to be selected for forwarding.


Proposed fixes for the GL-iNet development team

1. Update the EFR32 RCP firmware. This is the highest-impact item. The current RCP firmware on my unit is SL-OPENTHREAD/2.5.1.0_v2024.242.09761 from August 29 2024, 11 months old. Silicon Labs has published multiple releases since then that address radio state machine bugs. The failure mode (radio tx timeout on an otherwise idle RCP with TxErrCca=0) points squarely at the RCP layer, which the beta did not touch. Even bringing OpenThread to a current release would likely close many of these events.

2. Attempt a software reset before escalating to hardware PIN reset. When otbr-agent detects RCP failure detected, it goes straight to GPIO pin 2 (full hardware reset). A spinel CMD_RESET (software reset) is significantly less disruptive, the Thread network state on the RCP side is discarded but the SPI/UART interface stays up, allowing much faster re-sync. Try software reset first; escalate to PIN reset only if the RCP is unresponsive to spinel commands.

3. Proactively refresh EID cache entries after RCP reset recovery. After any RCP reset, the OTBR should not leave cache entries in canEvict=1 state for routers that are still present in the neighbor table. Iterate over known SRP-registered hosts and re-run address resolution, so that the first packet after recovery doesn't hit a stale cache entry that appears valid but forwards to a broken next hop.

4. Temporarily extend child supervision timeout during the recovery window. When gl-otbr-mgmt or otbr-agent initiates an RCP reset, it knows the mesh is rebuilding. It should raise childsupervision checktimeout from the current 190 s to 600–900 s for the duration of the reconnection window, then restore it. This gives sleepy end devices enough time to poll in and rejoin without being permanently declared offline. (Repeated from my previous post, still relevant.)

5. Log the trigger condition and emit a ubus event on RCP reset. Currently there is no log entry explaining why otbr-agent decided to reset, only that it happened. A message such as "spinel timeout after N retries on op X" would make each event interpretable. Additionally, a ubus event like otbr.rcp_reset { "reason": "...", "phase": "before" | "after" } would allow Matter controllers and other consumers to pause and resume cleanly, instead of silently losing session state.

6. Rate-limit or backpressure repeated resets. In my log, resets #2, #3, #4 fired within 6 minutes of each other. If the RCP is being reset three times in that window, something is fundamentally wrong and further resets are unlikely to help. otbr-agent should throttle the reset rate (e.g. exponential backoff) and produce a diagnostic dump instead of an endless reset loop.


Happy to run additional diagnostics or test another beta. Full logread excerpts, ot-ctl dumps, and any other data on request.

Thanks

Hello,

Sorry about that! It looks like the previous build didn't quite nail it.

Please test this updated build. Our R&D team has been stress-testing it for a few days without any issues, but our lab setup is nowhere near as complex as your real-world environment. We’d really appreciate it if you could help us verify if this fixes things on your end.

https://fw.gl-inet.com/firmware/s200/testing/openwrt-s200-4.7.0-0503-0803-1785737793.tar

Quick follow-up to confirm the fix:

I’ve been running firmware 4.7.0-0503 (with the updated EFR32 RCP 2.6.2.0) for 40 days now, across four reboots, and I can confirm that the issue is completely resolved, zero RCP resets, zero radio tx timeout events, zero device disconnections. The Thread mesh has been rock solid. I’ve also removed the UCI safety-net workarounds I had in place and the GL-S200 is now running on pure vendor defaults with no issues.

Thanks to the team for pushing the RCP firmware update through.

Hello, thanks a lot for testing this out and for your ongoing support!

Hi @bruce,

Now that the latest firmware has resolved the issues, are you planning to release it as a stable version on the firmware download page of your website?

Thank you.

Hello,

As the testing resources are a bit tight for this setup, the stable version may not be released for the time being.

The R&D team will first upload the beta firmware for customers to download and work. This firmware will be uploaded in the near future.

Hi Bruce,

The version currently available on your website’s beta channel is not the latest one you shared above. The version on your website still contains the bugs I previously reported.

Version currently available on your website (still contains the reported bugs):

https://fw.gl-inet.com/firmware/s200/testing/openwrt-s200-4.7.0-0502-0722-1784709441.tar

Working version:

https://fw.gl-inet.com/firmware/s200/testing/openwrt-s200-4.7.0-0503-0803-1785737793.tar

Could you please update the beta firmware on your website to the working version you shared with me?

https://fw.gl-inet.com/firmware/s200/testing/openwrt-s200-4.7.0-0503-0803-1785737793.tar

Thank you for your help.

Best

Hello,
I'm just jumping in to thank you both for keeping on top of this. I bought the S200 earlier this year and was beginning to fear that it was going to get forgotten about and remain out of date until it became EOL'ed. I will install the new firmware and get the border router added back into my Thread network.