
HCI_Create_Connection 命令的主要功能是指示链路管理器(Link Manager)创建一个与远程设备的连接。这个连接是在BR/EDR控制器层面,通过发起寻呼(Page)过程来建立链路级别的连接。链路管理器会根据本地设备的当前状态、微微网(piconet)状态以及待连接设备的状态,来确定新的ACL连接的建立方式。
HCI_Create_Connection 命令核心功能在于促使链路管理器依据命令参数中指定的远程设备的 BD_ADDR(蓝牙设备地址),创建与该远程设备的连接。一旦此命令被执行,本地的BR/EDR控制器便会启动寻呼(Page)流程,进而创建链路级别的连接。

关于新的ACL连接具体如何建立,并非固定不变,而是由多方面因素共同决定。链路管理器会综合考量本地设备的当前状态、所在微微网(piconet)的情况以及待连接设备的状态,来最终确定该 ACL 连接的建立方式,以此实现不同蓝牙设备间有效的链路连接搭建,为后续的数据通信等操作奠定基础。
2.1. HCI_Create_Connection 命令命令格式HCI_Create_Connection 命令的格式通常遵循HCI(Host Controller Interface)协议的规范,由操作码(OpCode)、参数总长度(Parameter_Total_Length)和各个参数组成。

HCI_Create_Connection命令,OGF通常为0x01(表示链路控制),OCF为0x0005。HCI_Create_Connection命令的示例: BD_ADDR是远程设备的蓝牙设备地址(Bluetooth Device Address),用于唯一标识要连接的目标设备。链路管理器将依据这个地址来发起与特定远程设备的连接过程。

Packet_Type参数指定了链路管理器在 ACL 连接中应该使用的数据包类型。主机(Host)不能指定本地控制器不支持的数据包类型。在发送 HCI ACL 数据分组时,链路管理器只能使用由 Packet_Type 指定的数据包类型或者始终允许的 DM1 数据包类型。可以通过对不同数据包类型进行按位或(bit - wise OR)操作来为 Packet_Type 参数指定多种数据包类型,然后链路管理器会从可接受的数据包类型列表中选择要使用的数据包类型。不同数据包类型的详细定义可参考蓝牙协议文档 [Vol 2] Part B, Section 6.5。

每一位都对应着一种或多种可能的数据包类型。
数据包类型解释
Page_Scan_Repetition_Mode参数指定了具有 BD_ADDR 的远程设备所支持的寻呼扫描重复模式(Page Scan Repetition Mode)。在查询(inquiry)过程中或者从 HCI_Page_Scan_Repetition_Mode_Change 事件中获取的最新信息版本。该参数对于正确寻呼远程设备以建立连接非常重要,因为它决定了远程设备何时处于可被寻呼的状态。


Reserved目前是保留(Reserved)状态。
Clock_Offset参数表示本地设备自身时钟与具有 BD_ADDR 的远程设备时钟之间的差值。不过,在这个差值中,只有第 2 位到第 16 位被使用,并且它们分别映射到此参数的第 0 位到第 14 位。位于 Clock_Offset 参数的第 15 位的 Clock_Offset_Valid_Flag 用于指示 Clock_Offset 是否有效。这个时钟偏移信息对于蓝牙设备在连接过程中进行同步等操作是非常关键的,因为蓝牙设备需要在一定程度上同步时钟来确保数据的正确传输。

Clock_Offset 参数时,应确保该参数是有效的。如果设置了无效的时钟偏移量,那么设备可能会无法进行正确的时钟同步,从而影响通信性能。
Allow_Role_Switch 参数指定本地设备在连接建立时(在本地控制器返回 HCI_Connection_Complete 事件之前,在 HCI_Accept_Connection_Request 命令的 Role 参数中)是否接受或拒绝来自远程设备的角色切换请求。涉及到蓝牙通信中的主从角色(Master/Slave)分配问题,不同的角色在通信过程中有不同的职责和权限,例如主设备可以控制链路的时序等。

Allow_Role_Switch参数在蓝牙连接建立过程中起着重要的作用,它允许设备根据需要动态地改变角色,从而提供更大的灵活性和适应性。然而,在使用该参数时,需要考虑功耗、兼容性和安全性等因素。
当蓝牙BR/EDR控制器接收到 HCI_Create_Connection 命令后,它应当向主机(Host)发送 HCI_Command_Status 事件。

这个事件的作用在于告知主机,控制器已经接收到了创建连接的命令,让主机知晓命令传递环节已顺利完成,并且可以通过该事件反馈的相关状态信息(例如命令是否被正确接收、有无执行方面的问题等)来初步判断命令执行的起始情况。
另外,当链路管理器判定连接已经成功建立时,参与形成该连接的双方 BR/EDR 控制器都需要向各自对应的主机发送一个 HCI_Connection_Complete 事件。

这个事件十分关键,因为它包含了此次连接的连接句柄(Connection_Handle)信息(前提是 HCI_Create_Connection 命令执行成功)。连接句柄可以被主机后续用于对该连接进行各种操作和管理,比如进行数据传输、监控连接状态、执行连接相关的配置调整等。
简而言之,当尝试创建蓝牙连接时,首先会收到一个命令状态事件,表明命令已经被接收;当连接成功建立后,双方都会收到一个连接完成事件,其中包含了用于管理这个连接的句柄。
以下是对HCI_Create_Connection命令执行流程的详细梳理。
通过这一系列精心设计的步骤和事件反馈机制,HCI_Create_Connection命令能够确保蓝牙设备之间能够安全、有效地建立连接,为后续的数据传输和通信提供坚实的基础。
以下代码示例是一个高度概括的版本,旨在展示如何组织代码来模拟这一流程。请注意,实际实现将依赖于特定的蓝牙协议栈和硬件接口。
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h> // 用于sleep函数模拟延迟
// 假设的HCI命令结构体
typedef struct {
uint16_t opcode; // 命令码
uint8_t bdaddr[6]; // 远端蓝牙设备地址
uint8_t packet_type; // 数据包类型
uint8_t page_scan_rep_mode; // 寻呼扫描重复模式
uint8_t reserved; // 保留位
uint16_t clock_offset; // 时钟偏移量
uint8_t allow_role_switch; // 是否允许角色转换
} hci_create_connection_cp;
// 假设的HCI事件结构体
typedef struct {
uint8_t event;
uint8_t status;
uint16_t connection_handle; // 连接句柄
// 其他可能的事件参数...
} hci_event_t;
// 模拟发送HCI命令的函数
void send_hci_command(const hci_create_connection_cp *cp) {
// 在这里实现与蓝牙硬件驱动的交互来发送HCI命令
// 例如,通过串口、USB或其他接口发送数据
printf("Sending HCI_Create_Connection command...\n");
// 模拟命令发送成功
}
// 模拟接收HCI事件的函数
void receive_hci_event(hci_event_t *event) {
// 在这里实现从蓝牙硬件驱动接收HCI事件的逻辑
// 例如,通过串口、USB或其他接口接收数据
// 这里我们模拟一个成功的连接完成事件
event->event = 0x03; // 假设0x03是连接完成事件的代码
event->status = 0x00; // 状态码0x00表示成功
event->connection_handle = 0x0001; // 假设的连接句柄
// 设置其他事件参数...
}
// 模拟等待并处理HCI命令状态的函数
void wait_for_command_status(uint16_t opcode) {
// 在这里实现等待HCI_Command_Status事件的逻辑
// 可以设置一个超时机制来防止无限等待
// 这里我们简单模拟一个成功的命令状态反馈
printf("Received HCI_Command_Status event (command accepted).\n");
}
// 主函数,模拟HCI_Create_Connection命令的执行流程
int main() {
// 准备HCI_Create_Connection命令参数
hci_create_connection_cp cp;
memset(&cp, 0, sizeof(cp));
cp.opcode = 0x0005; // HCI_Create_Connection命令码
// 设置远端蓝牙设备地址(示例地址)
cp.bdaddr[0] = 0x00; cp.bdaddr[1] = 0x11; cp.bdaddr[2] = 0x22;
cp.bdaddr[3] = 0x33; cp.bdaddr[4] = 0x44; cp.bdaddr[5] = 0x55;
cp.packet_type = 0x03; // 示例数据包类型
cp.page_scan_rep_mode = 0x02; // 示例寻呼扫描重复模式
cp.reserved = 0x00;
cp.clock_offset = 0x0000; // 示例时钟偏移量
cp.allow_role_switch = 0x01; // 允许角色转换
// 发送HCI_Create_Connection命令
send_hci_command(&cp);
// 等待并处理HCI_Command_Status事件
wait_for_command_status(cp.opcode);
// 准备接收HCI_Connection_Complete事件
hci_event_t event;
receive_hci_event(&event);
// 检查连接完成事件的状态
if (event.status == 0x00) {
printf("Connection established successfully with handle 0x%04X\n", event.connection_handle);
// 在这里实现连接建立后的后续操作,如数据传输等
} else {
printf("Failed to establish connection, status 0x%02X\n", event.status);
}
// 在实际应用中,这里应该还有更多的错误处理和资源管理代码
return 0;
}请注意,上述代码仅用于演示目的,并没有实际与蓝牙硬件进行交互。在实际应用中,需要根据所使用的蓝牙协议栈和硬件接口来实现send_hci_command和receive_hci_event函数的具体逻辑。此外,还需要处理各种可能的错误情况和超时情况,以确保系统的健壮性和稳定性。
HCI_Create_Connection命令在蓝牙通信中扮演着至关重要的角色,其应用场景主要涉及到与指定蓝牙设备建立ACL连接的过程。以下是该命令的具体应用场景梳理。
HCI_Create_Connection命令在蓝牙通信中具有广泛的应用场景,涵盖了从个人娱乐设备到工业监控系统的各个领域。通过该命令,蓝牙设备能够建立稳定的连接,实现数据传输和通信功能,为用户的日常生活和工作提供了极大的便利。
综上所述,HCI_Create_Connection命令是蓝牙技术中建立ACL连接的重要命令。它涉及多个关键参数的设置和执行流程的监控,需要在使用时特别注意准确性和安全性。同时,该命令也广泛应用于各种蓝牙设备之间的通信连接场景。