蓝牙LMP概述

LMP 全称是Link Manager Protocol,咱们仍是要一张图,说明LMP 在哪里?网络

他是在HCI 如下,baseband 以上,实如今蓝牙控制器中。架构

 按照协议规范,咱们分几个部分来分别介绍LMP加密

  1. introduction
  2. general rules
  3. device features
  4. procedure rules

下面咱们先来看看 总体的介绍部分:spa

Introduction

LMP是用来控制和协商两个设备链接行为的协议,涉及的方面包括逻辑传输链接的创建和控制,以及对于物理链路的控制等等,它是两个设备的LMP模块以前的交流,其消息是传输在ACL-C 的逻辑链路上,对于这一点,咱们在baseband的概述中已经提过:debug

这里须要注意的一点是,LMP 是实如今控制器里面,其消息并不会通过HCI 接口传输到HOST 端,其架构以下图:3d

咱们能够看到其是 两个设备的LMP 模块以前的通讯。code

General rules

 2.1 Message Transport

 这里描述的就是三个点:orm

  1. LMP的消息的交互是传输在ACL-C 逻辑链路上的,他和ACL-U的区别是经过LLID 来区分的。
  2. ACL-C有更高的优先级,通常控制信号都会有较高的优先级
  3. LMP消息自己没有携带额外的数据错误检测的信息

2.2 Synchronization

   LMP 传输在ACL-C的逻辑链路上面,但这并不能保证传输的时间的以及对方ack的及时性。blog

 

 2.3Packet Format

 LMP 的数据包的格式有两种,一种是7bit的opcode,另一种是15bit的opcode接口

咱们发现除了opcode,在最低位还有一个TID,他是transtransaction ID,当它是0 的时候,说明这个LMP message是 master 发起的,当它是1的是时候说明是slave 发起的。

上图中是 header的最低位是0,表明是Transaction ID Initiated by master。

 

2.4Transactions

 transaction 就是一次完整的打成某种目的的传输。全部属于同一个transaction 的单次传输的transaction ID 都是想同的。

好比下面:

LMP version exchange 的Transaction ID 都是 Initiated by slave

另外LMP_setup_complete 是一个 独立PDU,它本身造成一个transaction,

 

 

上面两个OpCode LMP_setup_complete 的transaction ID 是不一样的,他们是独立的PDU

LMP response的timeout 时间是30s

 2.5ERROR HANDLING

关于出错处理,每个错误都分配了一个错误码,常见的错误以下:

  1. Unknown opcode(0x19)
  2. Invalid parameters(0x1E)
  3. PDU is not allowed(0x24)
  4. PDU not supported(0x1A)
  5. Transaction Collision / LL Procedure Collision(0x23)
  6. Different Transaction Collision(0x2A)

2.6GENERAL RESPONSE MESSAGES

 general response  在不少的procedure中,被用来对于各类流程的应答消息,若是opcode是7bit,那么应该使用前两种 PDU,若是opcode 是15bit,那么应答的PDU 应该使用后两种。

 

DEVICE FEATURES

device feature,顾名思义,这里面定义了不少的设备的特性,而且这些特定是能够用特定的LMP message 来获取的。那么这些feature 是如何传输的呢?其实就是定义了一些bit 位来表明相应的feature,当这些位被设置为1的时候,就说明支持该feature,这个咱们在程序代码实现中常常见到这样的技巧。

 这些feature 定义在两个page 上面,page1 里面使用8个字节,64bit 定义了64个feature,page2用2个字节定义了12个feature,其中包括2个reserved 位。

这里简单列举几个feature:

 

 PROCEDURE RULES

 这里包含了不少的基本流程,主要有以下的项目:

  1. Connection control

  2. Information Requests
  3. Role Switch
  4. Modes of Operation
  5. Logical Transports

 咱们下面分别看看这几个流程:

4.1Connection control 

这里每个流程都有不少的子流程,这里只简单介绍下Connection establishment和Detach的流程:

下面先看一下Connection establishment的流程图

在通过了page的流程以后,可能的行为是请求时钟的偏移量,LMP的版本,对端支持的feature请求,对端的name请求,以及可能的deteach行为。

以后若是要创建链接的话,paging的设备就会发送LMP_host_connection_req,对端若是赞成创建链接就会回复LMP_accepted 不然就是LMP_not_accepted

后续可能走得关于认证和加密的流程,最后是LMP_setup_complete,下面咱们来看一个例子:

 

 下面的创建链接的PDU:

 

 下面咱们看看detach 的流程:

咱们发现关于detach 是没有LMP response 的消息的过来的,从实际的air log 中,也的确没有detach response 回复,对端设置只会简单的ack 该 消息:

下面咱们看看 从设备的host 端 去断开对端设备的 LMP 与HCI 的message 流向:

咱们发现是 A设备再收到了对端的ACK 以后就会向host 端上传断开完成事件。

关于 验证和加密的部分,会在分析配对的文章中专门讲述。

下面咱们咱们看看

4.2Information Requests

 这一类的message 交互都是 信息请求类型的,具体的有以下几种:

  1. Timing accuracy

  2. Clock offset
  3. LMP version
  4. Supported features
  5. Name request

这几个流程也是很是的类型,咱们也是挑选其中一个来 看一下:

咱们看看lmp version 的流程:

其交互流程很简单,发起端发起一个LMP_version_req,对端回应一个LMP_version_res

涉及到的PDU的包以下:

这里咱们发现,发起这个LMP version请求的时候,还会携带本端的LMP version,Company ID 以及Sub Version Number,这个Sub Version Number 应该是公司内部的编号了,那这样一来,一个request,一个response,就完成了LMP 相关版本信息的交互。咱们看看air log 关于这交互的消息:

response 以下:

 

 这里须要提一点就是LMP 数据包的payload header 里面也是有流控相关的,可是这个流控对于LMP 是不起做用的。其应该是主要针对ACL-U的数据。

 

这里再简单名字的获取的流程,当没有创建物理link的时候,获取名字和已经创建了link的获取的名字的流程有点区别。咱们先下有link的时候 流程:

 

有link的时候,很简单,直接是在LMP 层进行LMP_name_req的交互,收到对方的应答以后,经过HCI接口上报的到host端,若是是没有link的话,那么是要先创建一个临时的link,其流程见下图:

咱们能够看到两个设备通过page 以后,会先进行LMP feature exchange以及extend feature exchange,而后上报到host 端,接下来才进行LMP_name_req 的交互,最后是detach 这个临时的link,

咱们看看 air log 中实际的交互状况:

实际状况和上面的流程也是很是的吻合,最后会把这个 临时创建起来的获取名字的link断开。

下面咱们看看role switch 相关的

4.3Role switch

 关于role switch ,由于咱们日常在debug 中会遇到,值得仔细讲一下:

role switch的执行须要符合几个条件:

  1. 设备要处于active mode
  2. 加密的流程被终止或者已经关闭
  3. 在当前的link上面,没有sco数据在传输
  4. 须要停掉当前link全部的ACL-U 数据流

role switch 从字面含义上来看,很是的简单,就是交互角色,咱们知道两个设备链接以后,一开始发起配对的那个设备在创建链接以后就是master,这样一种默认模式不能老是符合应用场景,因此常常在两个设备以后须要交互角色。

role switch 是master 和slave 均可以发起的,咱们先看一下,master 发起的角色交换的流程:

LMP 层面的交互很简单,就三个指令。下面咱们详细讲一下LMP_switch_req和LMP_slot_offset的 做用。

 

咱们看出 LMP_slot_offset 携带两个关键的信息,一个slot offset,另一个 蓝牙设备地址。这个地址是当前 slave 地址,也是role switch 以后master的地址。这个slot offset 是干吗的呢?

这个在specification中原话是“The slot offset shall be the time in microseconds between the start of a master transmission in the current piconet to the start of the next following master transmission in the piconet where the BD_ADDR device (normally the slave) is master at the time that the request is interpreted by the BD_ADDR device.

 其含义就是,当前网络的master的开始传输的时机(时钟上升沿)到交换后的网络master 进行传输的时机(时钟上升沿)的时间间隔,次时间是用ms 来描述的。

 

从这里,咱们可以觉悟出,slot offset 应该都是由当前网络的slave(role switch 以后的master) 来发送,而不论是 哪一端的设备先发起的,下面咱们看看slave 端发起的role switch的交互流程:

咱们发现,slot offset,的确是由slave端送出,以后才送出 LMP_switch_req,如今咱们看看一下LMP_switch_req这个命令:

咱们能够设想一下,蓝牙设备之间的交互是要保持时钟同步的,不然就会“失去联系”,那么咱们在进行role swtich 以后仍是要保持时钟同步才能继续通讯,那在什么样的时机进行role switch呢?

咱们先看下LMP_switch_req的参数:

 

 咱们发现其有一个参数是 switch instant ,这就是 描述 具体在哪个时间点进行TDD switch。

这个instant 应该是一个将来的时间,若是是过去的时间,那么当接受者受到这个instant的时候,并不会接受这样的参数,会回复 LMP_not_accepted PDU with the error code Instant Passed (0x28)。

当role switch 完成的时候,两个设备都要向各自的host 上报HCI_Role_Change event,以下图:

 

 Modes of Operation

 hold mode 不多遇到,这里主要讲一下 sniff mode ,

sniff mode 就是呼吸模式,主要是为了省电而应用的,好比一些蓝牙设备,好比键盘鼠标,当他们在active mode的时候,每个master to slave  slot,设备都要去监听master是否有数据发过来。而当他们不使用的时候,若是仍是一直处于active mode 的话,那么这段时间的消耗的电量就浪费了,而进入到sniff mode 可使得设备进入了相似睡眠的状态,只是按期去监听master 的封包,这样能够节省电量。

咱们先看看 进入sniff mode  的流程图:

咱们这里主要着眼于LMP层面,当host端有进入sniff mode的命令下来,那么控制器 将向对方发出LMP_sniff_req的请求,对方若是赞成,那么回复LMP_accepted。由于这是一个协商的过程,上图只显示了一次协商的过程,其实可能存在有发屡次的LMP_sniff_req的状况。如今咱们看看 LMP_sniff_req的参数:

Dsniff = Clock_Value (bits 26-1) mod Tsniff

Tsniff  是 sniff interval,就是每次起来监听的时间间隔

Tsniff 就是 相邻的两个sniff anchor point的时间间隔。

sniff attempt 是 每次起来以后 尝试去监听的次数,若是监听了sniff  attempt 次数以后发现master 没有发数据过来,那么再次进入到睡眠的状态。

sniff timeout 是 在slave 去监听master 的封包的时候,若是有封包发过来,那么就要继续监听额外的sniff timeout 个master to slave slot。

咱们这里说一下Sniff 第一个锚点的计算方法:Dsniff = Clock_Value (bits 26-1) mod Tsniff 

 这里Dsniff 和Tsniff  是参数已经给出的,那么就是根据上面的公式去反推第一个锚点的clk的值。咱们这里举一个例子来讲明:

其当前的clk值是Clock[27-0] 0x04301E02  这里的Dsniff 的值是0,

bit27  = 0,咱们先看看当前的clk是0x04301E02,那么下一个锚点必定是 大于当前值而小于(0x04301E02+800*2)

咱们先看看当前的Clock_Value (bits 26-1) mod Tsniff  = (0x04301E02>>1)mod(800) = 737

那么下一个锚点的clk = ((800-737)+ (0x04301E02>>1))*2 = 0x4301E80  

 

 那么关于LMP 的概述就先介绍到这里。

相关文章
相关标签/搜索