目录
一、命令概述
二、命令格式及参数说明
2.1. HCI_Link_Key_Request_Negative_Reply命令格式
2.2. BD_ADDR
三、返回事件及参数
3.1. 生成的事件
3.2. BD_ADDR
2.3. Status
四、命令执行流程场景
4.1. 命令触发条件
4.2. 命令组装与发送
4.3. 控制器接收与处理
4.4. 执行结果反馈
4.5. 事件生成(如果适用)
4.6. 示例代码
五、使用场景
5.1. 安全认证环节
5.2. 设备管理与权限控制场景
5.3. 设备兼容性与协议差异场景
5.4. 命令影响
六、注意事项
6.1. 命令发送时机与参数设置
6.2. 状态码检查与错误处理
6.3. BD_ADDR准确性
6.4. 命令时效性与同步性
6.5. 协议版本和兼容性
6.6. 安全策略与设备管理
当两个BR/EDR控制器尝试建立安全连接时,可能需要共享一个Link Key。这个Link Key是一个用于加密和解密在蓝牙连接上传输的数据的密钥。如果主机(Host)没有为与另一个BR/EDR控制器(由BD_ADDR指定)之间的连接存储Link Key,那么当该控制器发出HCI_Link_Key_Request事件时,主机就会使用HCI_Link_Key_Request_Negative_Reply命令进行回应。
一、命令概述
当BR/EDR控制器需要Link Key来建立连接时,会生成HCI_Link_Key_Request事件。通常发生在远程主机发送了HCI_Create_Connection或HCI_Authentication_Requested命令后,远程链路管理器(Link Manager)向本地链路管理器发出请求时。
在这种情况下,本地主机必须在远程链路管理器检测到LMP响应超时之前,使用HCI_Link_Key_Request_Reply或HCI_Link_Key_Request_Negative_Reply命令进行回应。如果主机没有为指定BD_ADDR的连接存储Link Key,则应使用HCI_Link_Key_Request_Negative_Reply命令进行回应。
HCI_Link_Key_Request_Negative_Reply包含两个主要的参数,即 BD_ADDR(蓝牙设备地址)和 Status(状态)。BD_ADDR 用于指定目标蓝牙设备,也就是对来自这个设备的链路密钥请求做出否定回复。
二、命令格式及参数说明
2.1. HCI_Link_Key_Request_Negative_Reply命令格式
HCI_Link_Key_Request_Negative_Reply命令通常遵循蓝牙核心规范中定义的HCI命令格式。包括命令操作码(OCF)、参数长度、以及具体的参数值。
- 命令操作码(OCF):用于标识这是一个HCI_Link_Key_Request_Negative_Reply命令。
- 参数长度:表示后续参数的总长度(以字节为单位)。对于HCI_Link_Key_Request_Negative_Reply命令,参数长度通常包括BD_ADDR和Status两个参数的长度。
- 参数:BD_ADDR。
2.2. BD_ADDR
BD_ADDR
指定了与链路密钥请求相关的目标蓝牙设备。当主机(Host)发送这个否定回复命令时,它通过BD_ADDR
告诉控制器这个回复是针对哪一个具体的设备的链路密钥请求。蓝牙MAC地址-CSDN博客
三、返回事件及参数
3.1. 生成的事件
当HCI_Link_Key_Request_Negative_Reply命令执行完成后,会生成一个HCI_Command_Complete事件。这个事件是蓝牙HCI用于通知主机命令已经成功执行或失败的标准机制。
- 事件名称:HCI_Command_Complete
- 生成条件:当HCI_Link_Key_Request_Negative_Reply命令执行完成后(无论成功还是失败)。
- 包含的信息:该事件通常包含命令的操作码(OCF)、返回参数(如Status和BD_ADDR,如果适用)、以及任何额外的状态或结果信息。
3.2. BD_ADDR
BD_ADDR
用于唯一标识已完成 HCI_Link_Key_Request_Negative_Reply
命令的蓝牙设备。
0x
前缀表示这是一个十六进制数,XXXXXXXXXXXX
是地址的具体值,其中每个 X
代表一个十六进制字符(0-9 或 A-F)。
2.3. Status
Status
用于指示 HCI_Link_Key_Request_Negative_Reply
命令的执行结果。这个参数的值决定了命令是成功还是失败,并提供了有关失败原因的详细信息(如果适用)。
0x00
:表示HCI_Link_Key_Request_Negative_Reply
命令成功执行。意味着主机已经正确地发送了拒绝Link Key请求的回应,并且没有遇到任何错误。0x01
至0xFF
:表示HCI_Link_Key_Request_Negative_Reply
命令执行失败。这些值对应于不同的错误代码,每个代码都代表了一个特定的错误情况。具体的错误代码和对应的描述可以在蓝牙核心规范的[Vol 1] Part F, Controller Error Codes部分找到。蓝牙Controller错误代码全面概览_connection rejected due to limited resources-CSDN博客
四、命令执行流程场景
4.1. 命令触发条件
当蓝牙主机(Host)收到来自BR/EDR控制器的HCI_Link_Key_Request
事件时,如果该主机没有为与请求中指定的BD_ADDR
相关联的连接存储链路密钥(Link Key),则会触发HCI_Link_Key_Request_Negative_Reply
命令的发送。
4.2. 命令组装与发送
- 组装命令包:
- 操作码(OCF):设置为
0x000C
,以标识该命令为HCI_Link_Key_Request_Negative_Reply
。 - 参数:
BD_ADDR
:6个字节,表示请求链路密钥的远程蓝牙设备的地址。
- 操作码(OCF):设置为
- 发送命令:主机通过HCI接口将组装好的命令包发送给蓝牙控制器。这个过程涉及多个层次的协议处理,以确保命令能够准确无误地到达目标控制器。
4.3. 控制器接收与处理
- 接收命令:蓝牙控制器接收来自主机的命令包,并检查操作码以确认是否为
HCI_Link_Key_Request_Negative_Reply
命令。 - 处理命令:
- 控制器解析命令包中的
BD_ADDR
和Status
参数。 - 根据
BD_ADDR
确定该否定回复是针对哪个具体的设备连接请求。 - 将否定回复信息传递给相应的模块(如链路管理器),用于处理与目标设备的连接请求后续操作。
- 控制器解析命令包中的
4.4. 执行结果反馈
- 更新命令状态:
- 控制器根据命令的执行情况更新
Status
参数。 - 如果命令执行成功(如成功将否定回复信息传递给相关模块,且系统资源足够、通信链路正常等),则
Status
设置为0x00
。
- 控制器根据命令的执行情况更新
- 返回结果给主机:
- 控制器将包含更新后的
Status
和BD_ADDR
的结果信息打包成一个响应包,并通过HCI接口返回给主机。 - 主机接收响应包后,根据
Status
的值判断命令是否成功执行。
- 控制器将包含更新后的
4.5. 事件生成(如果适用)
- 当
HCI_Link_Key_Request_Negative_Reply
命令成功完成(即Status
为0x00
)时,会生成一个HCI_Command_Complete
事件。 - 该事件可以被主机中的其他模块捕获,用于通知系统相关部分该命令已经成功执行,并可能触发其他操作(如更新用户界面显示连接被拒绝的信息等)。
4.6. 示例代码
以下是一个简化的C语言代码示例,用于展示如何在一个蓝牙主机控制器中实现HCI_Link_Key_Request_Negative_Reply
命令的基本流程。请注意,这只是一个概念性的示例,并不包含完整的蓝牙协议栈实现或硬件接口代码。
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>// 假设这些结构体和函数是由蓝牙协议栈库提供的
typedef struct {uint8_t bd_addr[6];uint8_t status;
} HCI_Link_Key_Request_Negative_Reply_Command;typedef struct {uint16_t opcode;uint8_t status;uint8_t bd_addr[6];
} HCI_Command_Complete_Event;// 模拟发送HCI命令的函数(在实际中,这将与蓝牙硬件接口)
bool send_hci_command(uint16_t opcode, uint8_t *data, uint16_t length) {// 这里只是模拟发送,实际上需要将数据发送到蓝牙控制器printf("Sending HCI command with opcode 0x%04X\n", opcode);// ...(发送数据的代码)return true; // 假设发送成功
}// 模拟接收HCI事件的函数(在实际中,这将由蓝牙硬件中断触发)
void receive_hci_event(uint8_t *event_data, uint16_t length) {// 解析接收到的HCI事件if (length >= sizeof(HCI_Command_Complete_Event)) {HCI_Command_Complete_Event *event = (HCI_Command_Complete_Event *)event_data;if (event->opcode == 0x000C) { // 检查是否为我们的命令完成事件printf("Received HCI Command Complete Event for Link Key Request Negative Reply\n");printf("Status: 0x%02X, BD_ADDR: ", event->status);for (int i = 0; i < 6; i++) {printf("%02X ", event->bd_addr[i]);}printf("\n");}// ...(处理其他事件的代码)}
}// 发送HCI_Link_Key_Request_Negative_Reply命令的函数
bool send_link_key_request_negative_reply(const uint8_t *bd_addr, uint8_t status) {HCI_Link_Key_Request_Negative_Reply_Command command;command.bd_addr[0] = bd_addr[0];command.bd_addr[1] = bd_addr[1];command.bd_addr[2] = bd_addr[2];command.bd_addr[3] = bd_addr[3];command.bd_addr[4] = bd_addr[4];command.bd_addr[5] = bd_addr[5];command.status = status;uint16_t opcode = 0x0013; // HCI_Link_Key_Request_Negative_Reply的OCF为0x000C,加上OGF(通常为0x0001表示Link Control Commands)得到完整的opcodebool success = send_hci_command(opcode, (uint8_t *)&command, sizeof(command));if (success) {// 在这里,我们可能会等待一个HCI_Command_Complete事件来确认命令的成功执行// 但在这个简化的示例中,我们不会实现这一点printf("HCI_Link_Key_Request_Negative_Reply command sent successfully\n");} else {printf("Failed to send HCI_Link_Key_Request_Negative_Reply command\n");}return success;
}int main() {// 示例BD_ADDR和状态码uint8_t bd_addr[6] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55};uint8_t status = 0x00; // 表示成功(在这个上下文中,状态码的具体含义由蓝牙协议定义)// 发送Link Key Request Negative Reply命令send_link_key_request_negative_reply(bd_addr, status);// 在实际应用中,这里将会有一个事件循环来接收和处理来自蓝牙控制器的HCI事件// 但在这个简化的示例中,我们不会实现这一点return 0;
}
在这个示例中,我们使用了0x00作为状态码,但在实际应用中,应该根据蓝牙协议和具体需求来选择合适的状态码。
五、使用场景
5.1. 安全认证环节
- 初次配对失败场景
- 描述:在蓝牙设备初次配对过程中,若主机未存储与请求连接设备对应的Link Key,会拒绝连接请求。
- 示例:新蓝牙音箱尝试与手机配对,手机若未预先存储音箱的Link Key,则发送HCI_Link_Key_Request_Negative_Reply命令拒绝请求。
- 重新连接但密钥丢失场景
- 描述:已配对设备因某些原因(如恢复出厂设置、数据丢失)导致主机丢失Link Key,当设备再次尝试连接时,主机拒绝其Link Key请求。
- 示例:用户重置蓝牙耳机后尝试与之前配对过的手机重新连接,手机发现无该耳机的Link Key后,发送否定回复命令。
5.2. 设备管理与权限控制场景
- 未经授权设备连接拒绝场景
- 描述:在需要高安全性的环境中,主机拒绝未经授权的蓝牙设备连接请求。
- 示例:企业内部敏感设备只允许特定蓝牙设备连接,未知设备尝试连接并请求Link Key时,主机发送否定回复命令。
- 设备连接数量限制场景
- 描述:主机达到允许连接的蓝牙设备数量上限时,拒绝新的连接请求。
- 示例:智能手表最多允许同时连接3个蓝牙设备,第四个设备尝试连接并请求Link Key时,手表发送否定回复命令。
5.3. 设备兼容性与协议差异场景
- 旧设备与新协议不兼容场景
- 描述:蓝牙协议更新后,旧设备发送不符合新协议要求的Link Key请求,主机无法处理或不支持旧协议版本对应的请求方式时,发送否定回复命令。
- 示例:蓝牙协议从4.0更新到6.0后,基于旧版本协议设计的蓝牙设备尝试请求Link Key,新主机设备拒绝请求。
- 不同设备类型之间不兼容场景
- 描述:不同类型的蓝牙设备安全要求和Link Key管理方式不同,当一种设备的请求不符合另一种设备的安全策略或协议规范时,接收请求的主机发送否定回复命令。
- 示例:医疗设备蓝牙模块请求连接到普通消费类电子设备,由于医疗设备安全级别较高,其Link Key请求方式不被消费类设备接受,导致消费类设备发送否定回复命令。
5.4. 命令影响
- 连接失败:当HCI_Link_Key_Request_Negative_Reply命令被发送时,表示当前蓝牙连接尝试失败,设备间无法建立安全连接。
- 用户操作:用户可能需要重新尝试配对过程,或检查设备的蓝牙设置和兼容性。
HCI_Link_Key_Request_Negative_Reply命令在蓝牙通信中用于指示链路密钥请求失败的情况,通常与设备兼容性、配置问题、安全简单配对过程中的问题或设备管理与权限控制相关。
六、注意事项
在使用HCI_Link_Key_Request_Negative_Reply命令进行蓝牙通信时,需要关注以下关键事项以确保命令的正确执行和蓝牙设备间的稳定连接。
6.1. 命令发送时机与参数设置
- 在蓝牙设备尝试建立安全连接且主机无法找到或验证匹配的链路密钥时,及时发送此命令。
- 确保命令中包含正确的远端设备地址(BD_ADDR)以标识请求链路密钥的设备。
- 仔细检查并设置状态码(Status),以准确反映命令的执行情况。
6.2. 状态码检查与错误处理
- 接收控制器返回的结果后,仔细检查状态码,并根据蓝牙核心规范中的错误码列表进行详细的排查和处理。
- 规划好错误处理机制,如检查连接稳定性、设备兼容性或主机存储中的数据损坏问题,并向用户提供清晰的反馈。
6.3. BD_ADDR准确性
- 确保BD_ADDR正确标识目标设备,避免命令发送到错误的设备或无法正确识别需要拒绝Link Key请求的设备。
- 注意BD_ADDR的格式(6个字节)和传输完整性,遵循蓝牙协议规范。
6.4. 命令时效性与同步性
- 遵守命令响应时间要求,在远程链路管理器检测到LMP响应超时之前发送命令,避免通信双方链路管理器状态不一致。
- 同步处理与其他蓝牙命令和事件的关系,避免命令顺序混乱或冲突导致的蓝牙连接故障。
6.5. 协议版本和兼容性
- 考虑不同蓝牙协议版本对命令细节的差异,确保设备所遵循的协议版本与命令的实际使用方式相匹配。
- 进行充分的兼容性测试,确保在不同品牌、型号的设备之间使用该命令时能够正常工作。
6.6. 安全策略与设备管理
- 确保发送HCI_Link_Key_Request_Negative_Reply命令符合设备的安全策略,如在企业或安全要求较高的环境中拒绝未经授权的蓝牙设备连接请求。
- 定期检查设备的蓝牙设置和兼容性,以确保设备间的安全通信。
综上所述,HCI_Link_Key_Request_Negative_Reply命令是蓝牙协议栈中用于回应Link Key请求的重要命令之一。当主机没有为指定连接存储Link Key时,应使用此命令进行回应。