您现在的位置是:首页 >技术交流 >经典蓝牙 蓝牙连接 - 从AIR LOG和HCI LOG分别分析蓝牙连接流程网站首页技术交流
经典蓝牙 蓝牙连接 - 从AIR LOG和HCI LOG分别分析蓝牙连接流程
1、目录
文章目录
- 1、目录
- 2、LMP连接
- 3、从HCI LOG分析蓝牙连接流程
- 1、HCI_Inquiry
- 2、 HCI_Inquiry_Cancel
- 3、HCI_Remote_Name_Request
- 4、HCI_Create_Connection
- 5、HCI_Read_Clock_Offset
- 6、HCI_Write_Link_Policy_Settings
- 7、HCI_Write_Link_Supervision_Timeout
- 8、HCI_Read_Remote_Version_Information
- 9、HCI_Read_Remote_Supported_Features_Complete
- 10、HCI_Read_Remote_Extended_Features
- 11、HCI_Authentication_Requested
- 12、HCI_Link_Key_Request_Negative_Reply
- 13、Security
- 4、其它
- 5、SDP (Service Discovery Protocol)
- 5.1 概述
- 5.2 相关
- 5.3 Protocol description 协议描述
- 查询 Hands-Free 的 Service Attribute
2、LMP连接
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eXMpvBLC-1684252954815)(D:BLUETOOTH记录企业微信截图_20210824153255.png)]
-
Baseband page procedure
BB层的操作,Paging,建立 BR/EDR Controller层的 Link Layer 连接。
-
LMP procedure 获取 remote 的 一些信息
信息包括:clock offset、LMP Version、Supported Feature、Name;
LMP Version 和 Name 通过 HCI_Remote_Name_Request获取(HCI_Remote_Host_Supported_Features_Notification)
clock offset 和 Supported Feature通过Inquiry 得到的 EIR Data获取 (支持的服务,比如 Handsfree、Headset、Audio Sink )
-
如果需要建立LMP层之上的连接,发送 PDU LMP_HOST_CONNECTION_REQ
-
经过 配对 Pairing、鉴权 authentication 、加密 encryption
-
上述三个步骤完成,则建立了LMP层之上的 连接
3、从HCI LOG分析蓝牙连接流程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a2S5ih0K-1684252954816)(D:BLUETOOTH记录企业微信截图_20210831092247.png)]
1、HCI_Inquiry
1.1 命令参数解析
HCI_Inquiry 会让 BR/EDR Controller 进入 Inquiry Mode,去扫描周围的 BR/EDR Controller。
1.1.1 LAP
用来生成 查询接入码的同步字(IAC Inquiry Access Code),当Inquiry Scan Mode的 BR/EDR Controller收到 Inquiry的 ID 分组数据包时会检查 IAC,如果是可识别的就会回复 respone。
IAC
IAC分为 专业查询接入码DIAC(0x9E8B00 ~ 0x9E8B3F)、通用查询接入码GIAC(固定值 0x9E8B33)。
IAC的组成:
Preamble 前导码
固定值1010或者0101,由同步字的LSB决定,LSB = 1 – 1010,LSB = 0 – 0101;用来直流补偿(DC Offset Compensation)
**Sync word ** 同步字
由LAP生成,用于识别和同步。
Trailer 尾码
固定值1010或者0101,由同步字的MSB决定,MSB = 0 – 1010,MSB = 1 – 0101;用于扩展直流补偿(extended DC compensation)
1.1.2 Inquiry_Length
指定查询模式的总持续时间,当这个时间到期时,查询将停止,将会收到事件 HCI_Inquiry_Complete。
Time = N * 1.28 s;Range: 1.28 to 61.44 s
1.1.3 Num_Responses
指定在停止查询之前可以接收到的响应的数量,默认是0x00,也就是 unlimited。
Range: 0x01 to 0xFF
1.2 命令的返回事件:HCI_Inquiry_Result
Baseband Controller收到回复的 respone之后通过 以下三种 event的形式给到 Host。
1.2.1 HCI_Inquiry_Result
1.2.2 HCI_Inquiry_Result_with_RSSI
1.2.3 HCI_Extended_Inquiry_Result
-
Num_Responses:此次事件包含的 respone 的数量
-
BD_ADDR[i]:响应Inquiry的设备的地址
-
Page_Scan_Repetition_Mode[i]:Page Scan 重复模式 (R0、R1、R2)
-
Class_Of_Device[i]:设备类型;决定用户看到的设备图标、可能会根据COD调整发射功率
-
Clock_Offset[i]:CLK
-
RSSI[i]:HCI_Inquiry_Result_with_RSSI 特有的参数,携带了 RSSI数据。Range: -127 to +20Units: dBm
-
Reserved[i]:预留
-
Extended_Inquiry_Response:EIR Data,一般包含 设备的蓝牙名字、设备支持的服务 (Server Class UUID)
如果 EIR Data 中没有带设备名字,可以发送命令 HCI_Remote_Name_Request去请求remote发送名字。
下图是 HCI_Extended_Inquiry_Result: EIR Data 中有名字 “vivo TWS2”、以及 remote 支持的 Service
Page Scan 重复模式 (R0、R1、R2)
Page_Scan_Repetition_Mode:不同的模式对应的 Tpage_scan 不同,Tpage_scan 是两个连续的 page scan开始时刻之间的间隔
2、 HCI_Inquiry_Cancel
查询完成,取消当前正在进行的 Inquiry,没有命令参数,返回的 event将携带表示命令执行情况的参数
3、HCI_Remote_Name_Request
3.1命令参数解析
通过与remote的连接去获取 remote的名字。
-
如果当前设备没有与remote建立ACL连接,则会建立一个临时的 Link Layer connection。然后本地LMP 先去读取远端设备的LMP特性掩码表1和掩码表2(the remote LMP features mask pages 0 and 1)。如果掩码表存在,获取特性成功,则本地的 BR/EDR Controller 会先发送 event HCI_Remote_Host_Supported_Features_Notification,然后LMP 再去获取远端的名字,也就是本地的 BR/EDR Controller 再发送 event HCI_Remote_Name_Request_Complete。此种情况下 mote_Name_Request 命令会先后返回两个 event。
-
如果当前设备已经与remote建立ACL连接,则直接去获取远端的名字,然后只返回一个事件。
3.2 回复的事件1:HCI_Remote_Host_Supported_Features_Notification
这个“远端LMP扩展特性告知”事件只会在 执行HCI_Remote_Name_Request命令与远端建立临时Link Layer 连接,然后查找到远端有LMP特性掩码表时才会生成。
3.3 回复的事件2:HCI_Remote_Name_Request_Complete
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6raRHjQV-1684252954817)(D:BLUETOOTH记录微信截图_20210822000100.png)]
3.4 HCL LOG
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ifIUKjue-1684252954817)(D:BLUETOOTH记录微信截图_20210822000520.png)]
4、HCI_Create_Connection
4.1 命令参数解析
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cZcqJOGg-1684252954817)(D:BLUETOOTH记录微信截图_20210822100247.png)]
此命令让 Link Manager 与参数指定的 BD_ADDR 创建一个ACL连接,本地的 BR/EDR Controller 的LMP将会开始 paging 事务,也就是发送携带设备接入码 (Device Access Code DAC)的ID分组数据包。
- BD_ADDR:DAC中的同步字由 此命令中的参数 BD_ADDR 生成
- Packet_Type:指定了链路管理器(LMP) 在ACL连接中使用的数据包类型
- Page_Scan_Repetition_Mode:这是在Inquiry 过程中或从HCI_Page_Scan_Repetition_Mode_Change事件中获得的 Page Scan 的最新版本
此命令会返回一个事件 HCI_Connection_Complete,携带着此次连接的结果。
- Clock_Offset:本地时钟和 BD_ADDR指定的远端设备的时钟之间的差值
- Allow_Role_Switch:指定本地设备是否接受或拒绝来自远程设备的连接设置切换角色的请求(在HCI_Accept_Connection_Request命令的Role参数中)(在本地控制器返回HCI_Connection_Complete事件之前)
4.2 命令的返回事件:HCI_Connection_Complete
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GYTKVONc-1684252954818)(D:BLUETOOTH记录微信截图_20210822105745.png)]
- Status:连接的结果,成功(0x00)或者失败(0x01 to 0xFF)
- Connection_Handle:此次建立的连接的 handle(0x01 to 0xFF),ACL-U链路或SCO链路的 handle
- BD_ADDR:此次连接的remote的蓝牙地址
- Link_Type:连接类型,0x00-SCO、0x01-ACL、All other values - Reserved for future use.
- Encryption_Enabled:加密,0x00 - Link level encryption disabled、0x01 - Link level encryption enabled、All other values - Reserved for future use.
5、HCI_Read_Clock_Offset
5.2 命令参数解析
获取系统时钟和远程设备的时钟偏移。Clock_Offset都用于确定远程设备用于 page scan 的跳频,当本地设备尝试与远程设备的连接时,Clock_Offset可用于加速 page scan 过程,例如,当本地主机发出HCI_Create_Connection或 HCI_Remote_Name_Request时。
参数Connection_Handle是ACL-U逻辑链路的Connection_Handle,也就是 HCI_Connection_Complete携带的 Connection_Handle
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WhzO8oSF-1684252954818)(D:BLUETOOTH记录微信截图_20210822110714.png)]
5.2 命令的返回事件:HCI_Read_Clock_Offset_Complete
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IT9Hqgii-1684252954819)(D:BLUETOOTH记录微信截图_20210822110846.png)]
6、HCI_Write_Link_Policy_Settings
此命令是将连接策略的设置参数写入指定的 connection_handle。如果没有主动写入,会通过发送命令 HCI_Write_Default_Link_Policy_Settings写入默认值。
连接策略指的是:是否允许role switch;是否允许进入 sniff mode、hold mode 。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8nPdwieC-1684252954819)(D:BLUETOOTH记录微信截图_20210822111000.png)]
7、HCI_Write_Link_Supervision_Timeout
此命令是Host 在 BR/EDR Controller 写入链路监控的超时值 (Link_Supervision_Timeout ) 。如果 Host 使用 Connection_Handle 发出此命令,其中 BR/EDR Controller 是外设,则 Controller 应返回错误代码命令不允许 (0x0C)。
Link_Supervision_Timeout 是 BR/EDR Controller在时间范围内没有收到 HEC 检验正确并且 LT_ADDR对应成功的分组,则会发送 LMP_DATACH 断开当前 link,也就是 link loss。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-stqjm71H-1684252954820)(D:BLUETOOTH记录微信截图_20210822111152.png)]
7.1 Handle
Handle (Connection Handle) 指定的连接对应的设备 在 ACL和SCO 的链路监控上使用相同的 Link_Supervision_Timeout。
7.2 Link_Supervision_Timeout
8、HCI_Read_Remote_Version_Information
8.1 命令参数解析
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6l7bdBi8-1684252954820)(D:BLUETOOTH记录微信截图_20210822142144.png)]
此命令将获取 Connection_Handle 参数标识的远程设备的版本信息值。 Connection_Handle 应是 ACL-U 或 LE-U 逻辑链路的 Connection_Handle。
8.2 命令的返回事件:HCI_Read_Remote_Version_Information_Complete
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FypL1TPg-1684252954821)(D:BLUETOOTH记录微信截图_20210822142240.png)]
Version (Bluetooth Core 5.2)
Remote Controller支持的LMP or Link Layer 的版本。
Company_Identifier 供应商
Remote Controller 制造商的公司标识符
Subversion 版本控制
Remote Controller 中LMP or LL 实现的修订,该值是由供应商设定。
9、HCI_Read_Remote_Supported_Features_Complete
9.1 命令参数解析
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eFPIbU3n-1684252954821)(D:BLUETOOTH记录微信截图_20210822144740.png)]
此命令请求由Connection_Handle指定的远程设备所支持的特性列表。Connection_Handle应该是ACL-U逻辑链路的Connection_Handle。HCI_Read_Remote_ Supported_Features_Complete事件将返回一个LMP特性列表
9.2 命令的返回事件:HCI_Read_Remote_Version_Information_Complete
LMP特性列表:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sZVIJvmc-1684252954822)(D:BLUETOOTH记录微信截图_20210822144923.png)]
10、HCI_Read_Remote_Extended_Features
获取Connection_Handle 指定 ACL-U连接的 the extended LMP features,由Page_Number指定具体那一页特性表。远端有 扩展的LMP特性时此命令才有效。
10.1 命令参数解析
1. Connection_Handle (只能是ACL-U)
The Connection_Handle shall be the Connection_Handle for an ACL-U logical link. 只能是ACL连接的 handle。
2. Page_Number 指定特性页( page 1、page 2)
**此处读了两次,分别读了了 page 1和 page 2: **
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OeI0XWsP-1684252954822)(D:BLUETOOTH记录微信截图_20210822150513.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fY1A9g9G-1684252954823)(D:BLUETOOTH记录微信截图_20210822151424.png)]
指定具体那一页特性表。
0x00 : 请求由HCI_Read_Remote_Supported_Features命令返回的正常LMP特性
0x01 to 0xFF :返回相应的 features 页
10.2 命令的返回事件:HCI_Read_Remote_Extended_Features_Complete
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ogjrTOWp-1684252954823)(D:BLUETOOTH记录微信截图_20210822150742.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6eZ2syeO-1684252954824)(D:BLUETOOTH记录微信截图_20210822151543.png)]
-
Status:获取特性表的 结果
-
Connection_Handle:同命令中的 connection_handle
-
Page_Number:同命令参数相同
-
Max_Page_number:最高的特性页号包含远程设备的非零位
-
Extended_LMP_Features:命令中 Page_Number 指定的 特性页中的 特性表
11、HCI_Authentication_Requested
此命令用于尝试与指定的Connection_Handle关联的远程设备进行安全验证。在验证失败时,BR/EDR Controller 或 Link Manager不应自动断开链路。如果操作是适当的,Host 负责发送 HCI_Disconnect命令终止链接。
如果启用了 Secure Simple Pairing Mode,则会生成 HCI_Link_Key_Request 事件,Host 会根据是否存在相应的 Link Key来回应此事件:
- 存在Link Key,Host 用 HCI_Link_Key_Request_Negative_Reply 命令回应时,将会启动 Secure Simple Pairing ,由 LMP完成 SSP
- 没有Link Key,Host 用 HCI_Link_Key_Request_Reply 命令回应时,则只执行认证过程,不启动 Secure Simple Pairing
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iqzkN3BO-1684252954824)(D:BLUETOOTH记录微信截图_20210823225253.png)]
11.1 命令参数解析
Connection_Handle应该是ACL连接的Connection_Handle
11.2 命令的返回事件
11.2.1 HCI_Link_Key_Request
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RsKN6Bwt-1684252954824)(D:BLUETOOTH记录微信截图_20210823225236.png)]
11.2.2 HCI_Simple_Pairing_Complete
Secure Simple Pairing 已经完成,Staus 代表 SSP 成功或者失败。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-09agPJZZ-1684252954824)(D:BLUETOOTH记录微信截图_20210823231517.png)]
11.2.3 HCI_Link_Key_Notification
此事件表示 Host与 BD_ADDR指定的设备生成了新的 Link Key ,Host将存储这个 Link Key,或者发送命令 HCI_Write_Stored_Link_Key 将 Link Key存放在 BR/EDR Controller
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gvths4Se-1684252954825)(D:BLUETOOTH记录微信截图_20210823231858.png)]
11.2.4 HCI_Authentication_Complete
此事件表示认证完成
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1MSwnXMj-1684252954825)(D:BLUETOOTH记录微信截图_20210823231922.png)]
12、HCI_Link_Key_Request_Negative_Reply
此命令用于回复 Event HCI_Link_Key_Request ,如果 Host 没有存储与 BD_ADDR指定的另一个 BR/EDR Controller 的 Link Key,则发送此命令。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Xhl5Rve0-1684252954825)(D:BLUETOOTH记录微信截图_20210823230134.png)]
13、Security
1. Authentication
1.1 鉴权的两种类型
1)legacy authentication(传统)
当至少一个设备(Controller 或 Host)不支持 secure authentication 功能并且本地设备允许使用传统身份验证时,应执行传统身份验证。
传统认证程序基于 challenge-response 质询-响应方案,有两个角色,首先发送 PDU LMP_AU_RAND 的为 “发起验证者 verifier“,另外一个是 响应验证者 claimant。
verifier 发送 LMP_AU_RAND ,其中包含一个随机数(challenge)给 claimant。 claimant 根据 challenge、claimant’s BD_ADDR 和 secret key 计算 response; response 被发送给 verifier,验证器检查 response 是否正确。 生成正确的 response 需要两个设备共享一个 secret key。
2)secure authentication
当双方设备都支持secure authentication(Controller和Host) 时默认使用此认证方式。
1.2 鉴权的三种情况
1)Claimant has link key (legacy authentication)
传统鉴权时 被鉴权者存有相应的 link key。如果 Claimant 拥有与 verifier 相关联的 link key,则计算响应并使用LMP_SRES发送给verifier。verifier 检查响应。如果响应不正确,验证者可以通过发送一个带有Error_Code Authentication Failure的LMP_DETACH PDU来结束连接(0 x05);如果正确则鉴权成功,status = OK。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iu2QLcxk-1684252954826)(D:BLUETOOTH记录企业微信截图_20210825115653.png)]
2)Responder has link key (secure authentication)
secure 鉴权时 被鉴权者存有相应的 link key。
在 secure 鉴权过程中:Central LM 和 Peripheral LM 都充当 鉴权者(Initiating LM) 和 被鉴权者(Responding LM)。 发起方 Initiating LM 是首先发送 LMP_AU_RAND PDU 的设备,员外一个设备是 被鉴权者(Responding LM)。
-
如果被鉴权者有一个与鉴权者相关联的 link key,它应以 LMP_AU_RAND PDU 响应;
-
然后发起者和响应者都应计算 respone。 Peripheral LM 首先响应包含 SRES_P 的 LMP_SRES PDU; Central LM 随后应以包含 SRES_C 的 LMP_SRES PDU 进行响应。
-
Central 应验证 Peripheral 发送的 SRES_P 是否与 Central 计算的 SRES_P 匹配。 外设应验证中心发送的 SRES_C 是否与外设计算的 SRES_C 匹配。 如果响应不正确,则任一设备都可以通过发送带有 Error_Code 身份验证失败 (0x05) 的 LMP_DETACH PDU 来结束连接。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v0OeGED0-1684252954826)(D:BLUETOOTH记录企业微信截图_20210826154527.png)]
3)Claimant has no link key (legacy authentication and secure authentication)
被鉴权者没有存有相应的 link key,收到 LMP_AU_RAND 之后回复 LMP_NOT_ACCEPTED
2. Pairing
当两个设备没有共同的 link key 时,应使用 pairing 或 Secure Simple Pairing(SSP) 创建 初始化键(Kinit).
2.1 Pairing 过程概述
先根据 LMP_IN_RAND 的随机数、PIN、响应者的 BR_ADDR 生成 Kinit;再根据 Kinit 和 随机数生成 LMP_COMB_KEY的参数,再根据此参数两个设备各自生成 link key,最后鉴权确认 两个设备生成的link key 是相同的,即 pairing 完成。
Pairing 过程从设备发送 PDU LMP_IN_RAND 开始, 此设备被称为 发起者"initiating LM" or “initiator” ,另外一个称为 响应者"responding LM" or “responder”。整个 pairing 称为一个事务transaction,其中包含多个 PDU,这些 PDU的 transaction ID都与 事务第一个PDU(LMP_IN_RAND) 保持一致。
Pairing 过程中会用到如下 PDU:
2.2 生成 Kinit
使用 Pairing 时,Kinit需要基于一个PIN、一个随机数和一个BD_ADDR创建;
1) Responder 接受pairing 并且有一个 variable PIN (易变的PIN)
如果应答器接受配对并且有一个可变的PIN,那么它将用一个LMP_ACCEPTED PDU进行应答。然后两个设备将根据响应者的BD_ADDR和IN_RAND 计算Kinit。
2)Responder 接受pairing 并且有一个 fixed PIN (固定的PIN)
如果应答器Responder 接受配对并且有一个固定的PIN,那么它将生成一个新的随机数并将其发送回LMP_IN_RAND PDU。 如果启动器有一个可变的PIN,那么它将接受LMP_IN_RAND PDU,并将响应一个LMP_ACCEPTED PDU。然后双方根据最后的IN_RAND和启动
器的BD_ADDR计算Kinit。
2.3 生成 linkkey
在 pairing 过程中创建的链接键将是组合键 combination key,两个设备都发送一个LMP_COMB_KEY PDU,然后两个设备各自根据LMP_COMB_KEY 的内容计算 link key。 LMP_COMB_KEY PDU 的内容为 LK_RAND(随机数) 按位 xord with Kinit。
2.4 生成 linkkey 之后再鉴权
当创建了新的 link key 之后,需要进行相互 鉴权,以确认在两台设备中已经创建了相同的 link key 。 相互鉴权后,如果启用加密,发起设备应暂停并立即恢复加密,以产生新的加密密钥
3. Secure Simple Pairing(SSP)
3.1 SSP触发
当Host 发送 命令HCI_Authentication_Requested 之后,如果启用了 SSP,BD/EDR Controller 就会返回 事件HCI_Link_Key_Request,当 Host没有存储对应的 Link Key 时会发送 命令HCI_Link_Key_Request_Negative_Reply,此后会启动SSP,由 LMP完成。
3.2 SSP中LMP的四个过程
SSP过程中,在 LMP 有四个阶段,用到的PDU 如下:
1. IO capabilities exchange
首先交换 IO Capabilities ,以确定要使用的正确算法,以及关联模式 association model。指定了三种算法: Numeric comparison 数值比较、Passkey entry、Out of band。
在接下来的SSP流程中,发起 IO Capabilities 请求的一方被称为 “Initiating LM” 或 “Initiator 发起者”,另一方称为 “LM” 或 “Responder 响应者”,这个代称在整个SSP流程中不会改变。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JHJ5GUfz-1684252954826)(D:BLUETOOTH记录企业微信截图_20210826104148.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xb8QmgKv-1684252954827)(D:BLUETOOTH记录企业微信截图_20210826104010.png)]
此PDU 的三个参数: IO_Capabilities IO能力、OOB_Auth_Data 是否启用带外数据(比如NFC)、Authentication_Requirements 鉴权的要求。
1)IO_Capabilities IO能力:
2)Authentication_Requirements 鉴权的要求:Non-bondable mode、 dedicated bond、general bond。
non-bondable 模式:
此模式下设备不允许 pairing,所以会以 LMP_NOT_ACCEPTED 响应接收到的 LMP_IN_RAND,并给出 不允许配对的原因。
当两台设备都支持 SSP 且本地设备处于non-bondable模式时,当Authentication_ Requirements参数请求为 dedicated
bonding or general bonding,但没有响应时 ,本地主机应响应 IO capability 请求。
Bondable mode 模式:
当蓝牙设备处于 bondable mode 可绑定模式,且本地或远程设备均不支持 SSP 时,本地设备对接收到的 LMP_IN_RAND (也就是pairing) 响应 LMP_ACCEPTED (如果有固定PIN,则响应LMP_IN_RAND)。
2. Public key exchange
-
一旦交换了 IO capabilities ,就必须在两个设备之间交换 Public key 公钥;
-
由于公钥大小比 DM1 数据包的有效载荷正文长度长,因此应使用 LMP_ENCAPSULATED_HEADER 和 LMP_ENCAPSULATED_PAYLOAD PDU 完成交换;
-
当至少一台设备不支持 Secure Connection 时,应使用 P-192 曲线 计算公钥和私钥。 当两个设备都支持 Secure Connection 时,使用 **P-256 曲线 **计算公钥和私钥 private key;
-
发起方首先发送自己的公钥 public key,响应方使用自己的公钥 public key 进行回复;
-
Public key 公钥交换完成,然后设备可以开始计算它的 Diffie Hellman Key
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GNS5s0lx-1684252954827)(D:BLUETOOTH记录企业微信截图_20210826104845.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Wkx7mHw7-1684252954828)(D:BLUETOOTH记录企业微信截图_20210826105010.png)]
3. Authentication stage 1
在认证阶段 1 中应使用 Numeric Comparison 或 Out-of-Band procedure:
- 如果一个或两个设备的OOB_Auth_Data 参数设置为Received,则应使用带外程序。
- 如果两个设备都将Authentication_Requirements 参数设置为 不需要 man-in-the middle Protection(MITM),则应使用数字
比较认证程序 ( Numeric Comparison authentication procedure)
- 如果一个或两个设备的 Authentication_Requirements 参数设置为 需要 man-in-the middle Protection(MITM),如果本地
或远程 IO Capability 设置为 KeyboardOnly 而另一个 IO 能力未设置为 NoInputNoOutput,则应使用密码输入程序 . 否则,应
使用数字比较认证程序
Numeric Comparison 数字比较:
-
响应方 应计算其 承诺值A(commitment),并应使用以下方法将该值发送给发起方 LMP_SIMPLE_PAIRING_CONFIRM PDU。
-
发起方 应发送一个 LMP_SIMPLE_PAIRING_NUMBER PDU 及其生成的随机数
-
响应方 应通过发送 LMP_ACCEPTED PDU 进行确认
-
响应方 随后应发送一个 LMP_SIMPLE_PAIRING_NUMBER 包含它自己生成的随机数
-
收到后,发起方应计算其 承诺值B(commitment),并将其与先前收到的 承诺值A LMP_SIMPLE_PAIRING_CONFIRM PDU 进行比较,如果两个值相等,则发起方应以 LMP_ACCEPTED PDU 响应
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MZLZCsZ5-1684252954828)(D:BLUETOOTH记录企业微信截图_20210826143717.png)]
4. Authentication stage 2
在这个阶段,两个设备都根据 Diffie Hellman 密钥和之前交换的信息 计算新的确认值 DH Key。
-
发起方应向响应方发送一个 LMP_DHKEY_CHECK PDU,如果发起方确定接收到的公钥有效,此PDU 应包括计算出的确认值;公钥无效时,此PDU 应包含一个不同于计算确认值的值(例如,替换一个随机生成的数字);
-
响应方接收时,如果接收到的值等于计算出的值,它应该回复一个 LMP_ACCEPTED PDU。
-
然后,响应方应向发起方发送LMP_DHKEY_CHECK PDU,包括它计算出的确认值。
-
发起方接收时,如果接收到的值等于计算出的值,它应该回复一个 LMP_ACCEPTED PDU。
-
至此,两个设备都应根据 DH Key、BD_ADDR 去计算 link key
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Mu7NRiea-1684252954828)(D:BLUETOOTH记录企业微信截图_20210826143812.png)]
3.3 SSP 四个过程的 Air log
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vG6lWr45-1684252954829)(D:BLUETOOTH记录企业微信截图_20210826150202.png)]
4. Encryption
4.1 加密概述
如果已经执行了至少一种身份验证(legacy 鉴权、secure 鉴权),则可以使用加密。 定义了两种加密机制:E0 encryption (legacy) 和 AES-CCM encryption。
如果两个设备都支持 Secure Connection( BR/EDR Controller 支持 和 Host 支持)功能,则在启用加密时应使用 AES-CCM。 如果至少一台设备不支持 Secure Connection,则启用加密时应使用 E0 encryption (legacy)。
加密过程中会用到的 PDU:
4.2 Encryption mode
4.2.1 加密的规则和前提条件
-
Central 和 Peripheral 必须就是否使用加密(LMP_ENCRYPTION_MODE_REQ 中的参数 Encryption_Mode=1)或不使用(Encryption_Mode=0)达成一致。
-
如果使用半永久密钥,则加密仅适用于点对点数据包。
-
如果使用临时链接密钥,加密将应用于点对点数据包和广播数据包。
-
如果设备收到 Encryption_Mode 值为 2 的 LMP_ENCRYPTION_MODE_REQ,则设备应将其视为
Encryption_Mode 值为 1。 -
如果两个设备都支持安全连接(控制器支持)和安全连接(主机支持)功能,则不允许将 Encryption_Mode 设置为 0。 如果设备收到 Encryption_Mode 设置为 0 的 LMP_ENCRYPTION_MODE_REQ PDU,它应使用 Error_Code 加密模式不允许 (0x25) 的 LMP_NOT_ACCEPTED PDU 进行响应
4.2.2 加密的流程
加密发起者 应暂停 ACL-U 逻辑链路上的流量。 然后发起者应发送 LMP_ENCRYPTION_MODE_REQ PDU。 如果响应设备接受加密模式的改变,那么它将完成当前数据包在 ACL 逻辑传输上的传输,然后暂停在 ACL-U 逻辑链路上的传输。 然后响应设备应发送 LMP_ACCEPTED PDU。ACL-U 逻辑链路流量只能在尝试加密或解密逻辑传输完成后恢复。
4.2.3 加密过程中会拒绝 LMP_AU_RAND,防止 ACO 不同:
在设备发送 LMP_ENCRYPTION_MODE_REQ PDU 后,它不应在加密开始前发送 LMP_AU_RAND PDU。 在设备收到 LMP_ENCRYPTION_MODE_REQ PDU 并发送 LMP_ACCEPTED PDU 后,它不应在开始加密之前发送 LMP_AU_RAND PDU。 如果发送的 LMP_AU_RAND PDU 违反这些规则,则索赔方应以 LMP_NOT_ACCEPTED PDU 和 Error_Code LMP PDU Not Allowed (0x24) 进行响应。 这可确保设备在计算加密密钥时不会有不同的 ACO。 如果不接受加密模式或加密密钥大小协商结果不一致,设备可能会再次发送 LMP_AU_RAND PDU。
4、其它
Event: HCI_Number_Of_Completed_Packets
1、控制器使用 HCI_Number_Of_Completed_Packets 事件来告诉 Host自上一个HCI_Number_Of_Completed_Packets事件发送给 Host以来,每个Connection_Handle已经完成了多少HCI数据包;
2、此事件意味着 Controller中相应的缓冲区空间已经被释放,可以用来发送新的数据包;
3、基于这个信息和HCI_Read_Buffer_Size、HCI_LE_Read_Buffer_Size命令的返回参数,主机可以确定哪个Connection_Handles下面的HCI数据包应该被发送到
Controller
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qvEIMI6w-1684252954829)(D:BLUETOOTH记录微信截图_20210822153901.png)]
- **Num_Handles:**此事件中包含的 Connection_Handles 和 Num_HCI_Data_Packets 参数对的数量
- **Connection_Handle:**连接的 handle
- **Num_Completed_Packets:**自上次返回事件以来,Connection_Handle对应的 连接传输完成的HCI数据包的数量
缩写字符表
1 | P-192 曲线P-256 曲线 | 在SSP的第二阶段,当至少一台设备不支持 Secure Connection 时,应使用 P-192 曲线 计算公钥和私钥。 当两个设备都支持 Secure Connection 时,使用 P-256 曲线计算公钥和私钥 private key |
2 | SSP | Simple Secure Pairing |
3 | non-bondable和Bondable mode | 在 IO capabilitie 的查询中会返回 Authentication_Requirements 鉴权的要求,影响配对方式 (pair/SSP)的选择。 |
5、SDP (Service Discovery Protocol)
建立 PSM=SDP 的L2CAP连接之后,SDP_Server 请求寻找 ServiceSearchPattern(服务搜索图, 也就是Profile的UUID) 指定的服务的Service Record Handle;
再根据 Service Record Handle 去请求寻找 AttributeIDList 指定的属性值。 SDP_Client 收到请求后从 Service Record中寻找对应的 hanle和属性回复。
5.1 概述
服务发现协议(SDP)为应用程序提供了一种方法来发现哪些服务是可用的,并确定那些可用服务的特征。
5.2 相关
5.2.1 Service Record
服务记录,本质就是服务属性列表,存放了不同的 Service Attribute 的列表。
5.2.2 service record handle
service record handle 是一个32位的数字,它 唯一地标识 SDP服务器 中的每一个 Service Record。
通常每个句柄仅在每 个SDP服务器中是唯一 的。 如果SDP Server S1和 SDP Server S2都包含 相同的服务记录(代表 相同的服务),用于引 用这些相同的服务记录 的服务句柄是完全独立 的。 如果提供给S2,用于引 用S1上服务的句柄将毫 无意义。
SDP服务器添加或删除 Service Record 时,SDP不会 通知客户端。
5.2.3 Service Attribute
每个服务属性描述一个服务的单个特征。
5.2.3.1 Service Attribute 的类别
服务属性的类别以 Attribute ID 区分
Service Class ID List | 标识由服务记录表示的服务类型,换句话说,就是服务是其实例的类的列表 |
Service ID | 唯一标识服务的特定实例 |
Protocol Descriptor List | 指定可用于使用服务的协议 |
Provider Name | 供应商名字:提供服务的个人或组织的文本名称 |
Icon URL | 指定指向可用于表示服务的图标图像的URL |
Service Name | 服务名称的文本字符串 |
Service Description List | 描述服务的文本字符串 |
Supported Features | 服务支持的特性 |
Language Base | 语言 (en (english)、UTF-8) |
5.2.3.2 Service Attribute 的组成
Attribute ID
1、一个16位无符号整数,用于区分 Service Record 中的每个 Service Attribute;
2、定义 service class 时还会指定服务类的每个 Attribute ID,并为与每个属性ID相关联的属性值指定含义;
3、每个属性ID被定义为仅在每个服务类中是唯一的;
Attribute Value
属性值是一个可变长度字段,其含义由与其关联的 Attribute ID 和包含该属性的 Service Record 的 Service Class 决定。
在服务发现协议中,属性值表示为数据元素。 (参见第 3 节。)通常,任何类型的数据元素都被允许作为属性值,受服务类定义中指定的约束,该定义为属性分配属性 ID 并为属性值分配含义。
5.2.4 Service Class
每个服务类被分配一个唯一的标识符 UUID。 包含在ServiceClassIDList属性的属性值中,表示为UUID
5.2.5 Service search pattern
Searching For Service (搜索服务)
Service Search Transaction 允许 客户端根据 Service Record 中包含的 Attribute Value 检索特定 Service Record 的 Service Record Handle。一旦SDP客户端有了服务记录句柄,它就可以请求获取特定属性的值。
Service search pattern 是用于定位匹配 Service Record 的 UUID List。 如果 Service search pattern 中的每个 UUID 都包含在任何服务记录的属性值中,则 Service search pattern 匹配服务记录。 UUID 不需要包含在任何特定属性中,也不需要包含在服务记录中的任何特定顺序中。 如果 Service search pattern 包含的 UUID 构成服务记录属性值中 UUID 的子集,则 Service search pattern 匹配。
Service search pattern 与服务记录不匹配的唯一情况是 Service search pattern 至少包含一个未包含在服务记录属性值中的 UUID。 另请注意,有效的 Service search pattern 必须至少包含一个 UUID。
5.2.6 Transaction (事务)
事务由 一个 Request 和 一个Response组成,
5.2.7 Transfer
SDP 中当 Respone 的数据过大,需要分多个 PDU 包传输时,可以由多个 事务组成一个 Transfer,来完成一次 Client 通过SDP对 Service 的 Service Record 查询。
5.3 Protocol description 协议描述
5.3.1 Transfer byte order 传输字节序
SDP 将以标准的网络字节顺序(大端)传输多字节字段,在低阶(低阶)字节之前传输高阶(高阶)字节。
5.3.2 Protocol Data Unit format (PDU 数据包格式)
每个SDP PDU由一个PDU Header 和 PDU Parameter 组成
5.3.2.1 Header
1、PDU ID (表示PDU的类型)
Value | 描述 |
---|---|
0x01 | SDP_ERROR_RSP |
0x02 | SDP_SERVICE_SEARCH_REQ |
0x03 | SDP_SERVICE_SEARCH_RSP |
0x04 | SDP_SERVICE_ATTR_REQ |
0x05 | SDP_SERVICE_ATTR_RSP |
0x06 | SDP_SERVICE_SEARCH_ATTR_REQ |
0x07 | SDP_SERVICE_SEARCH_ATTR_RSP |
All other values | Reserved for future use |
2、Transaction ID (事务ID)
事务ID 是用来区分不同的事务的,也就是 用来区分不同的 REQ和RSP,对应的REQ和RSP的 这个ID是相同的。
3、Parameter Length
取值范围:0x0000 – 0xFFFF
5.3.2.2 Parameter
5.3.3 部分响应和延续状态 ( Partial responses and continuation state)
一些SDP请求可能需要比单个响应PDU所能容纳的更大的响应。在这种情况下,SDP服务器将生成一个部分响应和一个延续状态参数;在客户机接收到部分响应和附带的延续状态参数之后,它可以重新发出原始请求(PDU ID和Continuation State不变,使用新的 Transaction ID),并在新请求中包含延续状态,以此向服务器指示需要原始响应的其余部分。
1、Continuation state 的格式
Continuation state 是一个可变长度字段,其第一个字节(InfoLength) 包含字段中延续信息的附加字节数 (范围 <= 0x10)。
2、Air Log
如下图:
这是一个 Service Search Transfer,其中为了传输 对应服务的 Service Record 分了三个 Transaction。
1、(Transaction ID = 0x001) SDP Client request 查询 Service Record Handle = 0x00010003 的 All Attribute;
2、(Transaction ID = 0x001) SDP Service 回复了查询请求;并且 Continuation State = 0x02002D,表示此次只是部分响应;
3、(Transaction ID = 0x002) SDP Client 收到 (2)中的回复,因为 Continuation State = 0x02002D,表示这是部分响应,所以Client 发送 PDU ID和Continuation State都不变,新的Transaction ID 的PDU
4、(Transaction ID = 0x002) SDP Service 回复了查询请求;并且 Continuation State = 0x020007,表示此次只是部分响应;
5、(Transaction ID = 0x003) SDP Client 收到 (4)中的回复,因为 Continuation State = 0x020007,表示这是部分响应,所以Client 发送 PDU ID和Continuation State都不变,新的Transaction ID 的PDU
6、(Transaction ID = 0x003) SDP Service 回复了查询请求,因为 Service Record 内容已经传输完成,所以 Continuation State = 0
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jCdVrP7v-1684252954830)(D:BLUETOOTH记录企业微信截图_20210917091720.png)]
5.3.4 Service Search Transaction
根据 Client_Req 提供的 ServiceSearchPattern 去 Service 中查找对应的 Service Record Handle
查询到 Service Class = Headset 的 Service Record 在 Service 的 Servcie Record Handle 是 0x00010003
5.3.4.1 SDP Service Search Requrst PDU (0x02)
参数解析:
1、ServiceSearchPattern:用来定位Service Record的UUID,Server会 根据 ServiceSearchPattern(UUID)去服务数据库中找对应的 service record handle,然后通过RSP发送给 client
2、MaximumServiceRecordCount:规定了RSP中 record handle 的数量最大值
5.3.4.2 SDP Service Search Respone PDU (0x03)
5.3.5 Service Attribute Transaction
根据 Client_req 提供的 Service Record Handle 和 Attribute ID,在 Service 中查找 对应的 Service Record,并且返回要求的 Attribute。
Request:请求查询 Servcie Record Handle = 0x00010003 的 Service Record 的 All Attributes
Respone:返回了 对应Service Record 的 All Attributes,图中有三个 Attribute,分别是 Servcie Class ID List、Protocol Descriptor
List、Language Base Attribute ID List
5.3.5.1 SDP Service Attribute Request PDU (0x04)
1、此次查找属性值的 Service Record handle,这个handle是通过Service Search获取到的;之后根据handle去对应的 Service record中查找 List指定范围 的 Attribute
2、RSP中包含属性值的最大字节数,超过就需要分段rsp
3、此次查询的属性:单指某一个属性或者给出属性范围值
4、分段 RSP的continue state ,不需要时为 0
5.3.5.2 SDP Service Attribute Respone (0x05)
5.3.6 Service Search Attribute Transaction
相当于完成了 服务搜索事务 + 服务属性事务,减少了 SDP transactions的数量,特别是在需要检索多个 Service Record时。 参数中给出了 Service Search Pattern (UUID)和需要从 Service Record 中查找的 Attribute的 ID List
5.3.6.1 Service Search Attribute Request PDU (0x06)
5.3.6.2 Service Search Attribute Respone PDU (0x07)
查询 Hands-Free 的 Service Attribute
请求
请求查询 服务类别为 Hands-Free 的 四个 Service Attribute (由 Attribute ID 指定)。
回复
回复了四个 Service Attribute,回复内容与代码中的一致。
代码中的 HFP Service Record
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eSAqhCOC-1684252954830)(D:BLUETOOTH记录企业微信截图_20210915111949.png)]