目录
1.tools工具:
本章节介绍的小工具,都是可以直接访问controller设备,不依赖bluetoothd进程的。
tools目录中有部分工具是需要通过dbus访问bluetoothd守护程序才实现功能,实际上功能是bluetoothd来实现的,工具只是作为一个client来触发。为了更好的理解bluez的实现,本章节并不介绍此类dbus的tools的实现。
1.1 hciattach:
该执行程序用来将串口dongle设备挂载到hci总线上,Linux的应用层就可以收发数据了。
$ sudo hciattach /dev/ttyACM0 any 115200
其中/dev/ttyACM0需要根据实际情况来选择(不一定是ACM0,有可能是ACM1或者其他)。
并不是所有的后插入的dongle设备都需要手动hciattach,realtek的双模蓝牙设备安装完驱动之后,会自动挂载的。挂载完成后,hciconfig命令就可以看到对应的蓝牙设备。
btconfig与hciattach功能类似,不过现在很少被使用了。
不同的芯片原厂,会定制hciattach命令:
例如realtek:rtk_hciattach -n -s 115200 ttyS1 rtk_h5
例如全志:hciattach -n ttyS1 xradio
1.2 hciconfig:
- 查看controller当前状态:
tools$ hciconfig
hci1: Type: Primary Bus: UART
BD Address: C0:07:E8:34:E1:B1 ACL MTU: 256:4 SCO MTU: 0:0
UP RUNNING
RX bytes:2570 acl:40 sco:0 events:178 errors:0
TX bytes:1661 acl:38 sco:0 commands:123 errors:0
hci0: Type: Primary Bus: USB
BD Address: 00:93:37:8D:57:D8 ACL MTU: 8192:128 SCO MTU: 64:128
UP RUNNING PSCAN ISCAN
RX bytes:3870 acl:0 sco:0 events:211 errors:0
TX bytes:5132 acl:0 sco:0 commands:211 errors:0
- 停止和使能controller:
sudo hciconfig hci0 down,sudo hciconfig hci0 up
guofeng@ubuntu:~/Workspace/bluez/bluez-5.54/tools$ sudo hciconfig hci0 down
guofeng@ubuntu:~/Workspace/bluez/bluez-5.54/tools$ hciconfig
hci1: Type: Primary Bus: UART
BD Address: C0:07:E8:34:E1:B1 ACL MTU: 256:4 SCO MTU: 0:0
UP RUNNING
RX bytes:2570 acl:40 sco:0 events:178 errors:0
TX bytes:1661 acl:38 sco:0 commands:123 errors:0
hci0: Type: Primary Bus: USB
BD Address: 00:93:37:8D:57:D8 ACL MTU: 8192:128 SCO MTU: 64:128
DOWN
RX bytes:3870 acl:0 sco:0 events:211 errors:0
TX bytes:5132 acl:0 sco:0 commands:211 errors:0
guofeng@ubuntu:~/Workspace/bluez/bluez-5.54/tools$ sudo hciconfig hci0 up
guofeng@ubuntu:~/Workspace/bluez/bluez-5.54/tools$ sudo hciconfig
hci1: Type: Primary Bus: UART
BD Address: C0:07:E8:34:E1:B1 ACL MTU: 256:4 SCO MTU: 0:0
UP RUNNING
RX bytes:2570 acl:40 sco:0 events:178 errors:0
TX bytes:1661 acl:38 sco:0 commands:123 errors:0
hci0: Type: Primary Bus: USB
BD Address: 00:93:37:8D:57:D8 ACL MTU: 8192:128 SCO MTU: 64:128
UP RUNNING PSCAN ISCAN
RX bytes:4398 acl:0 sco:0 events:237 errors:0
TX bytes:5492 acl:0 sco:0 commands:237 errors:0
- 重置controller:
guofeng@ubuntu:~/Desktop$ sudo hciconfig hci0 reset
- 查看controller支持的特性(支持经典蓝牙和BLE):
guofeng@ubuntu:~/Desktop$ sudo hciconfig hci0 features
hci0: Type: Primary Bus: UART
BD Address: D5:3C:3B:25:13:47 ACL MTU: 512:4 SCO MTU: 0:0
Features: 0x00 0x00 0x00 0x00 0x60 0x00 0x00 0x00
<BR/EDR not supp.> <LE support>
- 查看controller支持的commands:
guofeng@ubuntu:~/Desktop$ sudo hciconfig hci0 commands
hci0: Type: Primary Bus: UART
BD Address: D5:3C:3B:25:13:47 ACL MTU: 512:4 SCO MTU: 0:0
Commands: Octet 0 = 0x20 (Bit 5)
Octet 2 = 0x80 (Bit 7)
Octet 5 = 0xc0 (Bit 6 7)
Octet 10 = 0x04 (Bit 2)
Octet 14 = 0x28 (Bit 3 5)
Octet 15 = 0x22 (Bit 1 5)
Octet 22 = 0x04 (Bit 2)
Octet 25 = 0xf7 (Bit 0 1 2 4 5 6 7)
Octet 26 = 0xff (Bit 0 1 2 3 4 5 6 7)
Octet 27 = 0xff (Bit 0 1 2 3 4 5 6 7)
Octet 28 = 0x7f (Bit 0 1 2 3 4 5 6)
Octet 32 = 0x30 (Bit 4 5)
Octet 33 = 0xf0 (Bit 4 5 6 7)
Octet 34 = 0xff (Bit 0 1 2 3 4 5 6 7)
Octet 35 = 0xff (Bit 0 1 2 3 4 5 6 7)
Octet 36 = 0xff (Bit 0 1 2 3 4 5 6 7)
Octet 37 = 0xff (Bit 0 1 2 3 4 5 6 7)
Octet 38 = 0xff (Bit 0 1 2 3 4 5 6 7)
Octet 39 = 0x07 (Bit 0 1 2)
Octet 40 = 0xe0 (Bit 5 6 7)
Octet 41 = 0xf7 (Bit 0 1 2 4 5 6 7)
Octet 42 = 0xff (Bit 0 1 2 3 4 5 6 7)
Octet 43 = 0xff (Bit 0 1 2 3 4 5 6 7)
Octet 44 = 0xff (Bit 0 1 2 3 4 5 6 7)
Octet 45 = 0x1e (Bit 1 2 3 4)
'Disconnect' 'Read Remote Version Information' 'Set Event Mask'
'Reset' 'Read Transmit Power Level' 'Read Local Version Information'
'Read Local Supported Features' 'Read BD ADDR' 'Read RSSI'
'Set Event Mask Page 2' 'LE Set Event Mask' 'LE Read Buffer Size'
'LE Read Local Supported Features' 'LE Set Random Address'
'LE Set Advertising Parameters' 'LE Read Advertising Channel TX Power'
'LE Set Advertising Data' 'LE Set Scan Response Data'
'LE Set Advertise Enable' 'LE Set Scan Parameters'
'LE Set Scan Enable' 'LE Create Connection'
'LE Create Connection Cancel' 'LE Read Accept List Size'
'LE Clear Accept List' 'LE Add Device To Accept List'
'LE Remove Device From Accept List' 'LE Connection Update'
'LE Set Host Channel Classification' 'LE Read Channel Map'
'LE Read Remote Used Features' 'LE Encrypt' 'LE Rand'
'LE Start Encryption' 'LE Long Term Key Request Reply'
'LE Long Term Key Request Negative Reply' 'LE Read Supported States'
'LE Receiver Test' 'LE Transmitter Test' 'LE Test End'
- 如果sudo hciconfig hci0 up/down失败的话,可以试试先输入这个命令
$ sudo rfkill unblock all
1.3 btmon:
linux系统上调试蓝牙的必备工具,可以监控到mgmt的消息收发,也可以监控到hci消息的收发。btmon很强大,linux系统平台蓝牙开发调试的必备手段。类似的工具还有hcidump,但是hcidump看不到mgmt的消息交互。另外hcidump在运行的时候,需要给与sudo权限,不然只能看到hci event数据。
1.4 hcitool:
这个工具在早期的bluez版本中是默认编译的,比较新的bluez版本,这个工具已经不是默认编译的了。它有一个问题是使用legacy hci command进行和controller通信,如果controller支持5.0及以上,并且已经处理过extend hci command,则回复忽略hcitool指令发送的hci command,返回错误Command Disallowed(0x0c)。
1.5 btmgmt:
blue协议栈里面和kernel的消息交互的方式目前首先推荐是mgmt格式的消息,而不是hci消息。开发者可以通过btmgmt程序来快速了解到mgmt的消息是如何收发的。btmgmt提供一个shell交互的menu(类似于bluetoothclt)。关于mgmt的详细的command和event的介绍可以参考doc/mgmt-api.txt文件。
1.6 others:
- advtest:
使用bt_hci_*的api(没有使用mgmt api),需要两个支持ble的controller,实现了广播数据的接收和发送示例代码。
- ibeacon:
使用bt_hci_*的api(没有使用mgmt api),实现了发送苹果的beacon包的功能,可供参考。
- btgatt-server:
gatt的server的实现demo,但是没有发送可连接广播的逻辑,需要再启动一个进程去对外发送ble广播,别的设备才可以发现它,并且连接它。
- btgatt-client:
gatt的client的实现demo,需要制定待连接设备的mac地址。
2.tester:
tools目录下有一些***-tester.c的源码,mgmt-tester.c,smp-tester.c,gap-tester.c,userchan-tester.c和hci-tester.c等等,这些文件是需要"--enable-testing --enable-test"才会进行编译的,这些程序对于理解linux系统上bluez的实现原理也是很有帮助的。
$ ./configure --enable-debug --enable-logger --enable-library --enable-shared --enable-static --enable-test --enable-testing --enable-threads --enable-debug
$ make
3.其他:
3.1 peripheral:
在bluez的根目录下有一个peripheral文件夹,里面实现了ble的peripheral角色,也就是包含和实现了gap profile和gatt server profile的功能,源码可以参考。
3.2 sys/kernel:
成功了挂在了controller到kernel上之后,也可以通过sys/kernel来获取controller的状态。
guofeng@ubuntu:/sys$ sudo tree kernel/debug/bluetooth/hci1
kernel/debug/bluetooth/hci1
├── adv_channel_map
├── adv_max_interval
├── adv_min_interval
├── auth_payload_timeout
├── blacklist
├── blocked_keys
├── conn_info_max_age
├── conn_info_min_age
├── conn_latency
├── conn_max_interval
├── conn_min_interval
├── device_id
├── device_list
├── discov_interleaved_timeout
├── dut_mode
├── features
├── force_no_mitm
├── force_static_address
├── hardware_error
├── hci_revision
├── hci_version
├── identity
├── identity_resolving_keys
├── long_term_keys
├── manufacturer
├── max_key_size
├── min_key_size
├── quirk_simultaneous_discovery
├── quirk_strict_duplicate_filter
├── random_address
├── remote_oob
├── resolv_list
├── resolv_list_size
├── rpa_timeout
├── sc_only_mode
├── static_address
├── supervision_timeout
├── use_debug_keys
├── uuids
├── white_list
└── white_list_size
最后:
bluez的代码结构过于庞大,bluetoothd和bluetoothctl是比较核心的一对应用,bluetoothd是bluetooth service的核心守护进程,linux的系统设置里面都是访问的bluetoothd进程实现的,但是也带了一个问题,就是bluetoothd是通过dbus对外提供访问它的接口,屏蔽掉了mgmt/hci消息的处理细节,同时dbus是一个相对复杂的跨进程通信方式,因此上来就看bluetoothd进程的话,相当于由深入浅,会给开发者增加理解源码的困难,增加学习难度和成本。如果我们先看tools目录下的应用程序的话,就会好一些,可以直接看到mgmt和hci的消息处理的逻辑,而且代码量不大,每个小工具只完成很小的一部分工作,和蓝牙的hci消息也对得上。