我其实对蓝牙并不了解,但是为了做一些蓝牙应用,好吧,不得不学,之前只看过一些代码,感觉像USB那样,但是实际上好像也一些相似性,网上知识过于零碎,最后还是通过抓包学习吧,首先这个东西我一开始也想从代码中学习到,但是发现什么都是封装成函数,哪怕有注释,也是专业术语,头疼.官方文档开篇就很硬,也没人给出过一个阅读顺序参考.
所有文档来源:https://www.bluetooth.com/specifications/specs/
蓝牙抓包文件(WCH 蓝牙抓包工具):
蓝牙抓包有多种方法,用Wireshark调用本机蓝牙抓包,最便宜,但是很多参数并不能自己分析,专业的分析工具也不贵,所以我买了一个.淘宝上太多,这里就不一一展开说.
上电后第一步,就是会不断广播.
![](https://www.taterli.com/wp-content/uploads/2023/03/image-3.png)
这个广播包会一直持续,直到被连接.
先看包(任意)格式.
![](https://www.taterli.com/wp-content/uploads/2023/03/image-4.png)
广播包时候,Access Address固定为0x8E89BED6,PDU是我们关心的数据,就是抓包的绿色位置.
![](https://www.taterli.com/wp-content/uploads/2023/03/image-5.png)
其中Header部分如下.
![](https://www.taterli.com/wp-content/uploads/2023/03/image-6.png)
其中PDU Type是0,上面已经给我们解码了,是ADV_IND.
![](https://www.taterli.com/wp-content/uploads/2023/03/image-7.png)
![](https://www.taterli.com/wp-content/uploads/2023/03/image-8.png)
RFU就是保留未来用途,Chsel目前的BLE中似乎也没用到(应该是BLE 5.X特性),然后TxAdd和RxAdd,为1则公共地址,为0则随机地址,明显这里发送我们用的就是公共地址,毫无疑问,后面的Len指的是接着的Payload有多大,所以Payload是值得分析的一部分.
![](https://www.taterli.com/wp-content/uploads/2023/03/image-9.png)
AdvA就是设备地址,谁发起广播,谁发一个地址出来,AdvData是简短的一些广播内容.至于AdvData就复杂很多了,这里要参考这个链接.
https://www.bluetooth.com/specifications/assigned-numbers/
我们分析一下,分别有两段.
- 02 01 05
- 03 19 C2 03
[02 01 05]这个Payload长度02,所以Payload总内容是01 05,其中01的Ad Type是Flags.
![](https://www.taterli.com/wp-content/uploads/2023/03/image-10.png)
Flag的内容是05,这就得找另一个文档.
![](https://www.taterli.com/wp-content/uploads/2023/03/image-11.png)
而05刚好是BIT0,BIT2,知道是LE Limited Discoverable Mode + BR/EDR Not Supported.
[03 19 C2 03],知道后面有效Payload是19 C2 03,其中19是Appearance,跳转到CCS 1.12,描述外形,就是你手机电脑能扫描到他的样子.
![](https://www.taterli.com/wp-content/uploads/2023/03/image-12.png)
但是这个从分配表文档能看到.(Assigned Numbers.pdf) - 我们这里显示是鼠标.
![](https://www.taterli.com/wp-content/uploads/2023/03/image-13.png)
确实扫描到是个鼠标.
![](https://www.taterli.com/wp-content/uploads/2023/03/image-14.png)
扫描到我们就去链接,这里用到的Adv PDU Type是CONNECT_REQ.这个包稍微复杂.
![](https://www.taterli.com/wp-content/uploads/2023/03/image-15.png)
![](https://www.taterli.com/wp-content/uploads/2023/03/image-16.png)
他的包格式如下.
![](https://www.taterli.com/wp-content/uploads/2023/03/image-18.png)
其中InitA是扫描者,比如电脑手机为了链接这个鼠标,AdvA是被链接的人,比如这里的D234567890AB,接下来的AA即通信时候用的地址(当时约定的),比如这里的5EB55383,这个会话里一直用.CRCInit是一个随机数,用来后续的计算.
后面设置传输串口大小和间隔,这里涉及一个知识,蓝牙是跳频通信,一会在这个频道一会在那个频道,大家约定一个时间窗口来通信,其他时候休息,这样可以降低能源消耗.而选择哪个频道,可以通过ChM和Hop,SCA来进行约定.Interval和Latency约定通信时候的断开机制,具体如何跳频如何断开以后再说.一般来说,我们自己做软件时候,都有对应的库去做这些.
![](https://www.taterli.com/wp-content/uploads/2023/03/image-19.png)
然后进入到真正的通信窗.
![](https://www.taterli.com/wp-content/uploads/2023/03/image-20.png)
其中NSEN和SN是为了确定包有没有传递到对面,M->S后,NESN存到S->M的SN位,然后NESN+1(因为只有1bit,你可以理解成反转),则说明确认成功,后面也有一个确认丢失的包,主机决定重发一次,因为蓝牙不是时刻接受信息的,就如之前说,一个间隔后他才会传输.所以就显得重要了.
![](https://www.taterli.com/wp-content/uploads/2023/03/image-22.png)
![](https://www.taterli.com/wp-content/uploads/2023/03/image-23.png)
可见LL_FEATURE_REQ的下一个部分是FeatureSet,具体还是按位查了.
![](https://www.taterli.com/wp-content/uploads/2023/03/image-26.png)
![](https://www.taterli.com/wp-content/uploads/2023/03/image-25.png)
剩余内容按着这个思路,也就不难继续分析了,大多数内容都在这个文件里.
![](https://www.taterli.com/wp-content/uploads/2023/03/image-27.png)
在flag那里为什么说05刚好是BIT0,BIT2?
@1111 05h = 0000 0101
16进制转换