最近入职一家公司做物联网模块,我负责手机蓝牙和设备通信模块。经过几天的摸索与实践,做一下笔记和分享。
一、理解BLE,先上理论
1.1简介
蓝牙是一种近距离无线通信技术。它的特性就是近距离通信,典型距离是 10 米以内,传输速度最高可达 24 Mbps,支持多连接,安全性高,非常适合用智能设备上。
1.2 蓝牙技术的版本演进
1999年发布1.0版本,目前市面上已很少见到;
2002年发布1.1版本,目前市面上已很少见到;
2004年发布2.0版本,目前市面上已很少见到;
2007年发布的2.1版本,是之前使用最广的,也是我们所谓的经典蓝牙。
2009年推出蓝牙 3.0版本,也就是所谓的高速蓝牙,传输速率理论上可高达24 Mbit/s;
2010年推出蓝牙4.0版本,它是相对之前版本的集大成者,它包括经典蓝牙、高速蓝牙和蓝牙低功耗协议。经典蓝牙包括旧有蓝牙协议,高速蓝牙基于Wi-Fi,低功耗蓝牙就是BLE。
2016年蓝牙技术联盟提出了新的蓝牙技术标准,即蓝牙5.0版本。蓝牙5.0针对低功耗设备速度有相应提升和优化,结合wifi对室内位置进行辅助定位,提高传输速度,增加有效工作距离,主要是针对物联网方向的改进。
1.3Android上BLE功能的逐步演进
在Android开发过程中,版本的碎片化一直是需要考虑的问题,再加上厂商定制及蓝牙本身也和Android一样一直在发展过程中,所以对于每一个版本支持什么功能,是我们需要知道的。
- Android 4.3 开始,开始支持BLE功能,但只支持Central Mode(中心模式)
- Android 5.0开始,开始支持Peripheral Mode(外设模式)
中心模式和外设模式是什么意思?
- Central Mode: Android端作为中心设备,连接其他外围设备。
- Peripheral Mode:Android端作为外围设备,被其他中心设备连接。在Android 5.0支持外设模式之后,才算实现了两台Android手机通过BLE进行相互通信。
1.4 理解GATT协议
大部分情况下,外设通过广播自己来让中心设备发现自己,并建立 GATT 连接,从而进行更多的数据交换。这里有且仅有两个角色,发起连接的一方,叫做中心设备—Central,被连接的设备,叫做外设—Peripheral。
- 外围设备:这一般就是非常小或者简单的低功耗设备,用来提供数据,并连接到一个更加相对强大的中心设备,例如小米手环。
- 中心设备:中心设备相对比较强大,用来连接其他外围设备,例如手机等。
GATT 连接需要特别注意的是:GATT 连接是独占的。也就是一个 BLE 外设同时只能被一个中心设备连接。一旦外设被连接,它就会马上停止广播,这样它就对其他设备不可见了。当设备断开,它又开始广播。中心设备和外设需要双向通信的话,唯一的方式就是建立 GATT 连接。
GATT 通信的双方是 C/S 关系。外设作为 GATT 服务端(Server),它维持了 ATT 的查找表以及 service 和 characteristic 的定义。中心设备是 GATT 客户端(Client),它向 Server 发起请求。需要注意的是,所有的通信事件,都是由客户端发起,并且接收服务端的响应。
1.5BLE通信基础
BLE通信的基础有两个重要的概念,ATT和GATT。
-
ATT
全称 attribute protocol,中文名“属性协议”。它是 BLE 通信的基础。ATT 把数据封装,向外暴露为“属性”,提供“属性”的为服务端,获取“属性”的为客户端。ATT 是专门为低功耗蓝牙设计的,结构非常简单,数据长度很短。 -
GATT
全称 Generic Attribute Profile, 中文名“通用属性配置文件”。它是在ATT 的基础上,对 ATT 进行的进一步逻辑封装,定义数据的交互方式和含义。GATT是我们做 BLE 开发的时候直接接触的概念。 -
GATT 层级
GATT按照层级定义了4个概念:配置文件(Profile)、服务(Service)、特征(Characteristic)和描述(Descriptor)。他们的关系是这样的:Profile 就是定义了一个实际的应用场景,一个 Profile包含若干个 Service,一个 Service 包含若干个 Characteristic,一个 Characteristic 可以包含若干 Descriptor。
-
Profile
Profile 并不是实际存在于 BLE 外设上的,它只是一个被 Bluetooth SIG 或者外设设计者预先定义的 Service 的集合。例如心率Profile(Heart Rate Profile)就是结合了 Heart Rate Service 和 Device Information Service。所有官方通过 GATT Profile 的列表可以从这里找到。 -
Service
Service 是把数据分成一个个的独立逻辑项,它包含一个或者多个 Characteristic。每个 Service 有一个 UUID 唯一标识。 UUID 有 16 bit 的,或者 128 bit 的。16 bit 的 UUID 是官方通过认证的,需要花钱购买,128 bit 是自定义的,这个就可以自己随便设置。官方通过了一些标准 Service,完整列表在这里。以 Heart Rate Service为例,可以看到它的官方通过 16 bit UUID 是0x180D
,包含 3 个 Characteristic:Heart Rate Measurement, Body Sensor Location 和 Heart Rate Control Point,并且定义了只有第一个是必须的,它是可选实现的。 -
Characteristic
需要重点提一下Characteristic, 它定义了数值和操作,包含一个Characteristic声明、Characteristic属性、值、值的描述(Optional)。通常我们讲的 BLE 通信,其实就是对 Characteristic 的读写或者订阅通知。比如在实际操作过程中,我对某一个Characteristic进行读,就是获取这个Characteristic的value。 -
UUID
Service、Characteristic 和 Descriptor 都是使用 UUID 唯一标示的。UUID 是全局唯一标识,它是 128bit 的值,为了便于识别和阅读,一般以 “8位-4位-4位-4位-12位”的16进制标示,比如“12345678-abcd-1000-8000-123456000000”。
但是,128bit的UUID 太长,考虑到在低功耗蓝牙中,数据长度非常受限的情况,蓝牙又使用了所谓的 16 bit 或者 32 bit 的 UUID,形式如下:“0000XXXX-0000-1000-8000-00805F9B34FB”。除了 “XXXX” 那几位以外,其他都是固定,所以说,其实 16 bit UUID 是对应了一个 128 bit 的 UUID。这样一来,UUID 就大幅减少了,例如 16 bit UUID只有有限的 65536(16的四次方) 个。与此同时,因为数量有限,所以 16 bit UUID 并不能随便使用。蓝牙技术联盟已经预先定义了一些 UUID,我们可以直接使用,比如“00001011-0000-1000-8000-00805F9B34FB”就一个是常见于BLE设备中的UUID。当然也可以花钱定制自定义的UUID。
1.6通讯原理
是一步步的通过uuid找到服务、在服务中通过uuid找Characteristic、再通过uuid找到Descriptor。
二、制定自己的通讯协议
Android要和设备通讯,要有自己的通讯协议,其实也是符合自己的传输规则。因为设备数据量特别小,都是以字节来衡量的。我们的制定的协议是参考“以太网”,当然没有它们那么复杂,具体确定要和嵌入式软件工程师协商确定,也是根据项目的业务。参考以太网:
图片.png
三、代码实践
蓝牙其实有很多坑,避免采坑,我找了开源项目,github有很多BLE开源的项目。
比如:
android-lite-bluetoothLE
FastBle
我使用的就是FastBle,阅读https://www.jianshu.com/p/795bb0a08beb文档足以解决。
网友评论