本专栏文章我们会以连载的方式持续更新,本专栏计划更新内容如下:
第一篇:蓝牙综合介绍 ,主要介绍蓝牙的一些概念,产生背景,发展轨迹,市面蓝牙介绍,以及蓝牙开发板介绍。
第二篇:Transport层介绍,主要介绍蓝牙协议栈跟蓝牙芯片之前的硬件传输协议,比如基于UART的H4,H5,BCSP,基于USB的H2等
第三篇:传统蓝牙controller介绍,主要介绍传统蓝牙芯片的介绍,包括射频层(RF),基带层(baseband),链路管理层(LMP)等
第四篇:传统蓝牙host介绍,主要介绍传统蓝牙的协议栈,比如HCI,L2CAP,SDP,RFCOMM,HFP,SPP,HID,AVDTP,AVCTP,A2DP,AVRCP,OBEX,PBAP,MAP等等一系列的协议吧。
第五篇:低功耗蓝牙controller介绍,主要介绍低功耗蓝牙芯片,包括物理层(PHY),链路层(LL)
第六篇:低功耗蓝牙host介绍,低功耗蓝牙协议栈的介绍,包括HCI,L2CAP,ATT,GATT,SM等
第七篇:蓝牙芯片介绍,主要介绍一些蓝牙芯片的初始化流程,基于HCI vendor command的扩展
第八篇:附录,主要介绍以上常用名词的介绍以及一些特殊流程的介绍等。
另外,开发板如下所示,对于想学习蓝牙协议栈的最好人手一套。以便更好的学习蓝牙协议栈,相信我,学完这一套视频你将拥有修改任何协议栈的能力(比如Linux下的bluez,Android下的bluedroid)。
------------------------------------------------------------------------------------------------------------------------------------------
CSDN学院链接(进入选择你想要学习的课程):
蓝牙交流扣扣群:970324688
Github代码:
入手开发板:
蓝牙学习目录:
------------------------------------------------------------------------------------------------------------------------------------------
L2CAP的命令叫做signaling command(叫做C-frame),所有的命令都是通过signaling channel来发送,传统蓝牙的CID是固定的0x0001,低功耗的CID是固定的0x0005,格式如下:
其中Length跟CID不需要额外说明,在signaling command的information payload的格式为:
参数:
Code:标示Signaling command id,如下:
Identifier (1 octet):用于标示command的发送序列,response必须跟request相同
Length (2 octets):用于标示后续的data长度
Data (0 or more octets):针对不同的signaling command,后续的data是不同的,具体command具体分析。下面我们来看下具体的signaling command,command的格式只提出红框部分。
也就是这个部分
此部分针对于每个SIGNALING来做说明
此命令是在command不合法以及对方的response不合法的情况下发送给对方Information的格式如下:
Reason (2 octets):告知remote端为什么发送拒绝封包,reason有以下值:
Data (0 or more octets):此部分长度并不是固定的,要看具体拒绝reason
如果拒绝reason是0x0000,那么是remote端发送的command id是错误的,data部分则是0byte,什么都不需要填写
如果拒绝reason是0x0001,那么就是MTU有问题,data就是2byte的MTU
如果拒绝reason是0x0002,那么会有4byte的data,分别来表示local (first) and remote(second) channel endpoints
总结图示如下:
该命令是发起连接请求,格式如下:
其中Code,Identifier,Length,PSM不做说明了,前面已经说明了
Source CID:连接的放用source ID,也就是本地的CID.
下面我们来看一个我抓取的BTsnoop封包.
该命令是响应发起连接请求,格式如下:
我们只说Destination CID,Source CID,Result,Status
Destination CID:可以认为是发送response的本地CID
Source CID:发送L2CAP_CONNECTION_REQ的CID
Result:连接的结果,如图:
Status (2 octets):只有当Result = 0x0001 connection pending的时候才会用到,值如下:
下面我们来看一个我抓取的BTsnoop封包
该命令是发起配置请求,格式如下:
Destination CID - DCID (2 octets):此部分连接发起的是source cid,连接response是destination id,也就是连接接收的CID,所以要根据谁发起的连接来填写
Flags (2 octets):只有一个C(continue)被定义,表明是否后续是否有数据
Configuration Options:配置参数,下面我们来详细说明下配置参数,内容比较多
配置选项的格式如下:
Type (1 octet):配置的类型,有以下几个:
0x01:MAXIMUM TRANSMISSION UNIT (MTU)
0x02:FLUSH TIMEOUT OPTION
0x03:QUALITY OF SERVICE (QOS) OPTION
0x04:RETRANSMISSION AND FLOW CONTROL OPTION
0x05:FRAME CHECK SEQUENCE (FCS) OPTION
0x06:EXTENDED FLOW SPECIFICATION OPTION
0x07:EXTENDED WINDOW SIZE OPTION
Length:option data的长度
Option data:根据不同的type,里面的数据不同
我们来一一分析每个配置选项
0x01:MAXIMUM TRANSMISSION UNIT (MTU):是上层协议的最大封包数
0x02:FLUSH TIMEOUT OPTION:
0x03:QUALITY OF SERVICE (QOS) OPTION
0x04:RETRANSMISSION AND FLOW CONTROL OPTION
0x05:FRAME CHECK SEQUENCE (FCS) OPTION
0x06:EXTENDED FLOW SPECIFICATION OPTION
0x07:EXTENDED WINDOW SIZE OPTION
下面我们举一个例子看看发送MTU的configure request的btsnoop
L2CAP configuration的response,格式如下:
Result:configuration req的结果,有以下几个值
Config:就是我们上面所说的配置参数
我们来看一个btsnoop
L2CAP channel断开请求,格式如下:
其中参数我们都见过了,直接来看一个BTSnoop。
断开请求的reponse,格式如下:
参数我们已经明了,来看下一个BTSnoop.
用来请求一个L2CAP的ECHO response,格式如下:
回复一个echo rrequest,格式如下:
用来请求一些信息,格式如下:
InfoType:信息类型,有以下值:
我们来看几个不同的info的BTSNOOP.
Information请求的response,格式如下:
其中InfoType就是Infomation request请求的type
Result如下:
Data:根据不同的Info type有不同长度的值,如下:
其中MTU就是普通的2个byte,没有啥好说的
EXTENDED FEATURE MASK值如下:
FIXED CHANNELS SUPPORTED定义如下:
我们来抓几个btsnoop看看.