BlueZ5
1. Bluez介绍
BlueZ 是官方 Linux Bluetooth 栈,由主机控制接口(Host Control Interface ,HCI)层、Bluetooth 协议核心、逻辑链路控制和适配协议(Logical Link Control and Adaptation Protocol,L2CAP)、SCO 音频层、其他 Bluetooth 服务、用户空间后台进程以及配置工具组成。
BlueZ提供对核心蓝牙层和协议的支持。它灵活,高效,并使用模块化实现。Bluez有很多有趣的特性:
(1)完全的模块化实现
(2)均衡的多处理安全
(3)支持多线程数据处理
(4)支持多个蓝牙设备
(5)真正的硬件抽象
(5)向所有层提供标准socket接口
(6)支持设备和服务级别的安全
目前BlueZ由许多单独的模块组成:
(1)蓝牙内核核心子系统
(2)L2CAP和SCO音频内核层
(3)RFCOMM,BNEP,CMTP和HIDP的内核实现
(4)HCI UART,USB,PCMCIA以及虚拟设备的驱动程序
(5)通用的蓝牙和SDP库以及守护进程
(6)配置和测试程序
(7)协议解码和分析工具
BlueZ目前支持很多蓝牙协议:
(1)底层主机协议栈(Lower level host stack)
Core Specification 4.2 (GAP, L2CAP, RFCOMM, SDP, GATT)
1)Classic Bluetooth (BR/EDR)
2)Bluetooth Smart (Low Energy)
(2)上层协议
由BlueZ提供:
A2DP 1.3
AVRCP 1.5
DI 1.3
HDP 1.0
HID 1.0
PAN 1.0
SPP 1.1
基于GATT(LE)协议:
PXP 1.0
HTP 1.0
HoG 1.0
TIP 1.0
CSCP 1.0
基于OBEX的协议(通过obexd支持):
FTP 1.1
OPP 1.1
PBAP 1.1
MAP 1.0
由oFono项目提供的协议:
HFP 1.6(AG&HF)
BlueZ的内核模块,库和以及实用程序已支持在Linux支持的许多架构上完美工作。这还包括很多单处理器和多处理器平台以及超线程系统:
(1)英特尔和AMD x86
(2)AMD64和EM64T(x86-64)
(3)SUN SPARC 32 / 64bit
(4)PowerPC 32 / 64bit
(5)英特尔StrongARM和XScale
(6)日立/瑞萨SH处理器
(7)摩托罗拉 DragonBall
BlueZ可以在许多Linux发行版中找到,一般来说它与市场上的任何Linux系统兼容:
(1)Debian GNU / Linux
(2)Ubuntu Linux
(3)Fedora Core / Red Hat Linux
(4)OpenSuSE / SuSE Linux
(5)Mandrake Linux
(6)Gentoo Linux
(7)Chrome操作系统
2.BlueZ架构
目前最新的BlueZ版本是BlueZ5。下面将以BlueZ5为例,详细说明BlueZ架构:
图1. Bluez5架构.
Bluez5的分为kernel和user space 两部分。
BlueZ的kernel模块从Linux 2.6内核开始就已经包含在linux内核中。
kernel 模块包括:
(1)底层协议(L2CAP,RFCOMM,BNEP,HIDP等)
(2)安全性(SSP,SMP)
(3)硬件驱动程序
(4)提供给user space的基于socket的接口
1)数据接口(L2CAP,RFCOMM,SCO,HCI)
2)控制接口(MGMT,HCl,BNEP,HIDP)
虽然kernel模块早已存在于linux内核中,但是没有user space模块的支持,kernel模块无法发挥作用。最新版本的user space模块的下载地址为:
http://www.kernel.org/pub/linux/bluetooth/bluez-5.44.tar.xz
user space模块包括:
(1)bluetoothd
1)是BlueZ的中央守护进程
2)提供用于UI和其他子系统的D-Bus接口
3)减少暴露底层细节
4)可以通过插件扩展(例如通过neard支持NFC,通过sixaxis支持DS3)
(2)obexd
1)是OBEX协议的守护进程
2)提供用于UI的D-Bus接口
3)具有与bluetoothd类似的架构
(3)工具(tools)
1)bluetoothctl - bluetooth命令行测试工具
2)obexctl - obex命令行测试工具
3)btmon - HCl信息跟踪
4)其他用于测试,开发和跟踪的命令行工具集
(4)上层协议
1)Audio and media (A2DP, AVRCP)
2)Telephony (HFP, HSP)
3)Networking (PAN, 6LoWPAN)
4)Input device (HID, HoG)
5)OBEX (FTP, OPP, MAP, PBAP)
6)Others
3.BlueZ源代码
下载BlueZ5(bluez-5.44.tar.xz)源代码压缩包,经解压后得到BlueZ5源代码,BlueZ5源代码中有很多目录和文件:
android/ - 用于替代android中bluedroid的android版本bluez源码。
attrib/ - 包含gatttool 源码以及与gatt attribute相关的代码,gatttool程序入口为gatttool.c。
btio/ - 通过的标准socket接口与BlueZ5 kernel模块通信?。
client/ - bluetoothctl源码,程序入口为main.c。
doc/ - BlueZ5 API文档。
emulator/ - 与bluetooth虚拟controller工具相关的代码?。
gdbus/ - BlueZ5自带的内部gdbus库源码。
gobex/ - Blue5自带的内部gobex库源码。
lib/ - libbluetooth.so 源码,提供BlueZ4 API,用来支持某些第三方应用。
monitor/ - btmon源码, 程序入口为main.c。
obexd/ - obexd源码,程序入口为src/main.c。
peripheral/ - 与蓝牙ble的GATT相关的代码?。
plugins/ - BlueZ5插件源码(neard,autopair等插件)。
profiles/ - BlueZ5蓝牙上层协议(a2dp,hid等)源码。
src/ - bluetoothd源码,程序入口为main.c。
test/ - Bluez5测试脚本。
tools/ - Bluez5测试工具集源码。
unit/ - PTS测试相关的一些代码?。
README / INSTALL - 配置,编译,安装Bluez5的说明。
Makefile.obexd - 定义obexd编译规则,此文件被include于Makefile.am中。
Makefile.plugins - 定义BlueZ5的plugins(neard,autopair等)的编译规则, 此文件被include于Makefile.am中。
Makefile.tools - 定义BlueZ5测试工具集的编译规则,此文件被include于 Makefile.am中。
Makefile.am - 定义了Bluez5的编译规则。用于automake工具,生成 Makefile.in文件。
Makefile.in - 用于configure脚本,生成最终的Makefile文件。
configure.ac - 用于autoconf工具,生成configure脚本。
configure - 配置编译选项,生成最终的Makefile文件,以及config.h文件。
4.BlueZ测试工具
BlueZ5提供了很多测试工具:
bccmd - 用于向CSR(Cambridge Silicon Radio)设备发出BlueCore命令。
bluemoon - 是一个Bluemoon配置工具。
bluetoothctl - bluetoothd测试工具。
bluetooth-player - 蓝牙音频测试(AVRCT)工具。
btmgmt - 使用Bluetooth Management API的蓝牙测试工具,通过Bluetooth Management sockets 与 kernel模块通信。
btmon - 用于监控HCI,获取HCI log,解析HCI log,可以替代hcidump。
ciptool - 用于设置,维护和检查Linux内核中蓝牙子系统的CIP配置。
hciattach - 用于将串口连接到蓝牙协议栈作为HCI的传输接口。
hciconfig - 用于配置蓝牙设备。
hcidump - 用于监控HCI,获取HCI log,解析HCI log。
hcitool - 用于配置蓝牙连接并向蓝牙设备发送一些特殊命令。
hex2hcd - 用于将Broadcom设备所需的文件转换为hcd(Broadcom蓝牙固件)格式。
hid2hci - 蓝牙USB Dongle 的HID和HCI模式切换工具。
l2ping - ping扫描到的远端设备。
l2test - l2cap测试工具。
mpris-proxy - 媒体播放器远程接口规范(mpris)是标准的D-Bus接口,其旨在提供用于控制媒体播放器的公共API。mpris-proxy 是一种实现mpris的媒体播放器测试工具(AVRTG?)。更多关于mpris的信息见:
http://specifications.freedesktop.org/mpris-spec/latest/
obexctl - obexd测试工具。
obex-client-tool - obex server端测试工具。
obex-server-tool - obex client端测试工具。
rctest - 用于测试蓝牙协议栈上的RFCOMM通信。
rfcomm - 用于设置,维护和检查Linux内核中蓝牙子系统的RFCOMM配置。
sdptool - 用于在蓝牙设备上执行SDP查询。
5.BlueZ5 API介绍和使用
所有BlueZ5的API都可以在BlueZ5源码目录下的 doc/ 目录下查询到,同时API 相关代码示例可以在BlueZ5源码目录下的 test/ 目录中查询到。与BlueZ 4相比,BlueZ 5的 D-Bus API有重大更改。大部分更改是由于BlueZ 5中的以下新特性导致的:
1)采用标准D-Bus Properties和ObjectManager接口(在D-Bus specification文档中定义)。
2)引入特定版本的接口(例如org.bluez.Adapter1)。当引入新版本接口时,会尽量同时支持至少两个最新版本。
3)简化或删除单独的profile接口,添加通用的org.bluez.Device1.Connect方法来连接profile。
4)移除org.bluez.Service接口(用于注册SDP records and authorization),引入新的org.bluez.Profile1接口。
5)在设备扫描期间动态创建设备对象。
6)引入新的AgentManager1接口。
7)基本D-Bus路径已移至“/org/bluez”。
(1)D-Bus Properties
D-Bus的Properties接口提供了对object/interface的属性(Properties)的访问方法。BlueZ4在需要提供访问属性方法的每个接口上自定义了GetProperties和SetProperty方法以及PropertyChanged信号。在BlueZ 4发布以后,一个新的的标准的属性接口已经完成了,现在不是在特定的接口上实现这些方法和信号,而是在每个对象(object)上都有一个包含如Set,Get和GetAll方法和PropertiesChanged信号的通用的org.freedesktop.DBus.Properties接口。这些方法和信号包含一部分属性属于消息参数的特定接口。
属性无效化(the invalidation of a property)的特性仅由标准属性接口提供,不存在与BlueZ4中。这个特性对于传递一个不再存在的属性的信息特别方便。
(2)D-Bus ObjectManager
D-Bus的ObjectManager接口是访问D-Bus服务的整个对象层次结构的通用方法。它包括用于监听接口添加和删除的信号(signal)以及一个返回服务中所有可用对象、对象的接口以及接口上的所有属性的GetManagedObjects方法。实际的ObjectManager接口可以在BlueZ服务的根(“/”)路径上找到。
因为大多数管理和发现对象的任务都可以通过ObjectManager接口来完成,BlueZ 4中的许多方法,信号和属性都因为变得多余,而被删除了。其中最著名的一个是旧的org.bluez.Manager接口。这个接口在BlueZ 5中没有任何对应的东西。相反,应用程序将通过ObjectManager.GetManagedObjects方法查找具有“org.bluez.Adapter1”接口的任何返回对象来发现可用的adapter。默认adapter的概念总是有点不清晰,并且adapter值不能改变,所以如果应用需要设置默认的adapter,应选择查找到的第一个adapter。
BlueZ5源代码test/目录下的get-managed-objects测试脚本,可以通过ObjectManager接口来查看bluetoothd上的对象。
(3)Device discovery
Ble的蓝牙地址基本上只是在经典蓝牙地址的基础上扩展了额外的一个位,这个地址还有“随机(ramdom)”还是“公共(public)”之分。这导致调用BlueZ 4 的CreateDevice和CreatePairedDevice API时,由于传入的蓝牙地址参数没有包含任何这个额外的随机/公共信息,bluetoothd不得不维护一个内部缓存来查找必要的信息。另一个问题是,由于BlueZ D-Bus API不区分传统的BR / EDR设备和LE设备,因此基本上有三种可能的地址类型需要缓存:BR / EDR,LE公共和LE随机。
为了解决这个问题,BlueZ5去除了显式CreateDevice / CreatePairedDevice的方法,同时由于远端设备是在设备扫描过程中发现的而采用了动态创建设备对象的方法。由于引入了新的ObjectManager,单独的DeviceFound信号也不再需要了。应用程序可以在设备发现过程中通过通用的ObjectManager信号简单地跟踪新创建的设备对象。BlueZ5引入一个新的Device1.Pair方法(与旧的CreatePairedDevice方法类似)去配对远端设备,同样引入一个新的Device1.Connect方法(与CreateDevice方法类似,但不完全相同)去跳过配对过程,直接连接远端设备。一旦停止了设备发现,未连接或配对的设备将在三分钟内被bluetoothd自动删除。
BlueZ5源代码的test/目录下有一个可以用于测试设备发现功能的test-discov