【蓝牙】蓝牙,调试 hcitool与gatttool实例

Bluez协议栈在安装完以后,会提供两个命令行调试工具,hcitool与gattool,我们可以根据提供的工具来轻松的调试我们的蓝牙设备,调试BLE设备时,需要获取root权限。

蓝牙设备的开启与关闭

首先,查看在使用hci工具时,我们需要查看当前能够识别的蓝牙设备,这里我们需要使用的工具是hciconfig命令,该命令如ifconfig一样,可以控制蓝牙设备的开启与关闭,在默认情况下,蓝牙设备在插入host时是不会自动开启的,所以我们在调试之前要先开启设备。

如果我们需要查看蓝牙设备的话:

hci0:	Type: Primary  Bus: UART
	BD Address: 54:C9:DF:B1:CD:8C  ACL MTU: 1024:7  SCO MTU: 60:8
	UP RUNNING PSCAN 
	RX bytes:85137 acl:851 sco:0 events:4646 errors:0
	TX bytes:44582 acl:847 sco:0 commands:2426 errors:0

 

会输出以上内容,我们可以看到蓝牙设备的编号为hci0,这是host分配给设备的ID,我们用来启动或关闭设备也是需要该ID来控制。

开启与关闭设备:

#设备打开
sudo hciconfig hci0 up
#设备关闭
sudo hciconfig hci0 down

 

hcitool命令及参数

在打开蓝牙设备以后,就可以使用hcitool工具集对蓝牙进行控制,工具集参数 分为两部分,一为正常的蓝牙设备调试,二为低功耗即BLE设备, 工具参数如下:

$  hcitool                                                      
hcitool - HCI Tool ver 4.93
Usage:
        hcitool [options] <command> [command parameters]
Options:
        --help  Display help
        -i dev  HCI device
Commands:
        dev     Display local devices
        inq     Inquire remote devices
        scan    Scan for remote devices
        name    Get name from remote device 
        info    Get information from remote device
        spinq   Start periodic inquiry
        epinq   Exit periodic inquiry
        cmd     Submit arbitrary HCI commands
        con     Display active connections
        cc      Create connection to remote device
        dc      Disconnect from remote device
        sr      Switch master/slave role
        cpt     Change connection packet type
        rssi    Display connection RSSI
        lq      Display link quality
        tpl     Display transmit power level
        afh     Display AFH channel map
        lp      Set/display link policy settings
        lst     Set/display link supervision timeout
        auth    Request authentication
        enc     Set connection encryption
        key     Change connection link key
        clkoff  Read clock offset
        clock   Read local or remote clock
        lescan  Start LE scan
        lewladd Add device to LE White List
        lewlrm  Remove device from LE White List
        lewlsz  Read size of LE White List
        lewlclr Clear LE White list
        lecc    Create a LE Connection
        ledc    Disconnect a LE Connection
        lecup   LE Connection Update

For more information on the usage of each command use:
        hcitool <command> --help

 

命令说明调用方式
参数    
–help 进入帮助 hcitool –help
-i 在host插有多个蓝牙适配器的情况下,可以通过该参数来指定某控制某一适配器 hcitool -i [dbaddr] [command]
命令 下面的命令是普通蓝牙设备,不需要sudo  
dev 同hciconfig一样,显示当前适配器设备,输出格式为[hciid MAC] hcitool dev
inq 查询可发现的远程设备,与scan不同的是,除了能查询出MAC以外,还可以查出远程设备的时钟偏移值“clock offset”与设备类型“class”,scan是不会输出相关设备的类型,这可以让我们区分设备是蓝牙耳机,或蓝牙鼠标 hcitool inq
    hcitool inq [–length=N]设置最大查询时间
    hcitool inq [–numrsp=N]设置最大查询数量
    hcitool inq [–iac=lap]指定查询的lac码
    hcitool inq [–flush]清除缓存
scan 查询可发现的远程设备,与inq不同的是,除了能查询出MAC以外,还可以输出设备的名字【名字写在标准的module中,若查询不到该key对应的values则会输出N/A】,可以通过设置参数来获取设备的类型,信息等 hcitool scan
    hcitool scan[–length=N]设置最大查询时间
    hcitool scan[–numrsp=N]设置最大查询数量
    hcitool scan[–iac=lap]指定查询的lac码
    hcitool scan[–class]查询设备类型
    hcitool scan[–info]查询设备信息
    hcitool scan[–oui]查询设备唯一标识
    hcitool scan[–flush]清除缓存
name 通过指定MAC地址来获取设备的名称,该命令可以补全inq查询时无法输出设备名称的问题. hcitool name [dbaddr]
info 通过指定MAC地址来获取设备的相关信息。 hcitool info [dbaddr]
spinq 开启定期查询,使设备被发现,没有则无输出 hcitool spinq
epinq 关闭定期查询,没有则无输出 hcitool epinq
cmd 向远程设备发送命令 hcitool cmd < ogf > < ocf > [parameters]
con 显示当前连接信息 hcitool con
cc 连接设备,可以设置数据类型,与主从关系 hcitool cc < bdaddr >
    hcitool cc [–ptype=pkt_types] < bdaddr > 可以设置接收数据的类型,数据类型包括[DM1, DM3, DM5,DH1,DH3,DH5, HV1, HV2, HV3],可以设置多个类型,类型中间以逗号分隔,默认接收所有类型数据
    hcitool cc [–role=m/s] < bdaddr >可以设置设备的主从关系,M为master,S为slave,默认为s
  Example: hcitool cc –ptype=dm1,dh3,dh5 01:02:03:04:05:06
    cc –role=m 01:02:03:04:05:06
dc 断开远程设备连接 hcitool dc < bdaddr > [reason]
sr 设置设备的主从关系 hcitool sr < bdaddr > < role >
cpt 设置远程设备数据类型 hcitool cpt < bdaddr > < packet_types >可以设置接收数据的类型,数据类型包括[DM1, DM3, DM5,DH1,DH3,DH5, HV1, HV2, HV3],可以设置多个类型,类型中间以逗号分隔
rssi 显示设备的信号强度 hcitool rssi < bdaddr>
lq 显示设备的链路质量 hcitool lq < bdaddr>
tpl 显示设备的发射功率级别 hcitool tpl < bdaddr> [type]
afh 显示设备的AFH(适应性跳频)的信道地图 hcitool afh < bdaddr>
lp 设置或显示设备的链路 hcitool lp < bdaddr> [link policy]
lst 设置或显示连接超时时间,默认情况下连接超时断开连接为20s可以设置超时时间来缩短超时断开连接的时间 hcitool lst < bdaddr> [new value in slots]
auth 请求设备配对认证 hcitool auth < bdaddr>
enc 设置连接加密,同样可以关闭连接加密 hcitool enc < bdaddr> [encrypt enable]
key 更新与远程设备的link key hcitool key < bdaddr>
clkoff 读取远程设备的时钟偏移量,不过这个变量不太靠谱 hcitool clkoff < bdaddr>
clock 读取本地时钟或远程设备的时钟 hcitool clock [bdaddr] [which clock]
BLE设备命令 以下命令需要root权限才能执行  
lescan 搜索BLE设备 hcitool lescan
    hcitool lescan[–privacy]启用隐私搜索
    hcitool lescan [–passive]默认参数,设置被动扫描
    hcitool lescan [–discovery=g/l] 设置搜索条件为综合设备或限制设备
    hcitool lescan [–duplicates]过滤重复的设备
lewladd 将设备加入BLE白名单 hcitool lewladd [–random] < bdaddr>可声明该设备的MAC地址为随机地址,有的BLE设备可以被设置为随机MAC地址以增加私密性,为以后也能连接到该MAC地址,需要声明MAC地址是随机,这样才能用旧的MAC地址连接到设备
lewlrm 将设备移除BLE白名单 hcitool lewlrm < bdaddr>
lewlsz 输出白名单设备列表 hcitool lewlsz
lewlclr 清空白名单列表 hcitool lewlclr
lecc 连接BLE设备 hcitool lecc < bdaddr>
    hcitool lecc [–random] < bdaddr>随机MAC地址连接
    hcitool lecc –whitelist 连接所有白名单设备
ledc 断开BLE设备的连接。在通过lecc链接后,hci工具会随机分配给该设备一个handle名,断开连接时需要使用该handle,因为在蓝牙4.0以后,一个蓝牙适配器可以连接7个BLE设备 hcitool ledc < handle> [reason]
lecup 更新BLE设备的连接及状态 hcitool lecup [Options]
  Options:  
    -H, –handle < 0xXXXX>指定更新状态的BLE设备Handle,在通过lecc链接后,hci工具会随机分配给该设备一个handle名
    -m, –min < interval> 设置设备蓝牙的休眠时间与–max联合使用,设置的区间为: 0x0006~0x0C80
    -M, –max < interval> 设置实例【hcitool lecup –handle 71 –min 6 –max 100】
    -l, –latency < range> 设置BLE数据传输速率,区间为: 0x0000~0x03E8
    -t, –timeout < time> N * 10ms 设置设备超时等待时间,区间为 0x000A~0x0C80
  备注: min/max参数区间为7.5ms到4s,误差在1.25ms,timeout的区间为100ms到32s

gattool命令及其参数

使用hcitool是为了对设备的连接进行管理,那么对BLE数据进行精细化管理的话,就需要用到gattool,使用gattool对蓝牙设备发送指令的操作上要比hcitool的cmd齐全很多,关于gattool的使用分为两种,一种直接使用参数对蓝牙设备进行控制,二就是使用-I参数进入gattool的interactive模式对蓝牙设备进行控制。

首先,看一下gattool的参数:

# gattool -h

Usage:
  gatttool [OPTION...]

Help Options:
  -h, --help                                Show help options
  --help-all                                Show all help options
  --help-gatt                               Show all GATT commands
  --help-params                             Show all Primary Services/Characteristics arguments
  --help-char-read-write                    Show all Characteristics Value/Descriptor Read/Write arguments


Application Options:
  -i, --adapter=hciX                        Specify local adapter interface
  -b, --device=MAC                          Specify remote Bluetooth address
  -t, --addr-type=[public | random]         Set LE address type. Default: public
  -m, --mtu=MTU                             Specify the MTU size
  -p, --psm=PSM                             Specify the PSM for GATT/ATT over BR/EDR
  -l, --sec-level=[low | medium | high]     Set security level. Default: low
  -I, --interactive                         Use interactive mode

具体含义如下:

参数说明调用方式
-i 指定适配器 gatttool -i < hciX> -b < MAC Address>
-b 指定远程设备,在连接多个设备的情况下需要指定控制某一设备 gatttool -b < bdaddr>
-t 指定设备的类型,是开放设备还是私密设备 gatttool -b < MAC Address> -t [public/random]
-m 设置数据包长度 -m MTU
–sec-leve 设置数据发送级别,默认情况下是low,需要高频发射数据的情况下需要将级别设置为high,但相应的耗电会上升 gatttool -b < MAC Address> -l [low/medium/high]
-I 进入interactive模式 gatttool -b < MAC Address> -I
  以下参数可以直接在interactive模式下使用,也可以在命令行直接使用  
–primary 寻找BLE中可用的服务 gatttool -b < MAC Address> –primary
–characteristics 查看设备服务的特性,其中handle是特性的句柄,char properties是特性的属性值,char value handle是特性值的句柄,uuid是特性的标识。 gatttool -b < MAC Address> –characteristics
–char-desc 配合查看服务特性使用,可以查看该设备所有服务特性的值,该值类型为键值对 gatttool –b < MAC Address> –char-desc [–uuid 0x000]可以通过设置UUID来查看某一特性的值
–char-write 更新特性的值,该更新类似于键值对,一个uuid匹配一个value gatttool -b –char-write –uuid [0x000] –value [0]
–char-write-req 读取notifications里的内容,可以设置listen来开启监听否则每次只读一次,监听读取notifications时需要向该handle写入一个1,在命令行中16进制的表示为0100,若向该handle写入0200的话则改为读取indications的内容 gatttool -b < MAC Address> –char-write-req –handle=0xXXXX –value=0100 –listen
  完整示例: gatttool -i hci0 -b aa:bb:cc:dd -t random –char-write-req -a 0x0039 -n 0100 –listen

 

 

蓝牙的使用:

BLE蓝牙的使用:

1、使能hci接口

# hciconfig hci0 up

2、使用hcitool搜索BLE设备

# hcitool lescan

LE Scan ...
D0:39:72:BE:D2:26 (unknown)
D0:39:72:BE:D2:26 HMDongle
D0:39:72:BE:D2:26 (unknown)

搜索到设备后按CTRL+C停止搜索,设备名称为HMDongle,是一个蓝牙串口设备,MAC地址为D0:39:72:BE:D2:26

3、使用gatttool连接设备

先查看gatttool的help

# gattool -h

Usage:
  gatttool [OPTION...]

Help Options:
  -h, --help                                Show help options
  --help-all                                Show all help options
  --help-gatt                               Show all GATT commands
  --help-params                             Show all Primary Services/Characteristics arguments
  --help-char-read-write                    Show all Characteristics Value/Descriptor Read/Write arguments


Application Options:
  -i, --adapter=hciX                        Specify local adapter interface
  -b, --device=MAC                          Specify remote Bluetooth address
  -t, --addr-type=[public | random]         Set LE address type. Default: public
  -m, --mtu=MTU                             Specify the MTU size
  -p, --psm=PSM                             Specify the PSM for GATT/ATT over BR/EDR
  -l, --sec-level=[low | medium | high]     Set security level. Default: low
  -I, --interactive                         Use interactive mode

 

使用interactive方式连接设备

# gatttool -b D0:39:72:BE:D2:26 -I

[   ][D0:39:72:BE:D2:26][LE]>

查看help

[   ][D0:39:72:BE:D2:26][LE]> help
help                                           Show this help
exit                                           Exit interactive mode
quit                                           Exit interactive mode
connect         [address [address type]]       Connect to a remote device
disconnect                                     Disconnect from a remote device
primary         [UUID]                         Primary Service Discovery
characteristics [start hnd [end hnd [UUID]]]   Characteristics Discovery
char-desc       [start hnd] [end hnd]          Characteristics Descriptor Discovery
char-read-hnd   <handle> [offset]              Characteristics Value/Descriptor Read by handle
char-read-uuid  <UUID> [start hnd] [end hnd]   Characteristics Value/Descriptor Read by UUID
char-write-req  <handle> <new value>           Characteristic Value Write (Write Request)
char-write-cmd  <handle> <new value>           Characteristic Value Write (No response)
sec-level       [low | medium | high]          Set security level. Default: low
mtu             <value>                        Exchange MTU for GATT/ATT
[   ][D0:39:72:BE:D2:26][LE]> 

连接设备

[   ][D0:39:72:BE:D2:26][LE]> connect
[CON][D0:39:72:BE:D2:26][LE]> 

连接成功之后命令行前面会有[CON]标识

查看设备提供的服务

[CON][D0:39:72:BE:D2:26][LE]> primary
[CON][D0:39:72:BE:D2:26][LE]> 
attr handle: 0x0001, end grp handle: 0x000b uuid: 00001800-0000-1000-8000-00805f9b34fb
attr handle: 0x000c, end grp handle: 0x000f uuid: 00001801-0000-1000-8000-00805f9b34fb
attr handle: 0x0010, end grp handle: 0xffff uuid: 0000ffe0-0000-1000-8000-00805f9b34fb

查看特性

[CON][D0:39:72:BE:D2:26][LE]> characteristics
[CON][D0:39:72:BE:D2:26][LE]> 
handle: 0x0002, char properties: 0x02, char value handle: 0x0003, uuid: 00002a00-0000-1000-8000-00805f9b34fb
handle: 0x0004, char properties: 0x02, char value handle: 0x0005, uuid: 00002a01-0000-1000-8000-00805f9b34fb
handle: 0x0006, char properties: 0x0a, char value handle: 0x0007, uuid: 00002a02-0000-1000-8000-00805f9b34fb
handle: 0x0008, char properties: 0x0a, char value handle: 0x0009, uuid: 00002a03-0000-1000-8000-00805f9b34fb
handle: 0x000a, char properties: 0x02, char value handle: 0x000b, uuid: 00002a04-0000-1000-8000-00805f9b34fb
handle: 0x000d, char properties: 0x20, char value handle: 0x000e, uuid: 00002a05-0000-1000-8000-00805f9b34fb
handle: 0x0011, char properties: 0x16, char value handle: 0x0012, uuid: 0000ffe1-0000-1000-8000-00805f9b34fb

其中handle是特性的句柄,char properties是特性的属性值,char value handle是特性值的句柄,uuid是特性的标识;

我想,可以把特性当作是设备特供的寄存器,寄存器会有属性,如只读、只写或可读可写,在蓝牙协议里面,还有notify的属性,当然,这个通知属性当作是寄存器的中断服务也是说得过去的;那么,第一个handle可以理解为寄存器的编号,第二个handle理解为寄存器的地址,properties即是寄存器属性,如果是可读可写,那么直接读写操作寄存器的地址即可。

上面列出了好多个特性,其中只有一个才是读写蓝牙串口的特性,很容易看得出来,它的uuid为ffe1,属性值为0x16,可读可写(without response)可通知。在这里,从蓝牙串口读取数据并不是直接去读取0x0012这个handle,而是通过notify获取数据,首先要使能notify功能,怎么使能呢,就是把特性值handle加1即0x0013,往这个0x0013handle写入0x0100,如:

[CON][D0:39:72:BE:D2:26][LE]> char-write-req 0x0013 0100  
[CON][D0:39:72:BE:D2:26][LE]> Characteristic value was written successfully

往handle写入十六进制值时不要带0x,不然会出错

[CON][D0:39:72:BE:D2:26][LE]> char-write-req 0x0013 0x0100
[CON][D0:39:72:BE:D2:26][LE]> Characteristic Write Request failed: Attribute value length is invalid

如果要向设备发送串口数据就直接往0x0012写入数据即可

[CON][D0:39:72:BE:D2:26][LE]> char-write-cmd 0x0012 48

posted @ 2018-06-03 11:30  陈晓猛  阅读(9185)  评论(0编辑  收藏  举报