第4章 GAP层联调:广播与连接参数的那些坑

GAP层,说白了就是蓝牙设备的“社交礼仪”。设备怎么打招呼、怎么回应、怎么建立长期关系,全归它管。我做了这么多年蓝牙开发,GAP层出的问题至少占联调阶段的一半以上。今天咱们就把广播参数、扫描参数、连接参数、白名单这几个核心模块掰开揉碎聊一聊。

本章核心脉络:广播参数决定“怎么喊” → 扫描参数决定“怎么听” → 连接参数决定“怎么聊” → 白名单决定“跟谁聊”。四个环节环环相扣,任何一个参数配错,联调都可能卡好几天。

GAP层联调知识体系 GAP层联调 广播参数配置 扫描参数优化 连接参数协商 白名单与绑定 间隔/类型/通道 窗口/间隔/被动扫描 最小/最大/延迟/超时 过滤/绑定/安全 ⚠ 联调黄金法则 先调通广播 → 再调扫描 → 最后调连接参数 不要一次性把所有参数都改完,每次只改一个变量

4.1 广播参数配置:别让你的设备“喊破嗓子”

广播参数是GAP层最基础、也最容易出问题的地方。我见过太多团队联调时,两边设备明明都在广播,就是互相发现不了。为什么?广播参数没对齐。

4.1.1 广播间隔:快与慢的博弈

广播间隔决定了设备多久发一次广播包。BLE协议规定范围是20ms到10.24s,但实际用起来远没那么简单。

场景 推荐间隔 原因
快速发现(配对/配置) 20ms - 50ms 用户等不了,越快越好
正常广播(信标/设备发现) 100ms - 500ms 功耗与发现速度的平衡点
低功耗广播(电池供电) 1s - 2s 省电优先,发现慢点无所谓

我曾经踩过的坑:有一次做智能门锁项目,广播间隔设了20ms,结果手机扫描死活搜不到。查了两天才发现——广播间隔太短,信道冲突率飙升,丢包率超过60%。后来改成100ms,问题立刻解决。记住:广播间隔不是越小越好,20ms在实验室环境可能没问题,到了真实场景,干扰一多就完蛋。

4.1.2 广播类型:可连接 vs 不可连接

广播类型有四种,但联调中最常用的是两种:

  • 可连接非定向广播:最常用,任何扫描设备都能发起连接
  • 不可连接非定向广播:只发数据,不接受连接,信标设备常用

我个人的习惯是:联调初期先用可连接广播,等基本功能调通后再根据需求切换。你想想看,如果一开始就设成不可连接,两边连不上,你都不知道是广播问题还是扫描问题。

4.1.3 广播通道:37/38/39的选择

BLE有三个广播通道:37(2402MHz)、38(2426MHz)、39(2480MHz)。默认情况下三个通道都会发,但有些场景需要调整。

小技巧:如果设备在WiFi密集的环境下工作(比如办公室),建议避开WiFi的Channel 1(2412MHz)和Channel 6(2437MHz)。我一般会保留37和39,关闭38——因为38离WiFi的Channel 6太近了,干扰特别严重。

4.2 扫描参数优化:别让你的设备“听不见”

广播参数配好了,扫描端也得跟上。扫描参数的核心就两个:扫描窗口和扫描间隔。

4.2.1 扫描窗口 vs 扫描间隔

扫描窗口是每次扫描持续的时间,扫描间隔是两次扫描开始之间的时间差。这两个参数决定了扫描的“占空比”。

// 典型的扫描参数配置(以TI CC254x为例)
#define DEFAULT_SCAN_INTERVAL  0x100  // 160ms
#define DEFAULT_SCAN_WINDOW    0x050  // 50ms

// 快速扫描配置(用于配对场景)
#define FAST_SCAN_INTERVAL     0x030  // 30ms
#define FAST_SCAN_WINDOW       0x030  // 30ms  // 连续扫描模式

说白了,扫描窗口越接近扫描间隔,扫描越密集,发现设备越快,但功耗也越高。我建议联调时先用连续扫描(窗口=间隔),等确认能发现设备了,再优化参数降低功耗。

4.2.2 被动扫描 vs 主动扫描

这个坑我见过太多次了。被动扫描只收广播包,不发送扫描请求;主动扫描会发扫描请求,获取设备的扫描响应数据。

很多新手把扫描端设成被动扫描,结果收不到设备的完整广播数据,以为是设备没发。其实设备发了,只是扫描端没去“要”而已。

经验之谈:如果你的广播数据超过31字节(需要用到扫描响应),扫描端必须用主动扫描。否则,你只能收到前31字节,后面的数据全丢了。我在做ibeacon项目时就吃过这个亏,调试了两天才发现是扫描模式设错了。

4.3 连接参数协商:最容易被忽略的“隐形杀手”

连接参数协商是GAP层联调中最复杂、也最容易出问题的环节。很多团队广播和扫描都调通了,但一建立连接就断,或者连接后数据传着传着就断了。十有八九是连接参数没谈拢。

4.3.1 连接参数的核心要素

参数 范围 说明
最小连接间隔 7.5ms - 4s 连接间隔的下限,单位1.25ms
最大连接间隔 7.5ms - 4s 连接间隔的上限,单位1.25ms
从机延迟 0 - 499 从设备可以跳过多少个连接事件
监督超时 100ms - 32s 超过这个时间没收到包就断连,单位10ms

4.3.2 参数协商的“潜规则”

连接参数不是主机单方面决定的。从机可以发起参数更新请求,主机可以接受或拒绝。这个协商过程,说白了就是两边讨价还价。

我遇到过最典型的问题:从机要求最小连接间隔7.5ms,但主机芯片不支持这么快的间隔(比如某些低端芯片最小只能到15ms)。结果主机直接拒绝,连接就断了。

避坑指南:从机发起参数更新请求时,一定要查主机芯片的数据手册,确认它支持的最小/最大间隔范围。我曾经在项目中把最小间隔设成7.5ms,结果对方用的是Nordic nRF51系列,最小只能到10ms,协商失败后连接直接断开。后来改成15ms,两边都满意。

4.3.3 从机延迟的“双刃剑”

从机延迟允许从设备在连续几个连接事件中不回复数据,从而省电。但延迟设得太大,会导致数据延迟增加。

举个例子:连接间隔30ms,从机延迟设成9。那么从设备最多可以跳过9个连接事件,也就是270ms不回复。如果主机发了数据,从机要等270ms才能收到。这对实时性要求高的场景(比如音频、遥控)是致命的。

我的建议:数据量大的场景,从机延迟设成0;省电场景,从机延迟不要超过3。超过3之后,用户体验会明显变差。

4.3.4 监督超时的“安全网”

监督超时是连接的最后一道防线。如果超过这个时间没收到任何包,双方都会认为连接已断开。

公式很简单:监督超时 > 连接间隔 × (1 + 从机延迟) × 2

为什么?因为从机最多可以跳过(从机延迟)个连接事件,再加上主机可能丢包,所以至少要留两倍的余量。

// 举个例子
连接间隔 = 50ms
从机延迟 = 5
最小监督超时 = 50ms × (1 + 5) × 2 = 600ms

// 实际配置建议留30%余量
推荐监督超时 = 600ms × 1.3 = 780ms → 取整为800ms

4.4 白名单与绑定:只跟“认识的人”说话

白名单和绑定是GAP层安全机制的核心。白名单决定谁可以扫描/连接我,绑定决定谁可以跟我建立加密连接。

4.4.1 白名单的两种模式

  • 扫描白名单:只允许白名单内的设备扫描到我
  • 连接白名单:只允许白名单内的设备连接我

这两个可以独立配置。我一般建议联调初期先关掉白名单,等基本功能调通后再开启。否则两边设备互相找不到,你都不知道是白名单的问题还是广播的问题。

4.4.2 绑定流程的“握手”细节

绑定不是自动发生的。它需要主机发起绑定请求,从机确认,然后交换密钥。这个过程中,任何一个步骤超时或失败,绑定就断了。

我遇到过最坑的问题:从机在绑定过程中突然进入低功耗模式,导致绑定请求超时。后来在绑定期间强制从机不休眠,问题解决。

关键提醒:绑定过程中,不要做任何其他操作(比如同时进行数据传输)。绑定本身就需要交换多个包,如果中间插了其他数据,很容易导致绑定失败。我习惯在绑定前先暂停所有业务数据,绑定完成后再恢复。

4.4.3 白名单与绑定的配合

绑定成功后,设备地址会自动加入白名单。但有个细节:绑定用的是“长期密钥”,白名单用的是“设备地址”。如果设备地址变了(比如用了随机地址),白名单就失效了。

所以,如果你用了随机地址,绑定后一定要把当前的随机地址加入白名单,而不是用静态地址。这个坑我踩过两次,第一次排查了整整一天。

4.5 联调实战:一个完整的GAP层调试流程

说了这么多理论,咱们来点实际的。下面是我个人总结的GAP层联调标准流程:

  1. 第一步:确认广播。用手机APP(比如nRF Connect)扫描,看能不能发现设备。如果发现不了,检查广播间隔、通道、发射功率。
  2. 第二步:确认扫描。用设备扫描手机(手机模拟广播),看设备能不能发现手机。如果发现不了,检查扫描窗口和扫描模式。
  3. 第三步:建立连接。两边都能互相发现了,尝试建立连接。如果连不上,检查连接参数是否在双方支持的范围内。
  4. 第四步:测试稳定性。连接建立后,持续传输数据30分钟以上,看会不会断连。如果断连,检查监督超时和从机延迟。
  5. 第五步:开启安全机制。最后再开启白名单和绑定,确认安全功能正常。

最后提醒一句:GAP层联调最忌讳“一把抓”。每次只改一个参数,改完测试,确认没问题再改下一个。我见过太多人一次性改了广播间隔、扫描窗口、连接参数三个地方,结果出了问题根本不知道是哪个参数导致的。记住:控制变量法是联调的第一原则。