Linux之蓝牙相关代码浅析

[TOC]

主要记录一些整体的概念、框架和简单介绍,不涉及具体的原理和实现细节

Linux协议栈

Kernel: v5.4.18
Bluez官网:http://www.bluez.org/

Linux蓝牙协议栈Bluez分为内核空间和用户空间2个部分。
这里我们先只讨论内核部分。

而内核部分也分为2块:HCI驱动协议栈源码

下面就分这两块分别进行分析

内核蓝牙HCI驱动:

路径:/drivers/bluetooth
固件:/usr/lib/firmware//lib/firmware/


                        btsdio --
                                |
btxxx(btrtl,vendor..)  btusb --(`/drivers/bluetooth/`)--> hci-core(`/net/bluetooth/`)
                                |
                        hci_ldisc

这里主要分析USB和Uart接口的HCI驱动:
注: 脑图省略了部分中间过程及接口,主要展示核心函数和上下层对应关系

USB:

主要源码文件:bt_usb.c
用到了USB主要几类传输方式:中断传输、块传输、控制传输和同步传输。
数据是以sk_buff的方式传输,主要有3类:evt_skbacl_skbsco_skb

通过id_table进行usb_device的匹配,主要是VID,PID;

avatar

UART:

主要源码文件:hci_ldisc.c
tty上层可能还会包含H4协议、三线H5协议、厂家自定义的协议等
avatar

从以上usb和uart的流程对比可以看出,为什么使用串口接口的蓝牙模块需要使用hciattach命令来进行初始化操作,hciattach命令里面会调用tty的ioctl接口,例如华为9A0笔记本使用的串口蓝牙Hi1005。

内核蓝牙协议栈核心源码:

路径: /net/bluetooth
内核蓝牙协议栈版本要与用户空间的匹配,bluez会对内核版本有要求。
主要核心是hci_corebt_init

hci_core.c:

主要针对hci_alloc_dev函数进行分析:
该函数主要对重要的数据结构、work和sysfs接口进行初始化
avatar

bt_init:

bt_init函数会在内核启动时或模块加载时被调用;
该函数主要是一些链路的初始化、sock注册

avatar

参考