蓝牙4.0版本推出了低功耗规范,简称BLE (Bluetooth Low Energy),很多小型设备,例如小米手环,都是使用低功耗蓝牙。要与这类模块连接,主设备的蓝牙模块必须支持低功耗,例如intel 2230:

现在有一个BLE的透传模块,会不断的发出数据,我的主机安装了Linux,使用intel 2230接收数据。协议栈依然是BlueZ。

1. GATT协议

BLE 连接都是建立在GATT协议之上的。介绍GATT之前,需要了解GAP(Generic

Access Profile)。它在用来控制设备连接和广播。GAP使你的设备被其他设备可见,并决定了你的设备是否可以或者怎样与合同设备进行交互。GAP给设备定义了若干角色,其中主要的两个是:外围设备(Peripheral)和中心设备(Central),外设必须不停的向外广播,让中心设备知道它的存在。中心设备扫描到外设后,发起并建立GATT连接。

GATT 连接是独占的,也就是一个BLE外设同时只能被一个中心设备连接。一旦外设被连接,它就会马上停止广播。中心设备和外设需要双向通信的话,唯一的方式就是建立GATT连接。一个外设只能连接一个中心设备,而一个中心设备可以连接多个外设。GATT定义BLE通信的双方是C/S关系,外设作为服务端(Server),也叫从设备(Slave),中心设备是客户端(Client),也叫主设备(Master)。所有的通信事件,都是由Client发起请求,Server作出响应。但GATT还有两个特性:notification和indication。这意味着server可以主动发出通知和指示,使client端不用轮询。

GATT 是一个在蓝牙连接之上的发送和接收很短的数据段的通用规范(ATT),这些很短的数据段被称为属性(Attribute)。一个attribute由三种元素组成:

一个16位的句柄(handle)

一个定长的值(value)

一个UUID,定义了attribute的类型,value的意义完全由UUID决定。

attribute 的handle具有唯一性,仅用作区分不用的attribute(因为可能有很多不同的attribute拥有相同的UUID)

Attribute 只存储在Server端,多个attribute构成一个characteristic(特征值),一个或多个characteristic构成一个Service (服务),一个BLE设备可以有多个Service,Service是把数据分成一个个的独立逻辑项。

一个GATT Service始于UUID为0x2800的attribute,直到下一个UUID为0x2800的attribute为止。范围内的所有attribute都属于该服务的。例如,一台有三种服务的设备拥有如下所示的attribute布局:

Handle

UUID

Description

Value

0x0100

0x2800

ServiceA definition

0x1816 (UUID)

...

...

Servicedetails

...

0x0150

0x2800

ServiceB definition

0x18xx

...

...

Servicedetails

...

0x0300

0x2800

ServiceC definition

0x18xx

...

...

Servicedetails

...

handle 具有唯一性,属于Service B的attribute的handle范围肯定落在0x0151和0x02ff之中。那么,我如何知道一个Service是温度检测,还是GPS呢?通过读取该Service的attribute的value。UUID为0x2800的attribute作为Service的起始标志,它的value就是该服务的UUID,是该服务的唯一标识,表示了该服务的类型。UUID有16 bit的,或者128 bit的。16 bit的UUID是官方通过认证的,需要购买,128 bit是自定义的,这个就可以自己随便设置。

每个Service都包含一个或多个characteristic(特征值)。这些characteristic负责存储Service的数据和访问权限。每个Characteristic用16 bit或者128

bit的UUID唯一标识。例如,一个温度计(service)一般会有一个只读的“温度”characteristic,和一个可读写的“日期时间”characteristic:

Handle

UUID

Description

Value

0x0100

0x2800

Thermometer service definition

UUID 0x1816

0x0101

0x2803

Characteristic: temperature

UUID 0x2A2B,Value handle:

0x0102

0x0102

0x2A2B

Temperature value

20 degrees

0x0110

0x2803

Characteristic: date/time

UUID 0x2A08,Value handle:

0x0111

0x0111

0x2A08

Date/Time

1/1/1980 12:00

可以看到,handle 0x0101定义了一个“温度”characteristic,该characteristic的UUID是0x2A2B,它的值位于handle 0x0102。

除了value,还可以在characteristic的附加attribute里获取到其它信息。这些附加的attribute称为descriptor。例如,当我们我们需要明确温度计的计量单位时,可以通过添加一个descriptor来实现:

Handle

UUID

Description

Value

0x0100

0x2800

Thermometer service definition

UUID 0x1816

0x0101

0x2803

Characteristic: temperature

UUID 0x2A2B,Value handle:

0x0102

0x0102

0x2A2B

Temperature value

20 degrees

0x0104

0x2A1F

Descriptor: unit

Celsius

0x0110

0x2803

Characteristic: date/time

UUID 0x2A08,Value handle:

0x0111

0x0111

0x2A08

Date/Time

1/1/1980 12:00

GATT 知道handle 0x0104是属于characteristic 0x0101的descriptor,因为:

它不是一个value

attribute,因为value attribute已经指明是handle 0x0102

它刚好在0x0103..0x010F的范围内,两个characteristic之间

每个service都可以自定义desctiptor,GATT已经预定义了一系列常用的desctiptor:

数据格式和表达方式

可读性描述

有效范围

扩展属性

其中一个很重要的descriptor是client characteristic configuration,简称CCC descriptor,它的UUID是0x2902,有一个可读性的16位Value,低两位已经被占用,用于配置characteristic的notification和indication:

Bit 0 设为1表示使能Notification

Bit 1 设为1表示使能Indication

对于具有Notify属性的characteristic,使能Notification后,数据发生变化时会主动通知Client端,Client端只要监听即可。

2. Linux中的操作

在BlueZ中就要用hcitool lescan 命令扫描低功耗蓝牙设备:

root@WR-IntelligentDevice:~#

hcitool lescan

LE Scan ...

20:91:48:6B:65:08 (unknown)

20:91:48:6B:65:08

SPP_2091486B6508

gatttool 是用来访问BLE设备的命令,用gatttool -b 20:91:48:6B:65:08 -I 打开一个与远程设备的会话,-I表示交互模式:

root@WR-IntelligentDevice:~#

gatttool -b 20:91:48:6B:65:08 -I

[   ][20:91:48:6B:65:08][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   [offset]              Characteristics Value/Descriptor

Read by handle

char-read-uuid  [start hnd] [end hnd]   Characteristics Value/Descriptor Read by

UUID

char-write-req  Characteristic Value Write (Write

Request)

char-write-cmd  Characteristic Value Write (No

response)

sec-level       [low | medium | high]          Set security level. Default: low

mtu             Exchange MTU for

GATT/ATT

[   ][20:91:48:6B:65:08][LE]>

connect 表示连接远程设备,连接成功后,提示符签名的状态会显示"CON" :

[   ][20:91:48:6B:65:08][LE]> connect

[CON][20:91:48:6B:65:08][LE]>

primary 命令会列出远程设备上所有的Service,每个服务所在的handle范围:

[CON][20:91:48:6B:65:08][LE]>

primary

[CON][20:91:48:6B:65:08][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: 0x0017 uuid: 0000fee7-0000-1000-8000-00805f9b34fb

attr handle: 0x0018, end grp

handle: 0x001b uuid: 0000fee0-0000-1000-8000-00805f9b34fb

attr handle: 0x001c, end grp

handle: 0x0024 uuid: f000ffc0-0451-4000-b000-000000000000

attr handle: 0x0025, end grp

handle: 0x002f uuid: 0000ccc0-0000-1000-8000-00805f9b34fb

attr handle: 0x0030, end grp

handle: 0xffff uuid: 0000180a-0000-1000-8000-00805f9b34fb

用primary fee7 查看UUID为0xfee7的Service,执行characteristics 0x0010 0x0017 可以发现它有三个characteristics:

[CON][20:91:48:28:26:AF][LE]>

primary fee7

[CON][20:91:48:28:26:AF][LE]>

Starting handle: 0x0010 Ending

handle: 0x0017

[CON][20:91:48:28:26:AF][LE]>

characteristics 0x0010 0x0017

[CON][20:91:48:28:26:AF][LE]>

handle: 0x0011, char properties:

0x20, char value handle: 0x0012, uuid: 0000fec8-0000-1000-8000-00805f9b34fb

handle: 0x0014, char properties:

0x0a, char value handle: 0x0015, uuid: 0000fec7-0000-1000-8000-00805f9b34fb

handle: 0x0016, char properties:

0x02, char value handle: 0x0017, uuid: 0000fec9-0000-1000-8000-00805f9b34fb

char properties 表示characteristic的属性,char value handle表示characteristic的值所在的attribute的handle。下面是characteristic properties的说明:

现在远程设备上有一个透传服务是0xFEE0,传输数据的特征值是0xFEE1,可以用如下方式查看:

[CON][20:91:48:6B:65:08][LE]>

primary 0xfee0

[CON][20:91:48:6B:65:08][LE]>

Starting handle: 0x0018 Ending

handle: 0x001b

[CON][20:91:48:6B:65:08][LE]>

characteristics  0x0018 0x001b

[CON][20:91:48:6B:65:08][LE]>

handle: 0x0019, char properties:

0x14, char value handle: 0x001a, uuid: 0000fee1-0000-1000-8000-00805f9b34fb

[CON][20:91:48:6B:65:08][LE]>

char-desc 0x0018 0x001b

[CON][20:91:48:6B:65:08][LE]>

handle: 0x0018, uuid: 2800

handle: 0x0019, uuid: 2803

handle: 0x001a, uuid: fee1

handle: 0x001b, uuid: 2902

首先执行primary 0xfee0 ,发现该服务包含handle

0x0018到handle 0x001b之间的attribute。然后用characteristics 0x0018 0x001b 发现该服务有一个characteristic,它的值在handle 0x001a,属性是0x14,表示可写无回复/通知(Write

without response/Notify)。最后用char-desc 0x0018 0x001b 列出该特征值的所有Descriptor,最后一个UUID为0x2902,是一个CCC Descriptor,读取它当前的值:

[CON][20:91:48:28:26:AF][LE]>

char-read-hnd 0x001b

[CON][20:91:48:28:26:AF][LE]>

Characteristic value/descriptor:

00 00

通过handle读写的好处是准确,因为handle具有唯一性。如果执行char-read-uuid 0x2902 ,就会发现列出了很多个attribute。

当前的值是0,这个characteristic的属性是Notify,所以要向handle 0x001b写入0x0100(X86是小端),使能Notify,然后就会不停的收到数据:

[CON][20:91:48:28:26:AF][LE]>

char-write-req 0x001b 0100

[CON][20:91:48:28:26:AF][LE]>

Characteristic value was written successfully

Notification handle = 0x001a

value: 41 47 3a 20 37 30 34 38 20 37 30 39 35 20 36 30 20 2d 31 37

[CON][20:91:48:28:26:AF][LE]>

Notification handle = 0x001a

value: 20 2d 32 31 33 20 39 34 36 20 2d 39 33 30 20 2d 31 39 36 20

[CON][20:91:48:28:26:AF][LE]>

Notification handle = 0x001a

value: 39 33 38 20 2d 39 33 30 0a 41 47 3a 20 37 30 34 31 20 37 31

[CON][20:91:48:28:26:AF][LE]>

在非交互模式下,用--listen 选项启动监听模式来接收通知:

root@WR-IntelligentDevice:~#

gatttool -b 20:91:48:28:26:AF --char-write-req --handle=0x001b --value=0100

--listen

Characteristic value was written

successfully

Notification handle = 0x001a

value: 32 30 37 32 20 35 33 32 39 20 34 32 39 35 20 41 47 3a 20 2d

Notification handle = 0x001a

value: 32 30 37 36 20 35 33 32 36 20 34 33 30 30 20 41 47 3a 20 2d

Notification handle = 0x001a

value: 32 30 37 38 20 35 33 32 37 20 34 33 30 35 20 41 47 3a 20 2d

3.参考

Linux卸载蓝牙模块,Linux 下调试低功耗蓝牙的笔记相关推荐

  1. linux卸载光驱模块,linux挂载光驱和卸载光驱_无需整理

    自我总结: 确定光盘路径               ls -l /dev  | grep cdrom 根据光盘路径去挂载      mount /dev/cdrom   /mnt/         ...

  2. 蓝牙模块HC-05的调试(利用LED灯来检验信号是否能正常传输)

    蓝牙模块HC-05的调试(利用LED灯来检验信号是否能正常传输) by hasyu 我所用到的硬件 BlueTooth HC-05,arduino 2560(uno也行吧) 电脑 手机 硬件的连接 不 ...

  3. 利尔达e95蓝牙模块程序_Arduino使用HC05蓝牙模块与手机连接

    通过本文,可以了解到以下内容: 进入 AT 模式进行蓝牙基本参数设置 Arduino 蓝牙控制 LED 电路设计以及代码编写 利用 Andorid 蓝牙串口调试软件测试功能 进入 At 模式进行蓝牙基 ...

  4. 20220727使用汇承科技的蓝牙模块HC-05配对手机进行蓝牙串口的演示

    20220727使用汇承科技的蓝牙模块HC-05配对手机进行蓝牙串口的演示 2022/7/27 18:55 Android11:摩托罗拉 motorola edge s 6GB+128GB 骁龙870 ...

  5. 怎么在linux卸载mysql,在linux中安装和卸载mysql

    [安装] 已经获取到linux版本的mysql安装包,包括mysql的server(服务端)和client(客户端)的安装包,假设安装包为: MySQL-server-5.0.22-0.i386.rp ...

  6. HC-05蓝牙模块AT指令调试

    HC-05蓝牙模块在AT模式下的波特率和正常模式下的波特率不是一回事,在AT模式下的波特率是我们没办法进行修改的,他永远都是固定的38400,而在正常模式下的波特率我们是可以在AT模式下通过AT指令集 ...

  7. win10下pyqt5低功耗蓝牙系列一:开发环境搭建

    1.序言 之前在网上搜索关于python实现低功耗蓝牙(BLE)的案例,基本都是让安装pybluez等之类的工具,实测发现基本行不通,具体原因也不记得了,折腾了将近一个星期时间.这两天看Qt的QtBl ...

  8. HC-05蓝牙模块学习(两个蓝牙模块连接互发信息)

    目录 1.进入AT模式和连接前注意事项 2.实现两个蓝牙完美配对 3.HC-05_1初始化配置 4.HC-05_2初始化配置 5.HC-05_1与HC-05_2绑定 6.设置模块通信波特率&通 ...

  9. feasycom蓝牙对接Android,2.4G低功耗蓝牙解决方案

    2.4G低功耗无线传输应用始于千年,并逐渐渗透到生活的各个方面.当时,由于功耗性能和蓝牙技术问题,在许多市场中,例如游戏手柄,遥控赛车,键盘和鼠标配件等,主要使用专用的2.4G应用程序.在2011年之 ...

最新文章

  1. usb调试模式已打开,adb devices显示List of devices attached 解决办法!纽维K333一键ROOT,获取ROOT权限!...
  2. 第一周Access课总结
  3. 1049 Counting Ones
  4. vsftpd安装配置
  5. 概率分布,先懂这6个
  6. pidstat 命令查看某个进程的CPU、内存、磁盘使用情况
  7. [USACO08JAN]跑步Running
  8. 围绕央行系统升级所产生的常见问题
  9. k8s架构及服务详解
  10. 学习SQL 的网址集合
  11. EasyRecovery深度扫描以恢复桌面遗失数据的方法
  12. 1688商品类目API接口-(item_cat_get-获得1688商品类目接口)
  13. Matlab的自相关函数corr
  14. 队列元素逆置 数据结构 队列
  15. Cinema DNG raw视频处理
  16. matlab中syms x是什么意思,matlab中怎样定义未知数,如x,syms是什么意思?
  17. redis安装和基本数据类型
  18. PCIe TLP详解
  19. vue 插件qs使用
  20. 计算机与科学hh,Mary-第十六届和谐人机环境联合学术会议 (HHME2020)

热门文章

  1. 【量化投资】策略三(聚宽)
  2. 2019牛客第四场I题 string
  3. 14.4 线程通讯-生产者与消费者
  4. 第十讲 二阶齐次常系数线性ODE(续)
  5. mysql修改密码的三种方式
  6. 不厌其烦的四大集成电路
  7. Selector-背景选择器
  8. 【基环树DP】[NOI2012]迷失游乐园
  9. BringWindowToTop(), SetForegroundWindow(), SetActiveWindow()
  10. HTML5与HTML4的区别