第1章:GAP(通用访问规范)——蓝牙设备的“社交礼仪”

各位同学,咱们开始聊GAP。说实话,GAP这个词听起来挺唬人的——“通用访问规范”,感觉像是什么高深莫测的协议。但说白了,它就是蓝牙设备之间怎么打招呼、怎么互相发现、怎么建立连接的一套规则。

我当年刚接触BLE时,也把GAP和GATT搞混过。后来在做一个共享单车的项目时,才真正体会到:GAP管的是“设备怎么被发现”,GATT管的是“发现之后能干什么”。今天咱们先搞定GAP。

1.1 广播模式:设备在“喊话”

想象一下,你走进一个共享单车停车场。每辆车都在喊:“我在这儿!我的编号是XXX!我支持这些服务!”——这就是广播。

在BLE里,广播模式分四种。我直接给你列个表,项目里选哪种,心里要有数:

广播模式 说明 典型场景
可连接广播 设备可被发现,也能被连接 共享单车、智能锁
可扫描广播 设备可被发现,但不能连接 信标(Beacon)
不可连接广播 只发数据,不响应扫描 广播传感器数据
定向广播 只对特定设备广播 快速重连

我在做共享单车项目时,用的就是可连接广播。因为用户扫码后,手机需要连上车锁,然后开锁。如果用了不可连接广播,那手机就永远连不上车了——嗯,这个坑我见过有人踩过。

重要:广播间隔(Advertising Interval)直接影响功耗和发现速度。我建议共享单车场景用 100ms-200ms,太短费电,太长用户扫码后半天连不上。

1.2 扫描模式:手机在“监听”

广播是车在喊,扫描就是手机在听。手机有两种扫描模式:

  • 被动扫描:只听,不回复。手机只接收广播包,不发送任何请求。省电,但信息有限。
  • 主动扫描:听到广播后,手机发一个“扫描请求”,设备回复“扫描响应”。能拿到更多数据,比如设备名称、支持的Service UUID。

你想想看,用户打开App扫码时,App用的是主动扫描还是被动扫描?答案是主动扫描。因为App需要拿到车锁的完整信息,才能判断这辆车能不能用、是不是在服务区。

我记得有一次,客户反馈说“有些车扫不到”。排查了半天,发现是车锁的广播间隔设得太长(1秒一次),手机扫描窗口又短,刚好错过。后来我把广播间隔调到150ms,问题就解决了。这种细节,项目里真的要注意。

1.3 连接建立流程:从“打招呼”到“握手”

广播和扫描只是前戏。真正的连接建立,分三步走:

  1. 广播阶段:车锁持续广播,包含设备地址、是否可连接等信息。
  2. 扫描阶段:手机收到广播,发起扫描请求(如果是主动扫描),拿到更多数据。
  3. 连接请求:手机决定连接,发送CONNECT_REQ。车锁收到后,双方进入连接状态。

这里有个关键点:连接参数。手机在CONNECT_REQ里会带上连接间隔、延迟、超时时间等参数。我建议共享单车场景用以下参数:

参数 推荐值 说明
连接间隔 30ms - 50ms 太短费电,太长响应慢
从机延迟 0 共享单车不需要延迟
超时时间 4秒 - 6秒 超过这个时间没收到包,就断开

避坑指南:我曾经遇到过一个情况——连接间隔设成10ms,结果车锁功耗飙升,电池两天就耗光了。后来改成30ms,功耗降了60%。别为了追求“快”而牺牲续航。

1.4 广播数据包结构(AD Structure)

广播包不是随便塞数据的。它遵循一个固定的结构——AD Structure。每个AD Structure由三部分组成:

  • 长度(Length):1字节,表示后面AD Type + AD Data的总长度。
  • 类型(AD Type):1字节,表示数据类型。比如0x01表示Flags,0x09表示完整设备名称。
  • 数据(AD Data):长度不固定,具体内容由AD Type决定。

举个例子,一个最简单的广播包,包含Flags和完整设备名称:

// 广播数据示例
0x02  // 长度:后面2字节
0x01  // AD Type: Flags
0x06  // Flags值:LE General Discoverable + BR/EDR Not Supported

0x0A  // 长度:后面10字节
0x09  // AD Type: Complete Local Name
0x42 0x69 0x6B 0x65 0x5F 0x30 0x30 0x31  // "Bike_001" 的ASCII码

你看,就是这么简单。但实际项目中,广播包能塞的数据有限——最多31字节。所以你得精打细算。我一般会放:

  • Flags(1字节)
  • 设备名称(看长度)
  • Service UUID(2或4字节)
  • 自定义数据(比如电量、锁状态)

小技巧:如果设备名称太长,可以用缩短的设备名称(AD Type 0x08),只放前几个字符。剩下的信息通过扫描响应补全。这样广播包能省出空间放更重要的数据。

1.5 实战经验总结

好了,这一章的内容差不多就这些。最后我分享几点实战经验:

  • 广播间隔别乱设:共享单车场景,100ms-200ms是黄金区间。太短费电,太长用户连不上。
  • 主动扫描是标配:别用被动扫描,否则拿不到设备名称,用户体验差。
  • 连接参数要权衡:30ms-50ms的连接间隔,兼顾响应速度和功耗。
  • 广播包要精打细算:31字节很宝贵,优先放关键数据。

下一章,咱们聊GATT——设备连上之后,怎么读写数据。到时候我会拿共享单车的开锁流程举例,保证你一听就懂。

公众号:蓝海资料掘金营,微信deep3321