2. 连接断开现象分类:瞬时断开、周期性断开、永久性断开

做蓝牙Mesh调试这些年,我见过最头疼的问题不是连不上,而是连上了又莫名其妙断开。你想想看,一个智能照明系统,灯泡忽明忽暗,用户第一反应就是“这破玩意儿坏了”。其实很多时候,问题出在连接断开上。

我个人习惯,拿到一个断连问题,先不急着抓空包。先问一句:这个断开是偶发的,还是有规律的,还是一断就再也回不来了? 这三种情况,根因完全不同。

核心观点: 断连现象的分类,决定了你的排查方向。方向错了,抓三天空包也找不到原因。

连接断开现象分类框架 连接断开现象 瞬时断开 周期性断开 永久性断开 表现特征 • 毫秒级闪断 • 无规律、偶发 • 链路层瞬时异常 • 应用层几乎无感知 表现特征 • 固定时间间隔断开 • 与心跳/扫描周期相关 • 低功耗节点常见 • 可复现、可预测 表现特征 • 断开后不再重连 • 需要手动/上电恢复 • 配置丢失或硬件故障 • 最严重的断连类型

2.1 瞬时断开

瞬时断开,说白了就是“闪断”。连接刚断,下一秒又自动回来了。应用层可能都没反应过来,或者只丢了一两个包。

表现特征:

  • 断开持续时间极短,通常在几十毫秒到几百毫秒之间
  • 断开后节点会自动发起重连,不需要用户干预
  • 应用层可能表现为“卡了一下”或者“丢了一个控制指令”
  • 抓空包时,能看到 LL_TERMINATE_IND 后紧跟着 CONNECT_REQ

我记得有一次,客户反馈说他们的智能灯偶尔会“闪一下”。我一开始以为是电源问题,后来抓空包才发现,是蓝牙连接在毫秒级断开又重连了。灯控芯片的PWM刚好在断连瞬间被重置,导致灯光闪烁。

排查技巧: 瞬时断开最难抓。我建议你在抓空包时,把时间戳精度调到微秒级,同时关注 Connection Interval 附近的异常跳变。

2.2 周期性断开

周期性断开,是有规律的。每隔几秒、几分钟或者几十分钟,连接准时断一次。这种问题最好排查,因为可以复现。

表现特征:

  • 断开间隔基本固定,误差在可接受范围内
  • 断开后通常能自动重连,但重连过程可能造成业务中断
  • 常见于低功耗节点(LPN)与Friend节点的交互场景
  • 与心跳包超时、扫描窗口关闭、睡眠唤醒周期强相关

为什么会这样?我举个例子。低功耗节点为了省电,会定期休眠。如果它的 Scan Duty Cycle 设置得太低,或者 Heartbeat Period 与 Connection Supervision Timeout 不匹配,节点在休眠期间收不到心跳,就会被对端判定为超时断开。

避坑指南: 我曾经在一个项目中,把LPN的扫描间隔设成了2秒,但Supervision Timeout只设了3秒。结果节点每次休眠超过3秒就被断开。嗯,这个坑我踩过,后来把Timeout改到6秒就解决了。

周期性断开还有一个常见原因——扫描窗口与广播窗口错位。两个节点如果时钟漂移太大,或者扫描窗口太窄,就会周期性“错过”对方的广播包,导致连接断开。

参数 推荐值 说明
Connection Supervision Timeout ≥ 6 × Connection Interval 给重传留足余量
Heartbeat Period ≤ Supervision Timeout / 3 确保心跳在超时前到达
Scan Window ≥ 2 × Advertising Interval 避免扫描窗口过窄

2.3 永久性断开

永久性断开,是最严重的情况。连接断了,就再也回不来了。用户必须手动重启设备,或者重新上电,甚至需要重新配网。

表现特征:

  • 断开后节点不发起重连,或者重连失败后放弃
  • 应用层长时间收不到数据,业务完全中断
  • 通常伴随硬件复位、协议栈崩溃或配置丢失
  • 抓空包时,能看到 LL_TERMINATE_IND 后没有任何重连请求

永久性断开的根因,我总结下来主要有三类:

  1. 硬件故障: 晶振停振、射频前端损坏、电源纹波过大导致芯片复位。我在项目中遇到过一颗晶振,温度一超过60°C就停振,连接直接永久断开。
  2. 协议栈崩溃: 内存泄漏、死锁、或者未处理的异常导致协议栈挂死。这种情况在低端MCU上尤其常见。
  3. 配置丢失: 节点的配网信息(Network Key、App Key、IV Index)被意外擦除,导致节点无法加入原有网络。

重要提示: 永久性断开,我建议你第一时间检查硬件复位引脚和电源波形。很多时候,问题不在蓝牙协议栈,而在硬件层面。

2.4 三种断连的快速对比

为了方便你快速定位,我把三种断连的关键差异整理成了一张表。你拿着这张表去对现场现象,基本能判断个八九不离十。

对比维度 瞬时断开 周期性断开 永久性断开
持续时间 毫秒级 秒级到分钟级 无限期
规律性 无规律 有固定周期 一次性
自动重连 立即重连 通常能重连 不重连
常见根因 射频干扰、链路层异常 心跳超时、扫描窗口错位 硬件故障、协议栈崩溃
排查难度 高(偶发难抓) 低(可复现) 中(需检查硬件)

我的习惯: 拿到一个断连问题,先看日志里有没有 LL_TERMINATE_IND 的原因码。如果是 0x08(Supervision Timeout),大概率是周期性断开;如果是 0x13(Unsupported Remote Feature),那就要检查协议栈版本兼容性了。