【Linux驱动构建】Linux BlueZ协议栈底层实现原理详解
Linux BlueZ协议栈底层实现原理详解
1. BlueZ架构解析
1.1 整体架构设计
BlueZ是Linux官方蓝牙协议栈,采用分层模块化架构,实现了从硬件驱动到应用接口的完整蓝牙解决方案:
用户空间应用
↓
D-Bus接口 (org.bluez)
↓
BlueZ用户空间守护进程
↓
AF_BLUETOOTH Socket接口
↓
Linux内核蓝牙子系统 (net/bluetooth)
↓
HCI层 (Host Controller Interface)
↓
L2CAP层 (Logical Link Control and Adaptation Protocol)
↓
RFCOMM层 (Serial Port Emulation)
↓
BNEP层 (Bluetooth Network Encapsulation Protocol)
↓
蓝牙硬件驱动
↓
蓝牙芯片
核心架构组件
1. 内核空间组件 (net/bluetooth/)
// 主要源码文件结构
net/bluetooth/
├── bluetooth.h # 核心数据结构和接口定义
├── hci/ # HCI协议层实现
│ ├── hci_core.c # HCI核心逻辑
│ ├── hci_event.c # HCI事件处理
│ ├── hci_conn.c # HCI连接管理
│ ├── hci_sysfs.c # HCI sysfs接口
│ └── hci_sock.c # HCI Socket接口
├── l2cap/ # L2CAP协议层
│ ├── l2cap_core.c # L2CAP核心逻辑
│ ├── l2cap_sock.c # L2CAP Socket接口
│ └── l2cap_debugfs.c # L2CAP调试接口
├── rfcomm/ # RFCOMM协议层
│ ├── rfcomm_core.c # RFCOMM核心逻辑
│ ├── rfcomm_sock.c # RFCOMM Socket接口
│ └── rfcomm_tty.c # RFCOMM TTY接口
├── bnep/ # BNEP协议层
│ ├── bnep_core.c # BNEP核心逻辑
│ └── bnep_sock.c # BNEP Socket接口
├── sco/ # SCO音频链路层
│ ├── sco_core.c # SCO核心逻辑
│ └── sco_sock.c # SCO Socket接口
├── amp/ # AMP (Alternate MAC/PHY)支持
├── mgmt/ # 管理接口
│ ├── mgmt.c # 管理协议实现
│ └── mgmt_util.c # 管理工具函数
└── lib/ # 通用库函数
├── utils.c # 工具函数
└── crypto.c # 加密相关函数
2. 用户空间组件
/usr/lib/bluetooth/
├── bluetoothd # BlueZ守护进程
├── bluetoothctl # 命令行控制工具
├── hciconfig # HCI设备配置工具
├── hcitool # HCI工具
├── sdptool # SDP工具
├── rfcomm # RFCOMM工具
└── gatttool # GATT工具
1.2 模块化架构设计
协议层模块化
// 协议层注册机制
struct bt_proto {
const char *name;
int (*init)(void);
void (*exit)(void);
int (*sock_create)(struct socket *sock, int protocol);
struct proto *proto;
struct module *owner;
};
// 各协议层注册实例
static struct bt_proto l2cap_proto = {
.name = "L2CAP",
.init = l2cap_init,
.exit = l2cap_exit,
.sock_create = l2cap_sock_create,
.proto = &l2cap_proto,
.owner = THIS_MODULE,
};
static struct bt_proto rfcomm_proto = {
.name = "RFCOMM",
.init = rfcomm_init,
.exit = rfcomm_exit,
.sock_create = rfcomm_sock_create,
.proto = &rfcomm_proto,
.owner = THIS_MODULE,
};
static struct bt_proto sco_proto = {
.name = "SCO",
.init = sco_init,
.exit = sco_exit,
.sock_create = sco_sock_create,
.proto = &sco_proto,
.owner = THIS_MODULE,
};
核心数据结构
// 蓝牙设备核心结构
struct hci_dev {
struct list_head list;
atomic_t refcnt;
__u16 id; // HCI设备ID
char name[8]; // 设备名称 (hci0, hci1, ...)
unsigned long flags; // 设备标志
__u8 bus; // 总线类型 (USB, UART, etc.)
bdaddr_t bdaddr; // 蓝牙设备地址
__u8 dev_class[3]; // 设备类别
char *hw_info; // 硬件信息
// 协议栈状态
__u16 manufacturer; // 制造商ID
__u8 hci_ver; // HCI版本
__u16 hci_rev; // HCI修订版本
__u8 lmp_ver; // LMP版本
__u16 lmp_subver; // LMP子版本
// 功能支持
__u8 commands[64]; // 支持的HCI命令
__u8 features[8]; // 支持的LMP功能
__u8 le_features[8]; // 支持的LE功能
__u8 le_states[8]; // 支持的LE状态
// 连接管理
struct list_head conn_hash[HASH_SIZE]; // 连接哈希表
struct list_head mgmt_pending; // 管理命令队列
// 工作队列
work_struct_work; // 工作队列
work_struct_rx_work; // 接收工作队列
work_struct_tx_work; // 发送工作队列
// Socket接口
struct sk_buff_head rx_q; // 接收队列
struct sk_buff_head tx_q; // 发送队列
struct sk_buff_head cmd_q; // 命令队列
struct sk_buff_head raw_q; // 原始数据队列
// 统计信息
atomic_t cmd_cnt; // 命令计数
atomic_t acl_cnt; // ACL数据计数
atomic_t sco_cnt; // SCO数据计数
atomic_t le_cnt; // LE数据计数
// 安全信息
__u8 auth_enable; // 认证使能
__u8 ssp_mode; // 安全简单配对模式
__u8 sc_mode; // 安全连接模式
__u8 debug_mode; // 调试模式
// 电源管理
__u8 power_switch; // 电源开关
__u8 le_white_list_size; // LE白名单大小
__u8 le_resolv_list_size; // LE解析列表大小
// 驱动接口
struct hci_driver *driver; // HCI驱动
void *driver_data; // 驱动私有数据
// Sysfs接口
struct device dev; // 设备模型
struct dentry *debugfs; // debugfs接口
};
// 蓝牙连接结构
struct hci_conn {
struct list_head list;
atomic_t refcnt;
struct hci_dev *hdev; // 所属HCI设备
bdaddr_t dst; // 对端设备地址
__u8 dst_type; // 对端地址类型
bdaddr_t src; // 本地设备地址
__u8 src_type; // 本地地址类型
// 连接参数
__u16 handle; // 连接句柄
__u8 type; // 连接类型 (ACL, SCO, LE)
__u8 state; // 连接状态
__u8 mode; // 连接模式
__u8 role; // 连接角色
// 链路参数
__u16 mtu; // MTU大小
__u16 max_mtu; // 最大MTU
__u16 cnt; // 数据包计数
__u16 sco_pkt_len; // SCO数据包长度
// 加密信息
__u8 sec_level; // 安全级别
__u8 pending_sec_level; // 待处理安全级别
__u8 link_mode; // 链路模式
__u8 link_policy; // 链路策略
// QoS参数
__u8 qos_type; // QoS类型
struct hci_qos qos; // QoS参数
// 电源管理
__u8 power_save; // 省电模式
__u8 idle_timeout; // 空闲超时
// L2CAP通道
struct list_head chan_list; // L2CAP通道列表
// 工作队列
work_struct_work; // 工作队列
// 统计信息
atomic_t sent; // 发送数据包数
atomic_t recv; // 接收数据包数
atomic_t drop; // 丢弃数据包数
// 私有数据
void *priv; // 私有数据
// 调试信息
struct dentry *debugfs; // debugfs接口
};
1.3 内核空间与用户空间交互原理
Socket接口层
// AF_BLUETOOTH Socket实现
static const struct net_proto_family bluetooth_family_ops = {
.family = PF_BLUETOOTH,
.create = bt_sock_create,
.owner = THIS_MODULE,
};
// Socket创建函数
static int bt_sock_create(struct net *net, struct socket *sock,
int protocol, int kern)
{
struct sock *sk;
int err;
// 验证协议
if (protocol < 0 || protocol >= BT_MAX_PROTO)
return -EINVAL;
// 分配socket
sk = sk_alloc(net, PF_BLUETOOTH, GFP_KERNEL, &bt_proto[protocol], kern);
if (!sk)
return -ENOMEM;
// 初始化socket
sock_init_data(sock, sk);
sock->state = SS_UNCONNECTED;
sock->ops = &bt_proto[protocol]->ops;
// 调用协议特定的创建函数
if (bt_proto[protocol]->sock_create) {
err = bt_proto[protocol]->sock_create(sock, protocol);
if (err) {
sk_free(sk);
return err;
}
}
return 0;
}
HCI Socket接口
// HCI Socket实现
static const struct proto_ops hci_sock_ops = {
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.release = hci_sock_release,
.bind = hci_sock_bind,
.connect = hci_sock_connect,
.listen = hci_sock_listen,
.accept = hci_sock_accept,
.sendmsg = hci_sock_sendmsg,
.recvmsg = hci_sock_recvmsg,
.mmap = hci_sock_mmap,
.poll = hci_sock_poll,
.ioctl = hci_sock_ioctl,
.compat_ioctl = hci_sock_compat_ioctl,
};
// HCI Socket发送函数
static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
{
struct sock *sk = sock->sk;
struct hci_dev *hdev;
struct sk_buff *skb;
int err;
// 获取HCI设备
hdev = hci_pi(sk)->hdev;
if (!hdev)
return -EBADFD;
// 验证消息长度
if (len < 4 || len > HCI_MAX_FRAME_SIZE)
return -EINVAL;
// 分配sk_buff
skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err);
if (!skb)
return err;
// 复制数据
err = memcpy_from_msg(skb_put(skb, len), msg, len);
if (err) {
kfree_skb(skb);
return err;
}
// 处理HCI命令
if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) {
err = hci_send_cmd(hdev, skb);
} else if (bt_cb(skb)->pkt_type == HCI_ACLDATA_PKT) {
err = hci_send_acl(hdev, skb);
} else if (bt_cb(skb)->pkt_type == HCI_SCODATA_PKT) {
err = hci_send_sco(hdev, skb);
} else {
kfree_skb(skb);
err = -EINVAL;
}
return err ? : len;
}
D-Bus接口映射
// D-Bus到内核的映射机制
static const struct hci_mgmt_handler {
u16 opcode;
int (*func)(struct sock *sk, struct hci_dev *hdev,
void *data, u16 len);
u16 var_size;
bool var_terminate;
} hci_mgmt_handlers[] = {
{ HCI_OP_READ_VERSION, mgmt_read_version, sizeof(struct hci_rp_read_version), false },
{ HCI_OP_READ_COMMANDS, mgmt_read_commands, sizeof(struct hci_rp_read_commands), false },
{ HCI_OP_READ_INDEX_LIST, mgmt_read_index_list, sizeof(struct hci_rp_read_index_list), false },
{ HCI_OP_READ_INFO, mgmt_read_info, sizeof(struct hci_rp_read_info), false },
{ HCI_OP_SET_POWERED, mgmt_set_powered, sizeof(struct hci_cp_set_powered), false },
{ HCI_OP_SET_CONNECTABLE, mgmt_set_connectable, sizeof(struct hci_cp_set_connectable), false },
{ HCI_OP_SET_DISCOVERABLE, mgmt_set_discoverable, sizeof(struct hci_cp_set_discoverable), false },
{ HCI_OP_SET_BONDABLE, mgmt_set_bondable, sizeof(struct hci_cp_set_bondable), false },
{ HCI_OP_SET_PAIRABLE, mgmt_set_pairable, sizeof(struct hci_cp_set_pairable), false },
{ HCI_OP_SET_LINK_SECURITY, mgmt_set_link_security, sizeof(struct hci_cp_set_link_security), false },
{ HCI_OP_SET_SSP, mgmt_set_ssp, sizeof(struct hci_cp_set_ssp), false },
{ HCI_OP_SET_HS, mgmt_set_hs, sizeof(struct hci_cp_set_hs), false },
{ HCI_OP_SET_LE, mgmt_set_le, sizeof(struct hci_cp_set_le), false },
{ HCI_OP_SET_DEV_CLASS, mgmt_set_dev_class, sizeof(struct hci_cp_set_dev_class), false },
{ HCI_OP_SET_LOCAL_NAME, mgmt_set_local_name, sizeof(struct hci_cp_set_local_name), true },
{ HCI_OP_ADD_UUID, mgmt_add_uuid, sizeof(struct hci_cp_add_uuid), false },
{ HCI_OP_REMOVE_UUID, mgmt_remove_uuid, sizeof(struct hci_cp_remove_uuid), false },
{ HCI_OP_LOAD_LINK_KEYS, mgmt_load_link_keys, sizeof(struct hci_cp_load_link_keys), true },
{ HCI_OP_LOAD_LONG_TERM_KEYS, mgmt_load_long_term_keys, sizeof(struct hci_cp_load_long_term_keys), true },
{ HCI_OP_DISCONNECT, mgmt_disconnect, sizeof(struct hci_cp_disconnect), false },
{ HCI_OP_GET_CONNECTIONS, mgmt_get_connections, sizeof(struct hci_rp_get_connections), false },
{ HCI_OP_PIN_CODE_REPLY, mgmt_pin_code_reply, sizeof(struct hci_cp_pin_code_reply), false },
{ HCI_OP_PIN_CODE_NEG_REPLY, mgmt_pin_code_neg_reply, sizeof(struct hci_cp_pin_code_neg_reply), false },
{ HCI_OP_SET_IO_CAPABILITY, mgmt_set_io_capability, sizeof(struct hci_cp_set_io_capability), false },
{ HCI_OP_PAIR_DEVICE, mgmt_pair_device, sizeof(struct hci_cp_pair_device), false },
{ HCI_OP_CANCEL_PAIR_DEVICE, mgmt_cancel_pair_device, sizeof(struct hci_cp_cancel_pair_device), false },
{ HCI_OP_UNPAIR_DEVICE, mgmt_unpair_device, sizeof(struct hci_cp_unpair_device), false },
{ HCI_OP_USER_CONFIRM_REPLY, mgmt_user_confirm_reply, sizeof(struct hci_cp_user_confirm_reply), false },
{ HCI_OP_USER_CONFIRM_NEG_REPLY, mgmt_user_confirm_neg_reply, sizeof(struct hci_cp_user_confirm_neg_reply), false },
{ HCI_OP_USER_PASSKEY_REPLY, mgmt_user_passkey_reply, sizeof(struct hci_cp_user_passkey_reply), false },
{ HCI_OP_USER_PASSKEY_NEG_REPLY, mgmt_user_passkey_neg_reply, sizeof(struct hci_cp_user_passkey_neg_reply), false },
{ HCI_OP_READ_LOCAL_OOB_DATA, mgmt_read_local_oob_data, sizeof(struct hci_rp_read_local_oob_data), false },
{ HCI_OP_ADD_REMOTE_OOB_DATA, mgmt_add_remote_oob_data, sizeof(struct hci_cp_add_remote_oob_data), false },
{ HCI_OP_REMOVE_REMOTE_OOB_DATA, mgmt_remove_remote_oob_data, sizeof(struct hci_cp_remove_remote_oob_data), false },
{ HCI_OP_START_DISCOVERY, mgmt_start_discovery, sizeof(struct hci_cp_start_discovery), false },
{ HCI_OP_STOP_DISCOVERY, mgmt_stop_discovery, sizeof(struct hci_cp_stop_discovery), false },
{ HCI_OP_CONFIRM_NAME, mgmt_confirm_name, sizeof(struct hci_cp_confirm_name), false },
{ HCI_OP_BLOCK_DEVICE, mgmt_block_device, sizeof(struct hci_cp_block_device), false },
{ HCI_OP_UNBLOCK_DEVICE, mgmt_unblock_device, sizeof(struct hci_cp_unblock_device), false },
{ HCI_OP_SET_DEVICE_ID, mgmt_set_device_id, sizeof(struct hci_cp_set_device_id), false },
{ HCI_OP_SET_ADVERTISING, mgmt_set_advertising, sizeof(struct hci_cp_set_advertising), false },
{ HCI_OP_SET_BREDR, mgmt_set_bredr, sizeof(struct hci_cp_set_bredr), false },
{ HCI_OP_SET_STATIC_ADDRESS, mgmt_set_static_address, sizeof(struct hci_cp_set_static_address), false },
{ HCI_OP_SET_SCAN_PARAMS, mgmt_set_scan_params, sizeof(struct hci_cp_set_scan_params), false },
{ HCI_OP_SET_SECURE_CONN, mgmt_set_secure_conn, sizeof(struct hci_cp_set_secure_conn), false },
{ HCI_OP_SET_DEBUG_KEYS, mgmt_set_debug_keys, sizeof(struct hci_cp_set_debug_keys), false },
{ HCI_OP_SET_PRIVACY, mgmt_set_privacy, sizeof(struct hci_cp_set_privacy), false },
{ HCI_OP_LOAD_IRKS, mgmt_load_irks, sizeof(struct hci_cp_load_irks), true },
{ HCI_OP_GET_CONN_INFO, mgmt_get_conn_info, sizeof(struct hci_rp_get_conn_info), false },
{ HCI_OP_GET_CLOCK_INFO, mgmt_get_clock_info, sizeof(struct hci_rp_get_clock_info), false },
{ HCI_OP_ADD_DEVICE, mgmt_add_device, sizeof(struct hci_cp_add_device), false },
{ HCI_OP_REMOVE_DEVICE, mgmt_remove_device, sizeof(struct hci_cp_remove_device), false },
{ HCI_OP_SET_APPEARANCE, mgmt_set_appearance, sizeof(struct hci_cp_set_appearance), false },
{ HCI_OP_SET_PHY_CONFIGURATION, mgmt_set_phy_configuration, sizeof(struct hci_cp_set_phy_configuration), false },
{ HCI_OP_LOAD_BONDING_KEYS, mgmt_load_bonding_keys, sizeof(struct hci_cp_load_bonding_keys), true },
{ HCI_OP_SET_EXTERNAL_CONFIG, mgmt_set_external_config, sizeof(struct hci_cp_set_external_config), false },
{ HCI_OP_SET_PUBLIC_ADDRESS, mgmt_set_public_address, sizeof(struct hci_cp_set_public_address), false },
{ HCI_OP_SET_RPA_RESOLVING, mgmt_set_rpa_resolving, sizeof(struct hci_cp_set_rpa_resolving), false },
{ HCI_OP_SET_STATIC_IDENTITY_ADDRESS, mgmt_set_static_identity_address, sizeof(struct hci_cp_set_static_identity_address), false },
{ HCI_OP_SET_ADVERTISING_SETS, mgmt_set_advertising_sets, sizeof(struct hci_cp_set_advertising_sets), false },
{ HCI_OP_SET_EXTENDED_ADVERTISING, mgmt_set_extended_advertising, sizeof(struct hci_cp_set_extended_advertising), false },
{ HCI_OP_SET_EXT_ADV_DATA, mgmt_set_ext_adv_data, sizeof(struct hci_cp_set_ext_adv_data), true },
{ HCI_OP_SET_EXT_SCAN_RSP_DATA, mgmt_set_ext_scan_rsp_data, sizeof(struct hci_cp_set_ext_scan_rsp_data), true },
{ HCI_OP_SET_EXT_ADV_PARAMS, mgmt_set_ext_adv_params, sizeof(struct hci_cp_set_ext_adv_params), false },
{ HCI_OP_SET_EXT_SCAN_PARAMS, mgmt_set_ext_scan_params, sizeof(struct hci_cp_set_ext_scan_params), false },
{ HCI_OP_SET_EXT_SCAN_ENABLE, mgmt_set_ext_scan_enable, sizeof(struct hci_cp_set_ext_scan_enable), false },
{ HCI_OP_READ_EXT_INFO, mgmt_read_ext_info, sizeof(struct hci_rp_read_ext_info), false },
{ HCI_OP_READ_ADV_FEATURES, mgmt_read_adv_features, sizeof(struct hci_rp_read_adv_features), false },
{ HCI_OP_SET_WIDEBAND_SPEECH, mgmt_set_wideband_speech, sizeof(struct hci_cp_set_wideband_speech), false },
};
2. 核心组件实现
2.1 D-Bus IPC通信机制
D-Bus架构集成
// BlueZ D-Bus接口定义
static const GDBusMethodTable adapter_methods[] = {
{ GDBUS_ASYNC_METHOD("StartDiscovery", NULL, NULL, adapter_start_discovery) },
{ GDBUS_ASYNC_METHOD("StopDiscovery", NULL, NULL, adapter_stop_discovery) },
{ GDBUS_ASYNC_METHOD("RemoveDevice", GDBUS_ARGS({ "device", "o" }), NULL, adapter_remove_device) },
{ GDBUS_ASYNC_METHOD("SetDiscoveryFilter", GDBUS_ARGS({ "filter", "a{sv}" }), NULL, adapter_set_discovery_filter) },
{ GDBUS_ASYNC_METHOD("GetDiscoveryFilters", NULL, GDBUS_ARGS({ "filters", "as" }), adapter_get_discovery_filters) },
{ GDBUS_ASYNC_METHOD("StartServiceDiscovery", GDBUS_ARGS({ "pattern", "s" }, { "recs", "a{uu}" }), NULL, adapter_start_service_discovery) },
{ GDBUS_ASYNC_METHOD("StopServiceDiscovery", NULL, NULL, adapter_stop_service_discovery) },
{ GDBUS_ASYNC_METHOD("SetRSSIReader", GDBUS_ARGS({ "rssi", "n" }), NULL, adapter_set_rssi_reader) },
{ GDBUS_ASYNC_METHOD("SetTXPowerReader", GDBUS_ARGS({ "tx_power", "n" }), NULL, adapter_set_tx_power_reader) },
{ GDBUS_ASYNC_METHOD("SetUUIDReader", GDBUS_ARGS({ "uuid", "s" }), NULL, adapter_set_uuid_reader) },
{ GDBUS_ASYNC_METHOD("SetModaliasReader", GDBUS_ARGS({ "modalias", "s" }), NULL, adapter_set_modalias_reader) },
{ GDBUS_ASYNC_METHOD("SetManufacturerDataReader", GDBUS_ARGS({ "manufacturer_data", "a{qv}" }), NULL, adapter_set_manufacturer_data_reader) },
{ GDBUS_ASYNC_METHOD("SetServiceDataReader", GDBUS_ARGS({ "service_data", "a{sv}" }), NULL, adapter_set_service_data_reader) },
{ GDBUS_ASYNC_METHOD("SetDataReader", GDBUS_ARGS({ "data", "ay" }), NULL, adapter_set_data_reader) },
{ GDBUS_ASYNC_METHOD("SetDiscoveryTimeout", GDBUS_ARGS({ "timeout", "u" }), NULL, adapter_set_discovery_timeout) },
{ GDBUS_ASYNC_METHOD("SetName", GDBUS_ARGS({ "name", "s" }), NULL, adapter_set_name) },
{ GDBUS_ASYNC_METHOD("SetAlias", GDBUS_ARGS({ "alias", "s" }), NULL, adapter_set_alias) },
{ GDBUS_ASYNC_METHOD("SetClass", GDBUS_ARGS({ "class", "u" }), NULL, adapter_set_class) },
{ GDBUS_ASYNC_METHOD("SetPowered", GDBUS_ARGS({ "powered", "b" }), NULL, adapter_set_powered) },
{ GDBUS_ASYNC_METHOD("SetDiscoverable", GDBUS_ARGS({ "discoverable", "b" }), NULL, adapter_set_discoverable) },
{ GDBUS_ASYNC_METHOD("SetDiscoverableTimeout", GDBUS_ARGS({ "timeout", "u" }), NULL, adapter_set_discoverable_timeout) },
{ GDBUS_ASYNC_METHOD("SetPairable", GDBUS_ARGS({ "pairable", "b" }), NULL, adapter_set_pairable) },
{ GDBUS_ASYNC_METHOD("SetPairableTimeout", GDBUS_ARGS({ "timeout", "u" }), NULL, adapter_set_pairable_timeout) },
{ GDBUS_ASYNC_METHOD("SetDeviceClass", GDBUS_ARGS({ "major", "q" }, { "minor", "q" }), NULL, adapter_set_device_class) },
{ GDBUS_ASYNC_METHOD("SetServiceClasses", GDBUS_ARGS({ "classes", "a{uv}" }), NULL, adapter_set_service_classes) },
{ GDBUS_ASYNC_METHOD("SetUUIDs", GDBUS_ARGS({ "uuids", "as" }), NULL, adapter_set_uuids) },
{ GDBUS_ASYNC_METHOD("SetModalias", GDBUS_ARGS({ "modalias", "s" }), NULL, adapter_set_modalias) },
{ GDBUS_ASYNC_METHOD("SetManufacturerData", GDBUS_ARGS({ "manufacturer_data", "a{qv}" }), NULL, adapter_set_manufacturer_data) },
{ GDBUS_ASYNC_METHOD("SetServiceData", GDBUS_ARGS({ "service_data", "a{sv}" }), NULL, adapter_set_service_data) },
{ GDBUS_ASYNC_METHOD("SetData", GDBUS_ARGS({ "data", "ay" }), NULL, adapter_set_data) },
{ GDBUS_ASYNC_METHOD("SetExternalConfig", GDBUS_ARGS({ "config", "b" }), NULL, adapter_set_external_config) },
{ GDBUS_ASYNC_METHOD("SetPublicAddress", GDBUS_ARGS({ "address", "s" }), NULL, adapter_set_public_address) },
{ GDBUS_ASYNC_METHOD("SetStaticAddress", GDBUS_ARGS({ "address", "s" }), NULL, adapter_set_static_address) },
{ GDBUS_ASYNC_METHOD("SetPrivacy", GDBUS_ARGS({ "privacy", "b" }), NULL, adapter_set_privacy) },
{ GDBUS_ASYNC_METHOD("SetLEAdvertising", GDBUS_ARGS({ "advertising", "b" }), NULL, adapter_set_le_advertising) },
{ GDBUS_ASYNC_METHOD("SetLEAdvertisingParams", GDBUS_ARGS({ "params", "a{sv}" }), NULL, adapter_set_le_advertising_params) },
{ GDBUS_ASYNC_METHOD("SetLEAdvertisingData", GDBUS_ARGS({ "data", "ay" }), NULL, adapter_set_le_advertising_data) },
{ GDBUS_ASYNC_METHOD("SetLEScanResponseData", GDBUS_ARGS({ "data", "ay" }), NULL, adapter_set_le_scan_response_data) },
{ GDBUS_ASYNC_METHOD("SetLEScanParams", GDBUS_ARGS({ "params", "a{sv}" }), NULL, adapter_set_le_scan_params) },
{ GDBUS_ASYNC_METHOD("SetLEScanEnable", GDBUS_ARGS({ "enable", "b" }), NULL, adapter_set_le_scan_enable) },
{ GDBUS_ASYNC_METHOD("SetLEWhitelist", GDBUS_ARGS({ "devices", "a{sv}" }), NULL, adapter_set_le_whitelist) },
{ GDBUS_ASYNC_METHOD("SetLEResolveList", GDBUS_ARGS({ "devices", "a{sv}" }), NULL, adapter_set_le_resolve_list) },
{ GDBUS_ASYNC_METHOD("SetLEPrivacy", GDBUS_ARGS({ "privacy", "b" }), NULL, adapter_set_le_privacy) },
{ GDBUS_ASYNC_METHOD("SetLESecurity", GDBUS_ARGS({ "security", "b" }), NULL, adapter_set_le_security) },
{ GDBUS_ASYNC_METHOD("SetLEConnectionParams", GDBUS_ARGS({ "params", "a{sv}" }), NULL, adapter_set_le_connection_params) },
{ GDBUS_ASYNC_METHOD("SetLEConnectionSecurity", GDBUS_ARGS({ "security", "b" }), NULL, adapter_set_le_connection_security) },
{ GDBUS_ASYNC_METHOD("SetLEConnectionPrivacy", GDBUS_ARGS({ "privacy", "b" }), NULL, adapter_set_le_connection_privacy) },
{ GDBUS_ASYNC_METHOD("SetLEConnectionMTU", GDBUS_ARGS({ "mtu", "q" }), NULL, adapter_set_le_connection_mtu) },
{ GDBUS_ASYNC_METHOD("SetLEConnectionLatency", GDBUS_ARGS({ "latency", "q" }), NULL, adapter_set_le_connection_latency) },
{ GDBUS_ASYNC_METHOD("SetLEConnectionTimeout", GDBUS_ARGS({ "timeout", "q" }), NULL, adapter_set_le_connection_timeout) },
{ GDBUS_ASYNC_METHOD("SetLEConnectionInterval", GDBUS_ARGS({ "interval", "q" }), NULL, adapter_set_le_connection_interval) },
{ GDBUS_ASYNC_METHOD("SetLEConnectionSlaveLatency", GDBUS_ARGS({ "latency", "q" }), NULL, adapter_set_le_connection_slave_latency) },
{ GDBUS_ASYNC_METHOD("SetLEConnectionSupervisionTimeout", GDBUS_ARGS({ "timeout", "q" }), NULL, adapter_set_le_connection_supervision_timeout) },
{ }
};
D-Bus到内核的映射
// D-Bus方法到内核HCI命令的映射
static void adapter_set_powered(GDBusMethodInvocation *invocation,
GVariant *parameters)
{
struct btd_adapter *adapter = g_dbus_method_invocation_get_user_data(invocation);
gboolean powered;
int err;
g_variant_get(parameters, "(b)", &powered);
// 转换为HCI命令
if (powered) {
err = adapter_ops->set_powered(adapter->dev_id, 1);
} else {
err = adapter_ops->set_powered(adapter->dev_id, 0);
}
if (err < 0) {
g_dbus_method_invocation_return_error_literal(invocation,
ERROR_INTERFACE ".Failed", "Failed to set powered");
return;
}
// 更新属性
adapter->powered = powered;
g_dbus_emit_property_changed(btd_get_dbus_connection(),
adapter->path, ADAPTER_INTERFACE, "Powered");
g_dbus_method_invocation_return_value(invocation, NULL);
}
2.2 蓝牙协议栈内核实现细节
HCI层核心实现
// HCI核心初始化
static int __init hci_init(void)
{
int err;
// 注册HCI Socket协议
err = hci_sock_init();
if (err < 0)
return err;
// 注册HCI设备驱动
err = hci_register_sysfs();
if (err < 0) {
hci_sock_cleanup();
return err;
}
// 注册管理接口
err = mgmt_init();
if (err < 0) {
hci_unregister_sysfs();
hci_sock_cleanup();
return err;
}
// 注册debugfs接口
hci_debugfs_init();
return 0;
}
// HCI命令处理
static int hci_send_cmd(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_command_hdr *hdr = (void *) skb->data;
int err;
// 验证HCI设备状态
if (!hdev_is_powered(hdev)) {
kfree_skb(skb);
return -ENETDOWN;
}
// 检查命令是否支持
if (!hci_command_supported(hdev, hdr->opcode)) {
kfree_skb(skb);
return -EOPNOTSUPP;
}
// 添加到命令队列
skb_queue_tail(&hdev->cmd_q, skb);
queue_work(hdev->workqueue, &hdev->cmd_work);
return 0;
}
// HCI命令工作队列
static void hci_cmd_work(struct work_struct *work)
{
struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work);
struct sk_buff *skb;
// 处理命令队列
while ((skb = skb_dequeue(&hdev->cmd_q))) {
struct hci_command_hdr *hdr = (void *) skb->data;
int err;
// 检查命令数量限制
if (atomic_read(&hdev->cmd_cnt) >= hdev->cmd_max) {
skb_queue_head(&hdev->cmd_q, skb);
break;
}
// 发送命令到硬件
err = hci_send_frame(hdev, skb);
if (err < 0) {
kfree_skb(skb);
continue;
}
// 增加命令计数
atomic_inc(&hdev->cmd_cnt);
// 设置命令超时
mod_timer(&hdev->cmd_timer, jiffies + HCI_CMD_TIMEOUT);
}
}
L2CAP层实现
// L2CAP核心结构
struct l2cap_chan {
struct list_head list;
atomic_t refcnt;
// 通道标识
struct l2cap_conn *conn; // L2CAP连接
__u16 scid; // 源通道ID
__u16 dcid; // 目的通道ID
__u16 psm; // 协议服务多路复用器
// 通道状态
__u8 state; // 通道状态
__u8 mode; // 通道模式
__u8 ident; // 标识符
__u8 type; // 通道类型
// 配置参数
__u16 imtu; // 输入MTU
__u16 omtu; // 输出MTU
__u8 sec_level; // 安全级别
// QoS参数
struct l2cap_qos qos; // QoS设置
// 流量控制
__u16 tx_win; // 发送窗口
__u16 rx_win; // 接收窗口
__u16 tx_max; // 最大发送
__u16 rx_max; // 最大接收
// 重传机制
__u8 retrans_effort; // 重传努力程度
__u16 monitor_timeout; // 监控超时
__u16 retrans_timeout; // 重传超时
// 数据缓冲
struct sk_buff_head tx_q; // 发送队列
struct sk_buff_head rx_q; // 接收队列
// 工作队列
work_struct_work; // 工作队列
// 回调函数
void (*state_change)(struct l2cap_chan *chan, int state);
void (*recv)(struct l2cap_chan *chan, struct sk_buff *skb);
void (*close)(struct l2cap_chan *chan);
// 私有数据
void *data; // 私有数据
};
// L2CAP数据包接收
static int l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
{
struct l2cap_hdr *hdr = (struct l2cap_hdr *) skb->data;
__u16 cid, len;
int err;
// 验证最小长度
if (skb->len < L2CAP_HDR_SIZE)
return -EINVAL;
// 解析L2CAP头
cid = __le16_to_cpu(hdr->cid);
len = __le16_to_cpu(hdr->len);
// 验证数据长度
if (skb->len - L2CAP_HDR_SIZE < len)
return -EINVAL;
// 调整数据指针
skb_pull(skb, L2CAP_HDR_SIZE);
skb_trim(skb, len);
// 根据CID分发到不同处理函数
switch (cid) {
case L2CAP_CID_SIGNALING:
err = l2cap_sig_channel(conn, skb);
break;
case L2CAP_CID_CONN_LESS:
err = l2cap_connless_channel(conn, skb);
break;
case L2CAP_CID_LE_SIGNALING:
err = l2cap_le_sig_channel(conn, skb);
break;
case L2CAP_CID_SMP:
err = l2cap_smp_channel(conn, skb);
break;
default:
err = l2cap_data_channel(conn, cid, skb);
break;
}
return err;
}
// L2CAP信号通道处理
static int l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
{
struct l2cap_sig_hdr *hdr = (struct l2cap_sig_hdr *) skb->data;
__u16 code, ident, len;
int err = 0;
// 解析信号头
code = hdr->code;
ident = hdr->ident;
len = __le16_to_cpu(hdr->len);
// 调整数据指针
skb_pull(skb, L2CAP_SIG_HDR_SIZE);
// 根据信号代码处理
switch (code) {
case L2CAP_CONN_REQ:
err = l2cap_connect_req(conn, ident, skb);
break;
case L2CAP_CONN_RSP:
err = l2cap_connect_rsp(conn, ident, skb);
break;
case L2CAP_CONF_REQ:
err = l2cap_config_req(conn, ident, skb);
break;
case L2CAP_CONF_RSP:
err = l2cap_config_rsp(conn, ident, skb);
break;
case L2CAP_DISCONN_REQ:
err = l2cap_disconnect_req(conn, ident, skb);
break;
case L2CAP_DISCONN_RSP:
err = l2cap_disconnect_rsp(conn, ident, skb);
break;
case L2CAP_ECHO_REQ:
err = l2cap_echo_req(conn, ident, skb);
break;
case L2CAP_ECHO_RSP:
err = l2cap_echo_rsp(conn, ident, skb);
break;
case L2CAP_INFO_REQ:
err = l2cap_info_req(conn, ident, skb);
break;
case L2CAP_INFO_RSP:
err = l2cap_info_rsp(conn, ident, skb);
break;
default:
err = l2cap_send_cmd(conn, ident, L2CAP_COMMAND_REJECT,
sizeof(struct l2cap_cmd_rej), &reject);
break;
}
return err;
}
2.3 设备管理机制
设备发现与扫描
// 设备发现机制
static int hci_inquiry(struct hci_dev *hdev, u8 length)
{
struct hci_cp_inquiry cp;
struct hci_request req;
int err;
// 验证设备状态
if (!hdev_is_powered(hdev))
return -ENETDOWN;
// 设置查询参数
bacpy(&cp.bdaddr, BDADDR_ANY);
cp.pscan_rep_mode = 0x02;
cp.pscan_period_mode = 0x00;
cp.pscan_window = 0x00;
cp.length = length;
// 创建HCI请求
hci_req_init(&req, hdev);
hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp);
// 发送请求
err = hci_req_run(&req, hci_inquiry_complete);
if (err < 0)
return err;
// 设置查询状态
hci_dev_set_flag(hdev, HCI_INQUIRY);
return 0;
}
// 查询结果处理
static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
struct inquiry_info *info = (void *) (skb->data + 1);
int num_rsp = *((__u8 *) skb->data);
struct inquiry_data data;
int i;
// 处理每个查询结果
for (i = 0; i < num_rsp; i++) {
bdaddr_t bdaddr;
__u8 pscan_rep_mode;
bacpy(&bdaddr, &info[i].bdaddr);
pscan_rep_mode = info[i].pscan_rep_mode;
// 检查是否为新设备
if (!hci_inquiry_cache_update(hdev, &info[i], false))
continue;
// 创建查询数据
memset(&data, 0, sizeof(data));
bacpy(&data.bdaddr, &bdaddr);
data.pscan_rep_mode = pscan_rep_mode;
data.pscan_period_mode = info[i].pscan_period_mode;
data.pscan_mode = info[i].pscan_mode;
memcpy(data.dev_class, info[i].dev_class, 3);
data.clock_offset = info[i].clock_offset;
data.rssi = info[i].rssi;
data.ssp_mode = 0x00;
// 通知管理接口
mgmt_device_found(hdev, &bdaddr, HCI_SCAN_INQUIRY,
info[i].dev_class, pscan_rep_mode,
pscan_period_mode, pscan_mode,
info[i].clock_offset, info[i].rssi,
NULL, 0, NULL, 0, 0x00);
}
}
服务发现协议(SDP)
// SDP会话管理
struct sdp_session {
struct list_head list;
struct l2cap_chan *chan; // L2CAP通道
// 会话状态
__u32 state; // 会话状态
__u32 flags; // 会话标志
// 请求队列
struct list_head req_queue; // 请求队列
struct list_head rsp_queue; // 响应队列
// 超时处理
struct timer_list timer; // 会话定时器
// 回调函数
void (*callback)(struct sdp_session *session, int status);
void *priv; // 私有数据
};
// SDP查询实现
static int sdp_search(struct sdp_session *session, const bdaddr_t *bdaddr,
const uuid_t *uuid, u16 attr, sdp_list_t **rsp)
{
struct sdp_search_req req;
struct sk_buff *skb;
int err;
// 验证会话状态
if (session->state != SDP_STATE_CONNECTED)
return -ENOTCONN;
// 构建搜索请求
memset(&req, 0, sizeof(req));
req.psm = cpu_to_be16(SDP_PSM);
req.tid = cpu_to_be16(session->tid++);
req.len = cpu_to_be16(sizeof(req) - sizeof(req.len));
// 设置UUID列表
req.uuid_len = uuid_to_data(uuid, req.uuid);
// 设置属性ID列表
req.attr_len = sdp_data_seq(&req.attr, sizeof(req.attr), attr);
// 分配sk_buff
skb = bt_skb_alloc(sizeof(req), GFP_KERNEL);
if (!skb)
return -ENOMEM;
// 复制请求数据
memcpy(skb_put(skb, sizeof(req)), &req, sizeof(req));
// 发送请求
err = l2cap_chan_send(session->chan, skb);
if (err < 0) {
kfree_skb(skb);
return err;
}
// 等待响应
err = wait_for_completion_timeout(&session->comp, SDP_TIMEOUT);
if (!err)
return -ETIMEDOUT;
// 处理响应
if (session->rsp_status)
return session->rsp_status;
*rsp = session->rsp_data;
session->rsp_data = NULL;
return 0;
}
2.4 安全机制实现
配对与认证
// 配对状态机
struct smp_chan {
struct l2cap_chan *chan; // L2CAP通道
struct hci_conn *hcon; // HCI连接
// 配对状态
__u8 state; // SMP状态
__u8 flags; // SMP标志
__u8 preq[7]; // 配对请求
__u8 prsp[7]; // 配对响应
__u8 tk[16]; // 临时密钥
__u8 prnd[16]; // 配对随机数
__u8 rrnd[16]; // 响应随机数
__u8 pcnf[16]; // 配对确认
__u8 rcnf[16]; // 响应确认
__u8 ltk[16]; // 长期密钥
__u8 csrk[16]; // 连接签名解析密钥
// 密钥派生
__u8 ir[16]; // 身份解析密钥
__u8 er[16]; // 加密根密钥
__u8 dhk[16]; // 多样化密钥
// 安全参数
__u8 io_capability; // IO能力
__u8 oob_flag; // OOB标志
__u8 auth_req; // 认证要求
__u8 max_key_size; // 最大密钥大小
// 工作队列
work_struct_work; // 工作队列
struct timer_list timer; // 定时器
};
// SMP配对流程
static int smp_pair(struct smp_chan *smp)
{
struct hci_conn *hcon = smp->hcon;
int err;
// 验证连接状态
if (hcon->state != BT_CONNECTED)
return -ENOTCONN;
// 设置配对状态
smp->state = SMP_STATE_PAIRING;
smp->flags = 0;
// 根据安全要求选择配对方法
if (smp->auth_req & SMP_AUTH_MITM) {
// 需要MITM保护,选择适当的配对方法
if (smp->io_capability == SMP_IO_KEYBOARD_DISPLAY) {
err = smp_passkey_entry(smp);
} else if (smp->io_capability == SMP_IO_DISPLAY_ONLY) {
err = smp_passkey_display(smp);
} else if (smp->io_capability == SMP_IO_KEYBOARD_ONLY) {
err = smp_passkey_entry(smp);
} else {
err = smp_just_works(smp);
}
} else {
// 不需要MITM保护,使用Just Works
err = smp_just_works(smp);
}
if (err < 0)
return err;
// 启动配对定时器
mod_timer(&smp->timer, jiffies + SMP_TIMEOUT);
return 0;
}
// 密钥派生函数
static int smp_derive_keys(struct smp_chan *smp)
{
struct hci_conn *hcon = smp->hcon;
u8 stk[16], ltk[16];
int err;
// 派生短期密钥(STK)
err = smp_f4(smp->tk, smp->prnd, smp->rrnd, 0, stk);
if (err)
return err;
// 派生长期密钥(LTK)
if (smp->auth_req & SMP_AUTH_BONDING) {
err = smp_f5(smp->tk, smp->prnd, smp->rrnd, smp->preq, smp->prsp,
hcon->dst_type, &hcon->dst, ltk);
if (err)
return err;
memcpy(smp->ltk, ltk, 16);
// 保存密钥到密钥存储
hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type,
hcon->role, smp->ltk, smp->ediv, smp->rand,
smp->key_size, smp->auth_req);
}
// 配置加密
err = hci_le_start_enc(hcon, smp->ediv, smp->rand, stk);
if (err)
return err;
return 0;
}
3. 关键流程分析
3.1 蓝牙设备初始化与配对流程
设备初始化流程
// HCI设备初始化流程
static int hci_dev_open(struct hci_dev *hdev)
{
int err;
// 验证设备状态
if (test_bit(HCI_UP, &hdev->flags))
return -EALREADY;
// 初始化硬件
err = hdev->open(hdev);
if (err)
return err;
// 设置设备标志
set_bit(HCI_UP, &hdev->flags);
// 读取设备信息
err = hci_read_local_version(hdev);
if (err)
goto err_close;
err = hci_read_local_features(hdev);
if (err)
goto err_close;
err = hci_read_buffer_size(hdev);
if (err)
goto err_close;
err = hci_read_bd_addr(hdev);
if (err)
goto err_close;
// 初始化默认参数
err = hci_init_setup(hdev);
if (err)
goto err_close;
// 通知管理接口
mgmt_index_added(hdev);
return 0;
err_close:
hdev->close(hdev);
clear_bit(HCI_UP, &hdev->flags);
return err;
}
// 初始化设置
static int hci_init_setup(struct hci_dev *hdev)
{
struct hci_cp_write_ssp_mode cp;
struct hci_cp_write_le_host_supported le_cp;
int err;
// 设置设备类别
if (hdev->dev_class != 0) {
err = hci_write_class_of_dev(hdev, hdev->dev_class);
if (err)
return err;
}
// 设置设备名称
if (hdev->dev_name[0]) {
err = hci_write_local_name(hdev, hdev->dev_name);
if (err)
return err;
}
// 设置简单安全配对
if (hdev->features[6] & LMP_SIMPLE_PAIR) {
cp.ssp_mode = 0x01;
err = hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, sizeof(cp), &cp);
if (err)
return err;
}
// 设置LE支持
if (hdev->features[4] & LMP_LE) {
le_cp.le = 0x01;
le_cp.simul = 0x00;
err = hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED,
sizeof(le_cp), &le_cp);
if (err)
return err;
}
// 设置默认链路策略
err = hci_write_default_link_policy(hdev, HCI_LP_RSWITCH |
HCI_LP_HOLD | HCI_LP_SNIFF);
if (err)
return err;
return 0;
}
配对流程实现
// 配对状态机
enum smp_state {
SMP_STATE_IDLE,
SMP_STATE_WAIT_TK,
SMP_STATE_WAIT_CFM,
SMP_STATE_WAIT_RAND,
SMP_STATE_WAIT_PAIRING,
SMP_STATE_WAIT_DHKEY,
SMP_STATE_WAIT_SIGN,
SMP_STATE_WAIT_AUTH,
SMP_STATE_WAIT_ENC,
SMP_STATE_COMPLETE,
};
// 配对请求处理
static int smp_pairing_req(struct smp_chan *smp, struct sk_buff *skb)
{
struct smp_cmd_pairing *req = (void *) skb->data;
struct smp_cmd_pairing rsp;
struct hci_conn *hcon = smp->hcon;
int err;
// 验证状态
if (smp->state != SMP_STATE_IDLE)
return -EBUSY;
// 保存配对请求
memcpy(smp->preq, req, sizeof(*req));
// 选择IO能力
smp->io_capability = smp_select_io_capability(smp);
// 构建配对响应
memset(&rsp, 0, sizeof(rsp));
rsp.io_capability = smp->io_capability;
rsp.oob_flag = smp->oob_flag;
rsp.auth_req = smp->auth_req;
rsp.max_key_size = smp->max_key_size;
rsp.init_key_dist = smp->init_key_dist;
rsp.resp_key_dist = smp->resp_key_dist;
// 发送配对响应
err = smp_send_cmd(smp, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp);
if (err)
return err;
// 保存配对响应
memcpy(smp->prsp, &rsp, sizeof(rsp));
// 选择配对方法
smp->method = smp_select_method(smp);
// 根据配对方法执行相应流程
switch (smp->method) {
case SMP_JUST_WORKS:
err = smp_just_works(smp);
break;
case SMP_PASSKEY_ENTRY:
err = smp_passkey_start(smp);
break;
case SMP_NUMERIC_COMPARISON:
err = smp_numeric_comparison(smp);
break;
case SMP_OOB:
err = smp_oob_start(smp);
break;
default:
err = -EOPNOTSUPP;
break;
}
if (err)
return err;
smp->state = SMP_STATE_WAIT_PAIRING;
return 0;
}
// 配对完成处理
static void smp_pairing_complete(struct smp_chan *smp, u8 status)
{
struct hci_conn *hcon = smp->hcon;
struct hci_dev *hdev = hcon->hdev;
// 更新连接安全级别
if (!status) {
hcon->sec_level = smp->sec_level;
hcon->link_mode |= HCI_LM_ENCRYPT;
// 派生密钥
if (smp->auth_req & SMP_AUTH_BONDING) {
smp_derive_keys(smp);
}
}
// 通知管理接口
mgmt_auth_complete(hdev, &hcon->dst, hcon->type, status);
// 清理SMP状态
smp->state = SMP_STATE_IDLE;
del_timer(&smp->timer);
}
3.2 数据包处理路径
HCI数据包处理流程
// HCI接收数据包主入口
static int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_event_hdr *ehdr;
int err;
// 验证数据包类型
if (!skb || skb->len < 1)
return -EINVAL;
// 根据数据包类型分发处理
switch (bt_cb(skb)->pkt_type) {
case HCI_EVENT_PKT:
// 事件数据包
ehdr = (struct hci_event_hdr *) skb->data;
if (skb->len < HCI_EVENT_HDR_SIZE) {
kfree_skb(skb);
return -EINVAL;
}
err = hci_event_packet(hdev, skb);
break;
case HCI_ACLDATA_PKT:
// ACL数据包
err = hci_acldata_packet(hdev, skb);
break;
case HCI_SCODATA_PKT:
// SCO数据包
err = hci_scodata_packet(hdev, skb);
break;
case HCI_VENDOR_PKT:
// 厂商特定数据包
err = hci_vendor_packet(hdev, skb);
break;
default:
// 未知数据包类型
kfree_skb(skb);
err = -EINVAL;
break;
}
return err;
}
// ACL数据包处理
static int hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_acl_hdr *hdr = (struct hci_acl_hdr *) skb->data;
struct hci_conn *conn;
__u16 handle, flags;
int err;
// 验证数据包长度
if (skb->len < HCI_ACL_HDR_SIZE) {
kfree_skb(skb);
return -EINVAL;
}
// 解析ACL头
handle = __le16_to_cpu(hdr->handle);
flags = hci_flags(handle);
handle = hci_handle(handle);
// 查找连接
conn = hci_conn_hash_lookup_handle(hdev, handle);
if (!conn) {
kfree_skb(skb);
return -ENOENT;
}
// 验证连接状态
if (conn->state != BT_CONNECTED) {
kfree_skb(skb);
return -ENOTCONN;
}
// 调整数据指针
skb_pull(skb, HCI_ACL_HDR_SIZE);
// 根据标志处理数据包
switch (flags) {
case ACL_CONT:
// 继续数据包
err = hci_reassembly_data(conn, skb);
break;
case ACL_START:
// 开始数据包
err = hci_process_frame(conn, skb);
break;
default:
kfree_skb(skb);
err = -EINVAL;
break;
}
return err;
}
// L2CAP数据处理
static int hci_process_frame(struct hci_conn *conn, struct sk_buff *skb)
{
struct l2cap_hdr *hdr = (struct l2cap_hdr *) skb->data;
__u16 len, cid;
int err;
// 验证L2CAP头
if (skb->len < L2CAP_HDR_SIZE) {
kfree_skb(skb);
return -EINVAL;
}
// 解析L2CAP头
len = __le16_to_cpu(hdr->len);
cid = __le16_to_cpu(hdr->cid);
// 验证数据长度
if (skb->len - L2CAP_HDR_SIZE < len) {
kfree_skb(skb);
return -EINVAL;
}
// 调整数据长度
skb_trim(skb, len + L2CAP_HDR_SIZE);
// 分发到L2CAP层
err = l2cap_recv_frame(conn, skb);
if (err < 0) {
kfree_skb(skb);
return err;
}
return 0;
}
3.3 电源管理与低功耗机制
电源状态管理
// 电源状态枚举
enum hci_power_state {
HCI_POWER_OFF,
HCI_POWER_ON,
HCI_POWER_SUSPENDED,
};
// 电源管理实现
static int hci_set_powered(struct hci_dev *hdev, u8 powered)
{
int err;
// 验证当前状态
if (test_bit(HCI_POWERED, &hdev->flags) == powered)
return 0;
if (powered) {
// 打开设备
err = hci_dev_open(hdev);
if (err)
return err;
// 设置电源标志
set_bit(HCI_POWERED, &hdev->flags);
// 恢复之前的设置
if (hdev->discov_timeout > 0)
hci_dev_set_flag(hdev, HCI_LIMITED_DISCOVERABLE);
if (hdev->scan_type == SCAN_PAGE)
hci_dev_set_flag(hdev, HCI_CONNECTABLE);
else if (hdev->scan_type == SCAN_INQUIRY)
hci_dev_set_flag(hdev, HCI_DISCOVERABLE);
// 启动周期性查询
if (hdev->discovery.timeout > 0)
queue_work(hdev->workqueue, &hdev->discov_update);
} else {
// 停止所有活动
hci_dev_stop_discovery(hdev);
hci_dev_stop_le_discovery(hdev);
hci_conn_hash_flush(hdev);
hci_inquiry_cache_flush(hdev);
// 关闭设备
hci_dev_close(hdev);
// 清除电源标志
clear_bit(HCI_POWERED, &hdev->flags);
}
// 通知管理接口
mgmt_powered(hdev, powered);
return 0;
}
// 省电模式实现
static void hci_pm_suspend(struct hci_dev *hdev)
{
// 停止发现
hci_dev_stop_discovery(hdev);
hci_dev_stop_le_discovery(hdev);
// 断开非关键连接
hci_conn_hash_suspend(hdev);
// 设置挂起状态
set_bit(HCI_SUSPENDED, &hdev->flags);
// 通知驱动
if (hdev->suspend)
hdev->suspend(hdev);
}
static void hci_pm_resume(struct hci_dev *hdev)
{
// 清除挂起状态
clear_bit(HCI_SUSPENDED, &hdev->flags);
// 通知驱动
if (hdev->resume)
hdev->resume(hdev);
// 恢复连接
hci_conn_hash_resume(hdev);
// 恢复发现状态
if (hdev->discovery.enable)
queue_work(hdev->workqueue, &hdev->discov_update);
}
低功耗蓝牙(LE)电源管理
// LE电源管理参数
struct le_power_params {
__u16 conn_interval_min; // 最小连接间隔
__u16 conn_interval_max; // 最大连接间隔
__u16 conn_latency; // 连接延迟
__u16 supervision_timeout; // 监督超时
__u16 min_ce_len; // 最小连接事件长度
__u16 max_ce_len; // 最大连接事件长度
};
// LE连接参数更新
static int le_conn_param_update(struct hci_conn *hcon,
struct le_power_params *params)
{
struct hci_cp_le_conn_update cp;
struct hci_request req;
int err;
// 验证连接类型
if (hcon->type != LE_LINK)
return -EINVAL;
// 验证连接状态
if (hcon->state != BT_CONNECTED)
return -ENOTCONN;
// 填充连接更新参数
cp.handle = cpu_to_le16(hcon->handle);
cp.conn_interval_min = cpu_to_le16(params->conn_interval_min);
cp.conn_interval_max = cpu_to_le16(params->conn_interval_max);
cp.conn_latency = cpu_to_le16(params->conn_latency);
cp.supervision_timeout = cpu_to_le16(params->supervision_timeout);
cp.min_ce_len = cpu_to_le16(params->min_ce_len);
cp.max_ce_len = cpu_to_le16(params->max_ce_len);
// 创建HCI请求
hci_req_init(&req, hcon->hdev);
hci_req_add(&req, HCI_OP_LE_CONN_UPDATE, sizeof(cp), &cp);
// 发送请求
err = hci_req_run(&req, le_conn_update_complete);
if (err < 0)
return err;
return 0;
}
// LE广播电源优化
static int le_set_advertising_params(struct hci_dev *hdev,
struct le_power_params *params)
{
struct hci_cp_le_set_adv_params cp;
int err;
// 验证设备状态
if (!hdev_is_powered(hdev))
return -ENETDOWN;
// 填充广播参数
cp.min_interval = cpu_to_le16(params->adv_interval_min);
cp.max_interval = cpu_to_le16(params->adv_interval_max);
cp.type = params->adv_type;
cp.own_addr_type = params->own_addr_type;
cp.direct_addr_type = params->direct_addr_type;
bacpy(&cp.direct_addr, ¶ms->direct_addr);
cp.channel_map = params->channel_map;
cp.filter_policy = params->filter_policy;
// 发送命令
err = hci_send_cmd(hdev, HCI_OP_LE_SET_ADV_PARAMS, sizeof(cp), &cp);
if (err < 0)
return err;
return 0;
}
4. 性能优化
4.1 协议栈性能瓶颈分析
数据路径性能分析
// 性能统计结构
struct hci_stats {
atomic_t cmd_tx; // 命令发送计数
atomic_t cmd_rx; // 命令接收计数
atomic_t cmd_err; // 命令错误计数
atomic_t acl_tx; // ACL数据发送计数
atomic_t acl_rx; // ACL数据接收计数
atomic_t acl_drop; // ACL数据丢弃计数
atomic_t sco_tx; // SCO数据发送计数
atomic_t sco_rx; // SCO数据接收计数
atomic_t le_tx; // LE数据发送计数
atomic_t le_rx; // LE数据接收计数
atomic_t le_drop; // LE数据丢弃计数
// 时间统计
u64 cmd_latency; // 命令延迟
u64 acl_latency; // ACL数据延迟
u64 le_latency; // LE数据延迟
// 吞吐量统计
u64 acl_throughput; // ACL吞吐量
u64 le_throughput; // LE吞吐量
};
// 性能监控实现
static void hci_update_stats(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_stats *stats = &hdev->stats;
ktime_t now = ktime_get();
switch (bt_cb(skb)->pkt_type) {
case HCI_EVENT_PKT:
atomic_inc(&stats->cmd_rx);
if (stats->last_cmd_tx) {
stats->cmd_latency = ktime_to_ns(ktime_sub(now, stats->last_cmd_tx));
stats->last_cmd_tx = 0;
}
break;
case HCI_ACLDATA_PKT:
atomic_inc(&stats->acl_rx);
if (stats->last_acl_tx) {
stats->acl_latency = ktime_to_ns(ktime_sub(now, stats->last_acl_tx));
stats->last_acl_tx = 0;
}
// 更新吞吐量统计
stats->acl_throughput += skb->len;
break;
case HCI_SCODATA_PKT:
atomic_inc(&stats->sco_rx);
break;
case HCI_VENDOR_PKT:
atomic_inc(&stats->le_rx);
if (stats->last_le_tx) {
stats->le_latency = ktime_to_ns(ktime_sub(now, stats->last_le_tx));
stats->last_le_tx = 0;
}
// 更新吞吐量统计
stats->le_throughput += skb->len;
break;
}
}
// 零拷贝传输优化
static int hci_zero_copy_send(struct hci_dev *hdev, struct sk_buff *skb)
{
struct sk_buff *frag;
int err;
// 检查是否支持零拷贝
if (!hdev->driver->send_skb)
return -EOPNOTSUPP;
// 验证数据包完整性
if (!skb || skb->len == 0)
return -EINVAL;
// 处理分片数据包
if (skb_shinfo(skb)->nr_frags > 0) {
// 使用DMA映射处理分片
err = hci_map_skb_frags(hdev, skb);
if (err)
return err;
}
// 直接发送,避免数据复制
err = hdev->driver->send_skb(hdev, skb);
if (err) {
// 发送失败,取消DMA映射
if (skb_shinfo(skb)->nr_frags > 0)
hci_unmap_skb_frags(hdev, skb);
return err;
}
return 0;
}
// DMA映射优化
static int hci_map_skb_frags(struct hci_dev *hdev, struct sk_buff *skb)
{
struct skb_shared_info *shinfo = skb_shinfo(skb);
struct hci_dma_mapping *mapping;
int i;
// 分配DMA映射结构
mapping = kzalloc(sizeof(*mapping) + sizeof(dma_addr_t) * shinfo->nr_frags, GFP_KERNEL);
if (!mapping)
return -ENOMEM;
// 映射每个分片
for (i = 0; i < shinfo->nr_frags; i++) {
skb_frag_t *frag = &shinfo->frags[i];
dma_addr_t dma_addr;
dma_addr = dma_map_page(hdev->dma_dev, skb_frag_page(frag),
skb_frag_off(frag), skb_frag_size(frag),
DMA_TO_DEVICE);
if (dma_mapping_error(hdev->dma_dev, dma_addr)) {
// 映射失败,回滚
while (--i >= 0) {
frag = &shinfo->frags[i];
dma_unmap_page(hdev->dma_dev, mapping->dma_addrs[i],
skb_frag_size(frag), DMA_TO_DEVICE);
}
kfree(mapping);
return -EIO;
}
mapping->dma_addrs[i] = dma_addr;
}
// 保存映射信息
mapping->nr_frags = shinfo->nr_frags;
skb->cb[0] = (unsigned char)mapping;
return 0;
}
### 4.2 实时性保障机制
// 实时调度优化
static int hci_set_realtime_priority(struct hci_dev *hdev)
{
struct sched_param param = {
.sched_priority = MAX_RT_PRIO - 1,
};
int err;
// 设置工作队列线程为实时优先级
err = sched_setscheduler(hdev->workqueue->task->pid, SCHED_FIFO, ¶m);
if (err)
return err;
// 设置中断处理线程为实时优先级
if (hdev->irq_thread) {
param.sched_priority = MAX_RT_PRIO - 2;
err = sched_setscheduler(hdev->irq_thread->pid, SCHED_FIFO, ¶m);
if (err)
return err;
}
return 0;
}
// 低延迟路径优化
static inline int hci_fast_path(struct hci_dev *hdev, struct sk_buff *skb)
{
// 检查是否可以使用快速路径
if (likely(hdev->fast_path_enabled &&
skb_queue_empty(&hdev->rx_q) &&
!test_bit(HCI_SUSPENDED, &hdev->flags))) {
// 直接处理,绕过工作队列
return hci_process_fast(hdev, skb);
}
// 使用标准路径
return hci_process_normal(hdev, skb);
}
### 4.3 内存管理优化
// 内存池管理
struct hci_mempool {
struct kmem_cache *cache;
mempool_t *pool;
size_t obj_size;
size_t pool_size;
};
static int hci_mempool_init(struct hci_dev *hdev)
{
// 初始化ACL数据包内存池
hdev->acl_pool.cache = kmem_cache_create("hci_acl_skb",
HCI_ACL_MAX_SIZE,
0, SLAB_HWCACHE_ALIGN,
NULL);
if (!hdev->acl_pool.cache)
return -ENOMEM;
hdev->acl_pool.pool = mempool_create_slab_pool(128, hdev->acl_pool.cache);
if (!hdev->acl_pool.pool) {
kmem_cache_destroy(hdev->acl_pool.cache);
return -ENOMEM;
}
// 初始化LE数据包内存池
hdev->le_pool.cache = kmem_cache_create("hci_le_skb",
HCI_LE_MAX_SIZE,
0, SLAB_HWCACHE_ALIGN,
NULL);
if (!hdev->le_pool.cache) {
mempool_destroy(hdev->acl_pool.pool);
kmem_cache_destroy(hdev->acl_pool.cache);
return -ENOMEM;
}
hdev->le_pool.pool = mempool_create_slab_pool(64, hdev->le_pool.cache);
if (!hdev->le_pool.pool) {
kmem_cache_destroy(hdev->le_pool.cache);
mempool_destroy(hdev->acl_pool.pool);
kmem_cache_destroy(hdev->acl_pool.cache);
return -ENOMEM;
}
return 0;
}
// 快速内存分配
static struct sk_buff *hci_mempool_alloc(struct hci_mempool *mempool, gfp_t gfp_mask)
{
struct sk_buff *skb;
// 从内存池分配
skb = mempool_alloc(mempool->pool, gfp_mask);
if (!skb)
return NULL;
// 初始化sk_buff
skb->head = (void *)skb + sizeof(struct sk_buff);
skb->data = skb->head;
skb->tail = skb->data;
skb->end = skb->head + mempool->obj_size;
return skb;
}
## 5. 调试与开发
### 5.1 底层调试接口
#### Debugfs接口实现
```c
// Debugfs根目录
static struct dentry *bt_debugfs;
// HCI设备debugfs接口
static int hci_debugfs_init(struct hci_dev *hdev)
{
char name[64];
struct dentry *dir;
// 创建设备特定目录
snprintf(name, sizeof(name), "hci%d", hdev->id);
dir = debugfs_create_dir(name, bt_debugfs);
if (!dir)
return -ENOMEM;
hdev->debugfs = dir;
// 创建调试文件
debugfs_create_file("commands", 0444, dir, hdev, &hci_cmds_fops);
debugfs_create_file("events", 0444, dir, hdev, &hci_events_fops);
debugfs_create_file("acl_data", 0444, dir, hdev, &hci_acl_fops);
debugfs_create_file("sco_data", 0444, dir, hdev, &hci_sco_fops);
debugfs_create_file("le_data", 0444, dir, hdev, &hci_le_fops);
debugfs_create_file("connections", 0444, dir, hdev, &hci_conn_fops);
debugfs_create_file("keys", 0400, dir, hdev, &hci_keys_fops);
debugfs_create_file("power", 0644, dir, hdev, &hci_power_fops);
debugfs_create_file("scan", 0644, dir, hdev, &hci_scan_fops);
debugfs_create_file("discov", 0644, dir, hdev, &hci_discov_fops);
debugfs_create_file("secmgr", 0644, dir, hdev, &hci_sec_fops);
debugfs_create_file("features", 0444, dir, hdev, &hci_features_fops);
debugfs_create_u32("debug_mask", 0644, dir, &hdev->debug_mask);
return 0;
}
// 命令调试文件操作
static const struct file_operations hci_cmds_fops = {
.open = hci_cmds_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int hci_cmds_open(struct inode *inode, struct file *file)
{
return single_open(file, hci_cmds_show, inode->i_private);
}
static int hci_cmds_show(struct seq_file *f, void *ptr)
{
struct hci_dev *hdev = f->private;
struct hci_command *cmd;
int i;
seq_puts(f, "HCI Commands:\n");
seq_puts(f, "=============\n");
for (i = 0; i < HCI_MAX_COMMANDS; i++) {
cmd = &hdev->commands[i];
if (cmd->opcode == 0)
continue;
seq_printf(f, "Opcode: 0x%04x, Status: %d, Result: %d\n",
cmd->opcode, cmd->status, cmd->result);
seq_printf(f, " Parameters: ");
if (cmd->plen > 0) {
int j;
for (j = 0; j < cmd->plen; j++)
seq_printf(f, "%02x ", cmd->params[j]);
}
seq_puts(f, "\n");
if (cmd->rlen > 0) {
seq_printf(f, " Response: ");
int j;
for (j = 0; j < cmd->rlen; j++)
seq_printf(f, "%02x ", cmd->response[j]);
seq_puts(f, "\n");
}
}
return 0;
}
跟踪点实现
// 定义跟踪点
#include <linux/tracepoint.h>
// HCI事件跟踪点
DECLARE_TRACE(hci_event,
TP_PROTO(struct hci_dev *hdev, struct sk_buff *skb),
TP_ARGS(hdev, skb));
// HCI命令跟踪点
DECLARE_TRACE(hci_cmd,
TP_PROTO(struct hci_dev *hdev, struct sk_buff *skb),
TP_ARGS(hdev, skb));
// HCI ACL数据跟踪点
DECLARE_TRACE(hci_acl,
TP_PROTO(struct hci_dev *hdev, struct sk_buff *skb),
TP_ARGS(hdev, skb));
// L2CAP事件跟踪点
DECLARE_TRACE(l2cap_event,
TP_PROTO(struct l2cap_chan *chan, struct sk_buff *skb),
TP_ARGS(chan, skb));
// SMP事件跟踪点
DECLARE_TRACE(smp_event,
TP_PROTO(struct smp_chan *smp, u8 event, u8 status),
TP_ARGS(smp, event, status));
// 在代码中使用跟踪点
static int hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_event_hdr *hdr = (void *) skb->data;
// 跟踪HCI事件
trace_hci_event(hdev, skb);
// 处理事件
switch (hdr->evt) {
case HCI_EV_CMD_COMPLETE:
hci_cmd_complete_evt(hdev, skb);
break;
case HCI_EV_CMD_STATUS:
hci_cmd_status_evt(hdev, skb);
break;
case HCI_EV_INQUIRY_COMPLETE:
hci_inquiry_complete_evt(hdev, skb);
break;
case HCI_EV_INQUIRY_RESULT:
hci_inquiry_result_evt(hdev, skb);
break;
default:
break;
}
return 0;
}
// 跟踪点实现
DEFINE_TRACE(hci_event);
DEFINE_TRACE(hci_cmd);
DEFINE_TRACE(hci_acl);
DEFINE_TRACE(l2cap_event);
DEFINE_TRACE(smp_event);
5.2 协议栈扩展开发
新协议层添加
// 新协议层注册示例
static struct bt_proto my_proto = {
.name = "MYPROTO",
.init = myproto_init,
.exit = myproto_exit,
.sock_create = myproto_sock_create,
.proto = &my_proto,
.owner = THIS_MODULE,
};
// 协议初始化函数
static int __init myproto_init(void)
{
int err;
// 注册协议族
err = bt_proto_register(&my_proto);
if (err < 0)
return err;
// 注册Socket协议
err = proto_register(&my_proto_proto, 1);
if (err < 0) {
bt_proto_unregister(&my_proto);
return err;
}
// 注册Sock协议
err = sock_register(&my_proto_family_ops);
if (err < 0) {
proto_unregister(&my_proto_proto);
bt_proto_unregister(&my_proto);
return err;
}
return 0;
}
// 协议清理函数
static void __exit myproto_exit(void)
{
// 注销Sock协议
sock_unregister(PF_MYPROTO);
// 注销Socket协议
proto_unregister(&my_proto_proto);
// 注销协议族
bt_proto_unregister(&my_proto);
}
// Socket创建函数
static int myproto_sock_create(struct socket *sock, int protocol)
{
struct sock *sk;
int err;
// 分配socket
sk = sk_alloc(sock_net(sock), PF_MYPROTO, GFP_KERNEL, &my_proto_proto, 0);
if (!sk)
return -ENOMEM;
// 初始化socket
sock_init_data(sock, sk);
sock->state = SS_UNCONNECTED;
sock->ops = &my_proto_sock_ops;
// 初始化协议特定数据
err = myproto_init_sock(sk);
if (err) {
sk_free(sk);
return err;
}
return 0;
}
驱动开发指南
// HCI驱动结构
struct hci_driver {
const char *name;
const char *bus;
// 基本操作
int (*open)(struct hci_dev *hdev);
int (*close)(struct hci_dev *hdev);
int (*flush)(struct hci_dev *hdev);
// 发送操作
int (*send)(struct hci_dev *hdev, struct sk_buff *skb);
int (*send_skb)(struct hci_dev *hdev, struct sk_buff *skb);
// 电源管理
int (*suspend)(struct hci_dev *hdev);
int (*resume)(struct hci_dev *hdev);
// 诊断操作
int (*diag)(struct hci_dev *hdev, struct sk_buff *skb);
// 配置操作
int (*set_bdaddr)(struct hci_dev *hdev, const bdaddr_t *bdaddr);
int (*set_diag)(struct hci_dev *hdev, bool enable);
int (*set_msft)(struct hci_dev *hdev, bool enable);
// 厂商特定
int (*vendor)(struct hci_dev *hdev, void *data, size_t len);
// 设备模型
struct device_driver driver;
};
// 驱动注册示例
static struct hci_driver myhci_driver = {
.name = "myhci",
.bus = "mybus",
.open = myhci_open,
.close = myhci_close,
.send = myhci_send,
.suspend = myhci_suspend,
.resume = myhci_resume,
};
// 驱动初始化
static int __init myhci_init(void)
{
return hci_register_driver(&myhci_driver);
}
// 驱动清理
static void __exit myhci_exit(void)
{
hci_unregister_driver(&myhci_driver);
}
module_init(myhci_init);
module_exit(myhci_exit);
5.3 常见问题分析
连接问题诊断
// 连接状态诊断
static void hci_conn_diagnose(struct hci_conn *conn)
{
struct hci_dev *hdev = conn->hdev;
BT_DBG("Connection diagnostic for %p", conn);
BT_DBG(" Handle: 0x%04x", conn->handle);
BT_DBG(" State: %d", conn->state);
BT_DBG(" Type: %d", conn->type);
BT_DBG(" Mode: %d", conn->mode);
BT_DBG(" Role: %d", conn->role);
BT_DBG(" Security: %d", conn->sec_level);
BT_DBG(" Pending security: %d", conn->pending_sec_level);
BT_DBG(" Link policy: 0x%04x", conn->link_policy);
BT_DBG(" Packet type: 0x%04x", conn->pkt_type);
BT_DBG(" QoS type: %d", conn->qos_type);
BT_DBG(" Power save: %d", conn->power_save);
BT_DBG(" Idle timeout: %d", conn->idle_timeout);
// 检查常见连接问题
if (conn->state == BT_CONNECTED) {
if (conn->sec_level < conn->pending_sec_level) {
BT_WARN("Security level mismatch: current=%d, required=%d",
conn->sec_level, conn->pending_sec_level);
}
if (conn->mode == HCI_CM_SNIFF && conn->power_save) {
BT_WARN("Connection in sniff mode with power save enabled");
}
if (conn->link_policy == 0) {
BT_WARN("No link policy configured");
}
}
// 检查数据包统计
BT_DBG(" Sent packets: %d", atomic_read(&conn->sent));
BT_DBG(" Received packets: %d", atomic_read(&conn->recv));
BT_DBG(" Dropped packets: %d", atomic_read(&conn->drop));
// 检查L2CAP通道
if (!list_empty(&conn->chan_list)) {
struct l2cap_chan *chan;
int chan_count = 0;
list_for_each_entry(chan, &conn->chan_list, list) {
chan_count++;
BT_DBG(" L2CAP channel %d: state=%d, scid=0x%04x, dcid=0x%04x",
chan_count, chan->state, chan->scid, chan->dcid);
}
} else {
BT_WARN("No L2CAP channels configured");
}
}
性能问题诊断
// 性能瓶颈分析
static void hci_performance_diagnose(struct hci_dev *hdev)
{
struct hci_stats *stats = &hdev->stats;
u64 cmd_rate, acl_rate, le_rate;
u64 cmd_latency, acl_latency, le_latency;
u64 acl_throughput, le_throughput;
// 计算数据包速率
cmd_rate = atomic_read(&stats->cmd_rx) * 1000 / hdev->uptime;
acl_rate = atomic_read(&stats->acl_rx) * 1000 / hdev->uptime;
le_rate = atomic_read(&stats->le_rx) * 1000 / hdev->uptime;
// 获取延迟统计
cmd_latency = stats->cmd_latency;
acl_latency = stats->acl_latency;
le_latency = stats->le_latency;
// 获取吞吐量统计
acl_throughput = stats->acl_throughput * 8 / hdev->uptime; // bits per second
le_throughput = stats->le_throughput * 8 / hdev->uptime; // bits per second
BT_INFO("Performance diagnostic for %s:", hdev->name);
BT_INFO(" Command rate: %llu packets/sec", cmd_rate);
BT_INFO(" ACL rate: %llu packets/sec", acl_rate);
BT_INFO(" LE rate: %llu packets/sec", le_rate);
BT_INFO(" Command latency: %llu ns", cmd_latency);
BT_INFO(" ACL latency: %llu ns", acl_latency);
BT_INFO(" LE latency: %llu ns", le_latency);
BT_INFO(" ACL throughput: %llu bits/sec", acl_throughput);
BT_INFO(" LE throughput: %llu bits/sec", le_throughput);
// 性能问题检测
if (cmd_latency > 100000000) { // 100ms
BT_WARN("High command latency detected: %llu ns", cmd_latency);
}
if (acl_latency > 50000000) { // 50ms
BT_WARN("High ACL latency detected: %llu ns", acl_latency);
}
if (le_latency > 20000000) { // 20ms
BT_WARN("High LE latency detected: %llu ns", le_latency);
}
if (atomic_read(&stats->acl_drop) > atomic_read(&stats->acl_rx) * 0.01) {
BT_WARN("High ACL drop rate: %d drops out of %d packets",
atomic_read(&stats->acl_drop), atomic_read(&stats->acl_rx));
}
if (atomic_read(&stats->le_drop) > atomic_read(&stats->le_rx) * 0.01) {
BT_WARN("High LE drop rate: %d drops out of %d packets",
atomic_read(&stats->le_drop), atomic_read(&stats->le_rx));
}
// 检查工作队列状态
if (hdev->workqueue) {
struct workqueue_struct *wq = hdev->workqueue;
BT_INFO(" Workqueue: %s", wq->name);
BT_INFO(" Workqueue active: %d", workqueue_active(wq));
BT_INFO(" Workqueue pending: %d", workqueue_pending(wq));
}
}
6. 总结
本文档深入分析了Linux BlueZ协议栈的底层实现原理,涵盖了以下核心内容:
架构层面
- BlueZ采用分层模块化架构,实现了从硬件驱动到应用接口的完整蓝牙解决方案
- 内核空间与用户空间通过AF_BLUETOOTH Socket接口和D-Bus IPC机制进行交互
- 各协议层(HCI、L2CAP、RFCOMM、BNEP、SCO)独立实现,通过标准接口集成
核心机制
- HCI层:负责与蓝牙硬件的直接交互,管理命令、事件和数据传输
- L2CAP层:提供逻辑链路控制和适配,支持多路复用和QoS
- 安全机制:实现SMP协议,支持多种配对方法和密钥派生
- 电源管理:支持传统蓝牙和LE的低功耗模式,优化电池寿命
性能优化
- 零拷贝传输:通过DMA映射减少数据复制,提高传输效率
- 实时性保障:使用实时优先级和快速路径优化延迟
- 内存管理:采用内存池技术减少内存分配开销
调试开发
- 调试接口:通过debugfs和跟踪点提供详细的调试信息
- 扩展开发:支持新协议层添加和驱动开发
- 问题诊断:提供连接和性能问题的诊断工具
BlueZ协议栈的设计充分体现了Linux内核的模块化思想和性能优化理念,为蓝牙应用提供了稳定、高效的底层支撑。通过深入理解其实现原理,开发者可以更好地进行蓝牙应用开发、性能优化和问题调试。
参考资料
- Linux内核源码:net/bluetooth/ 目录
- BlueZ官方文档:https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc
- Bluetooth Core Specification v5.2
- Linux Bluetooth Programming Guide
- Kernel Debugging and Performance Tuning Guide
浙公网安备 33010602011771号