链路管理器协议(LMP)用于控制和协商两个设备之间蓝牙连接操作的所有方面。这包括逻辑传输和逻辑链路的设置和控制,以及物理链路的控制。
链路管理器协议用于在两个设备上的链路管理器(LM)之间进行通信。所有LMP消息应仅适用于发送和接收设备之间的物理链路和相关逻辑链路以及逻辑传输。
该协议由一系列消息组成,这些消息应通过两个设备之间的ACL-C或ASB-C逻辑链路传输。LMP消息应由LM解释和操作,不得直接传播到更高的协议层。
LMP消息应通过ACL-C逻辑链路进行交换,该逻辑链路在默认ACL逻辑传输上或在ASB逻辑传输上承载的ASB-C逻辑链路上。除非另有说明,否则LMP消息应在默认ACL逻辑传输上进行。
LMP消息在ACL-C和ASB-C逻辑链路上承载,这些链路不保证传送或确认数据包的时间。举个例子,LM在发送某个请求时,可能不会等到对方回应该请求之后,在开始下一条请求,所以有时可能会连续推送几个消息。在同步两个设备中的状态更改时,LMP过程会考虑这一点。
每个PDU分配一个7或15位操作码,用于唯一标识不同类型的PDU 。操作码的前7位和事务ID(transaction ID,TID)位于有效负载主体的第一个字节中。如果操作码的初始7位具有特殊转义值124-127之一,则操作码的附加字节位于有效载荷的第二字节中,并且该组合唯一地标识PDU。
如果PDU包含一个或多个参数,则将这些参数放置在操作码之后立即开始的有效载荷中,即如果PDU具有7位操作码则在字节2处,或者如果PDU具有15位操作码则在字节3处。使用的字节数取决于参数的长度。所有参数都使用小端格式。
PDU格式如下图所示:
如果PDU构成由主机发起的交互的一部分,则TID应为0;如果交互是由从机发起的,则TID应为1。
接收携带LMP PDU的基带分组和发送携带有效响应PDU的基带分组之间的时间应小于LMP响应超时,现在的值为30秒。
如果LM遇到错误的情况,比如收到带有无法识别的操作码的PDU等,它将响应LMP_not_accepted或LMP_not_accepted_ext,并指示相应的错误代码。
其运用于许多不同的过程中用作对其他PDU的响应消息,格式如下图:
LMP的消息有一些约束限制:
设备特性描述了设备可以支持哪些功能和支持哪些操作。
当Controller与另一个设备连接时,LM支持的一组功能不会改变。对等设备可以缓存设备的特征掩码或扩展特征掩码,或者LM可以在连接期间缓存对等体的特征掩码或扩展特征掩码。
由于内容较多,这里仅展示一部分,详细请参考vol 2,part C,3.2节:
在LMP_features_req的请求中,这些特性会以掩码的形式包含在参数中,具体的位值如下图所示,由于内容较多,这里也只是贴出一部分,具体请参考vol 2,part C,3.3节:
这些规则在核心协议中被分为7大部分:连接控制,安全,信息请求,角色转换,模式切换,逻辑传输和测试模式,这里我只是简单的描述一下,具体内容在协议的Vol 2,Part C,第4章。
连接控制包括了连接建立,解除连接,电源控制,自适应跳频等等操作交互流程,这里举一个连接建立的例子:
连接建立
在paging过程之后,然后可以启动用于时钟偏移请求,LMP版本,支持的特征,名称请求和断连等LMP过程,流程图如下:
当寻呼设备希望创建涉及LM之上的层的连接时,它发送LMP_host_connection_req PDU。当另一方收到此消息时,将通知主机有关传入连接的信息。远程设备可以通过发送来接受或拒绝连接请求LMP_accepted PDU或LMP_not_accepted PDU。
如果接受LMP_host_connection_req PDU,则可以调用LMP安全过程(配对,认证和加密)。当设备在连接建立期间不打算启动任何更多安全过程时,它发送LMP_setup_complete PDU。当两个设备都发送了LMP_setup_complete PDU时,可以在BR / EDR ACL逻辑传输上传输数据。
安全方面的操作包括了设备认证,配对,加密,简单安全配对等等操作,这里举一个认证的例子参考:
认证
认证定义了两个身份验证过程:旧式和安全身份验证。当至少一个设备不支持安全连接功能并且本地设备允许使用旧式身份验证时,应执行传统身份验证。当两个设备都支持安全连接功能时,优先使用安全认证。
在传统认证中,如果申请人具有与验证者相关联的链接密钥,则它应计算响应并将其发送给具有LMP_sres的验证者。验证者检查响应。如果响应不正确,验证者可以通过发送带有错误代码0x05的LMP_detach PDU来结束连接,过程如下:
信息请求包含时钟偏移,LMP版本,设备支持的特性,设备名等,这里以获取LMP举例作参考:
LMP支持对LM协议版本的请求。该LMP_version_req和LMP_version_res PDU包含三个参数:VersNr,CompId和SubVersNr。VersNr指定设备支持的蓝牙LMP规范的版本。CompId用于跟踪较低蓝牙层的可能问题。所有创建LM独特实现的公司都应拥有自己的CompId。同一家公司还负责SubVersNr的管理和维护。建议每个公司为每个RF / BB / LM实施都有一个独特的SubVersNr。对于给定的VersNr和CompId,每次发布新实现时,SubVersNr的值都将增加。该过程具体流程如下图:
这部分中主要利用LMP_slot_offset,发送关于不同微微网中的时隙边界之间的差异的信息,和利用LMP_switch_req,进行主从角色切换。
该块主要进行设备的hold和sniff模式的切换,使用的PDU为:LMP_hold, LMP_hold_req和LMP_sniff_req等。
当两个设备之间首次建立连接时,连接由ACL逻辑传输(携带LMP消息的ACL-C逻辑链路和L2CAP数据的ACL-U逻辑链路)和携带ASB-C逻辑的ASB逻辑传输组成。 LMP消息的链接和L2CAP数据的ASB-U逻辑链接。然后可以添加一个或多个同步逻辑传输(SCO或eSCO)。
在LMP的第五章,主要是介绍每个类型的PDU的操作码和参数结构,以及每个参数的定义,可以看作是一个附录,如下图示:
PDU内容组成介绍在5.1节,参数介绍在5.2节。内容比较多,我就不全部贴出来了,有兴趣自行查阅。
我用sniffer抓取了一些数据,可以用于参考学习,已放到百度网盘的共享链接中,需要的请到我的博客<蓝牙学习笔记(序)>最下面的网盘链接中下载!