蓝牙基础
参考
https://www.jianshu.com/p/3a372af38103
蓝牙版本的介绍
深入了解Android蓝牙Bluetooth——《基础篇》 (qq.com)
蓝牙发展至今经历了8个版本的更新。1.1、1.2、2.0、2.1、3.0、4.0、4.1、4.2、5.0。
那么在1.x~3.0之间的我们称之为传统蓝牙,
4.x开始的蓝牙我们称之为低功耗蓝牙也就是蓝牙ble,当然4.x版本的蓝牙也是向下兼容的。
android手机必须系统版本4.3及以上才支持BLE API。
蓝牙各版本间区别
- 蓝牙1.0:传输速率约1M/s。
- 蓝牙2.0+EDR:传输速率约2-3M/s,其中2.1+EDR是最经典的蓝牙,最大的特点是安全简易配对。
- 蓝牙3.0+HS(高传输蓝牙):高传输24M/s,只有标注了"+HS"商标的设备才是真正支持802.11高速数据传输。
- 蓝牙4.0(低功耗蓝牙):它包括经典蓝牙、高速蓝牙和蓝牙低功耗协议,在3.0基础上功耗更低,主要面向对功耗需求极低、用纽扣电池供电的应用。
- 蓝牙5.0:4 倍通讯距离,2 倍传输速度,8 倍广播资料传输量
现在主流 4.0BLE蓝牙
蓝牙4.0有几种模式,如果是蓝牙4.0低功耗模式单模的设备(常称为BLE模式),是不向下兼容的。
- 低功耗蓝牙比传统蓝牙,传输速度更快,覆盖范围更广,安全性更高,延迟更短,耗电极低等等优点
- 传统的一般通过socket方式,而低功耗蓝牙是通过Gatt协议来实现。
若是之前没做过传统蓝牙开发,也是可以直接上手低功耗蓝牙开发的。因为它们在通信协议上都有所改变,关联不大。
那么我们现在所处的4.x的设备大多是属于主从模式的。
什么是主从模式
一个主设备比如手机,一个从设备(这里也成为子设备或从机)
主设备搜索从机,可以发送,也可以接收,
从机也可以发送和接收,但只能被搜索
蓝牙协议规范
https://www.bluetooth.com/specifications/archived-specifications/
蓝牙GATT协议介绍
http://murata.eetrend.com/article/2017-11/1000980.html
https://blog.csdn.net/u013378580/article/details/52891462
一、 引言
现在低功耗蓝牙(BLE buletouch low energy)连接都是建立在 GATT (Generic Attribute Profile) 协议之上。GATT 是一个在蓝牙连接之上的发送和接收很短的数据段的通用规范,这些很短的数据段被称为属性(Attribute)。
从图中我们可以清晰看出广播数据和扫描回复数据是怎么工作的。
外围设备会设定一个广播间隔,每个广播间隔中,它会重新发送自己的广播数据。广播间隔越长,越省电,同时也不太容易扫描到。
一旦建立起了连接,通信就是双向的了,对比前面的 GAP 广播的网络拓扑,GAP 通信是单向的。如果你要让两个设备外设能通信,就只能通过中心设备中转。
- Profile
- Profile
并不是实际存在于 BLE 外设上的,它只是一个被 Bluetooth SIG 或者外设设计者预先定义的 Service 的集合。
例如心率Profile(Heart Rate Profile)就是结合了 Heart Rate Service 和 Device Information Service。
一个设备可以实现多个配置文件。例如,一个设备可能包括心率监测仪和电量检测。
- Service
每个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 ControPoint,并且定义了只有第一个是必须的,它是可选实现的。
service可以理解为一个服务,在ble从机中,通过有多个服务,例如电量信息服务、系统信息服务等,每个service中又包含多个characteristic特征值。每个具体的characteristic特征值才是ble通信的主题。比如当前的电量是80%,所以会通过电量信息服务的characteristic特征值存在从机的profile里,这样主机就可以通过这个characteristic来读取80%这个数据。
你可以在bluetooth.org 找到一个目前支持的基于GATT的配置文件和服务列表。
- Characteristic
在 Service 下面,又包括了许多的独立数据项,我们把这些独立的数据项称作 Characteristic,
一个characteristic包括一个单一变量和0-n个用来描述characteristic变量的descriptor。
与 Service 类似,每个 Characteristic 用 16 bit 或者 128 bit 的 UUID 唯一标识。你可以免费使用 Bluetooth SIG 官方定义的标准 Characteristic,使用官方定义的,可以确保 BLE 的软件和硬件能相互理解。当然,你可以自定义 Characteristic,这样的话,就只有你自己的软件和外设能够相互理解。
举个例子, Heart Rate Measurement Characteristic,这是上面提到的 Heart Rate Service 必需实现的 Characteristic,它的 UUID 是 0x2A37。它的数据结构是,开始 8 bit 定义心率数据格式(是UINT8 还是 UINT16?),接下来就是对应格式的实际心率数据。
实际上,和 BLE 外设打交道,主要是通过 Characteristic。你可以从 Characteristic 读取数据,也可以往 Characteristic 写数据。这样就实现了双向的通信。所以你可以自己实现一个类似串口(UART)的 Sevice,这个 Service 中包含两个 Characteristic,一个被配置只读的通道(RX),另一个配置为只写的通道(TX)。
在 Android 开发中,建立蓝牙连接后,我们说的通过蓝牙发送数据给外围设备就是往这些 Characteristic 中的 Value 字段写入数据;外围设备发送数据给手机就是监听这些 Charateristic 中的 Value 字段有没有变化,如果发生了变化,手机的 BLE API 就会收到一个监听的回调。
- Descriptor
Descriptor用来描述characteristic变量的属性。
每个characteristic可以对应一个或多个Description用于描述characteristic的信息或属性
例如,一个descriptor可以规定一个人类可读的可读的描述,或者一个characteristic变量可接受的范围,或者一个characteristic变量特定的测量单位。
每个包都是 31 字节,数据包中分为有效数据(significant)和无效数据(non-significant)两部分。
- 有效数据部分 :包含若干个广播数据单元,每个数据单元称为 AD Structure 。
如图中所示,AD Structure 的组成是:
-
- 第一个字节是长度值 Len ,表示接下来的 Len 个字节是数据部分。
- 数据部分的第一个字节表示数据的类型 AD Type ,剩下的 Len - 1 个字节是真正的数据 AD data 。
- 其中 AD type 非常关键,决定了 AD Data 的数据代表的是什么和怎么解析,这个在后面会详细讲;
- 无效数据部分 :
因为广播包的长度必须是 31 个 byte,如果有效数据部分不到 31 byte,剩下的就用 0 补全。这部分的数据是无效的,解释的时候,忽略即可。
The non-significant part extends the data when necessary and shalcontain all-zero octets
AD Type 包括如下类型
https://blog.csdn.net/slimmm/article/details/100583655
https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile/
定义 |
说明 |
备注 |
#define GAP_ADTYPE_FLAGS 0x01 |
Discovery Mode: @ref GAP_ADTYPE_FLAGS_MODES |
flag说明了物理连接功能,比如有限发现模式,不支持经典蓝牙等。 bit 0: LE 有限发现模式。 bit 1: LE 普通发现模式。 bit 2: 不支持 BR/EDR。 bit 3: 对 Same Device Capable(Controller) 同时支持 BLE 和 BR/EDR。 bit 4: 对 Same Device Capable(Host) 同时支持 BLE 和 BR/EDR。 bit 5..7: 预留。 |
#define GAP_ADTYPE_16BIT_MORE 0x02 |
Service: More 16-bit UUIDs available |
Service UUID: 广播数据中一般都会把设备支持的 GATT Service 广播出来,用来告诉外面本设备所支持的 Service。有三种类型的 UUID:16 bit, 32bit, 128 bit。广播中,每种类型类型有有两个类别:完整和非完整的。这样就共有 6 种 AD Type。 |
#define GAP_ADTYPE_16BIT_COMPLETE 0x03 |
Service: Complete list of 16-bit UUIDs |
服务的 UUID,通知中央设备什么服务包括在此外围设备 |
#define GAP_ADTYPE_32BIT_MORE 0x04 |
Service: More 32-bit UUIDs available |
服务的 UUID,通知中央设备什么服务包括在此外围设备 |
#define GAP_ADTYPE_32BIT_COMPLETE 0x05 |
Service: Complete list of 32-bit UUIDs |
服务的 UUID,通知中央设备什么服务包括在此外围设备 |
#define GAP_ADTYPE_128BIT_MORE 0x06 |
Service: More 128-bit UUIDs available |
服务的 UUID,通知中央设备什么服务包括在此外围设备 |
#define GAP_ADTYPE_128BIT_COMPLETE 0x07 |
Service: Complete list of 128-bit UUIDs |
服务的 UUID,通知中央设备什么服务包括在此外围设备 |
#define GAP_ADTYPE_LOCAL_NAME_SHORT 0x08 |
Shortened locaname |
简称 |
#define GAP_ADTYPE_LOCAL_NAME_COMPLETE 0x09 |
Complete locaname |
完整名称 |
#define GAP_ADTYPE_POWER_LEVE0x0A |
TX Power Level: 0xXX: -127 to +127 dBm |
发送功率 |
#define GAP_ADTYPE_OOB_CLASS_OF_DEVICE 0x0D |
Simple Pairing OOB Tag: Class of device (3 octets) |
out-of-band,OOB- 带外数据 |
#define GAP_ADTYPE_OOB_SIMPLE_PAIRING_HASHC 0x0E |
Simple Pairing OOB Tag: Simple Pairing Hash C (16 octets) |
简单配对OOB标签:简单配对散列C |
#define GAP_ADTYPE_OOB_SIMPLE_PAIRING_RANDR 0x0F |
Simple Pairing OOB Tag: Simple Pairing Randomizer R (16 octets) |
简单配对OOB标签:简单配对随机器R |
#define GAP_ADTYPE_SM_TK 0x10 |
Security Manager TK Value |
安全管理器TK值 |
#define GAP_ADTYPE_SM_OOB_FLAG 0x11 |
Security Manager OOB Flags |
安全管理器OOB标志 |
#define GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE 0x12 |
Min and Max values of tde connection interva(2 octets Min, 2 octets Max) (0xFFFF indicates no conn intervamin or max) |
从机连接间隔的最小值和最大值 |
#define GAP_ADTYPE_SIGNED_DATA 0x13 |
Signed Data field |
签名数据字段 |
#define GAP_ADTYPE_SERVICES_LIST_16BIT 0x14 |
Service Solicitation: list of 16-bit Service UUIDs |
服务搜寻:外围设备可以要请中心设备提供相应的 Service |
#define GAP_ADTYPE_SERVICES_LIST_128BIT 0x15 |
Service Solicitation: list of 128-bit Service UUIDs |
服务征集:128位服务uuid列表 |
#define GAP_ADTYPE_SERVICE_DATA 0x16 |
Service Data - 16-bit UUID |
服务数据- 16位UUID |
#define GAP_ADTYPE_PUBLIC_TARGET_ADDR 0x17 |
Public Target Address |
公共目标地址 |
#define GAP_ADTYPE_RANDOM_TARGET_ADDR 0x18 |
Random Target Address |
随机目标地址 |
#define GAP_ADTYPE_APPEARANCE 0x19 |
Appearance |
外观特性 |
#define GAP_ADTYPE_ADV_INTERVA0x1A |
Advertising Interval |
广播时间间隔 |
#define GAP_ADTYPE_LE_BD_ADDR 0x1B |
LE Bluetootd Device Address |
LE 蓝牙设备地址 |
#define GAP_ADTYPE_LE_ROLE 0x1C |
LE Role |
LE 角色 |
#define GAP_ADTYPE_SIMPLE_PAIRING_HASHC_256 0x1D |
Simple Pairing Hash C-256 |
简单配对哈希C-256 |
#define GAP_ADTYPE_SIMPLE_PAIRING_RANDR_256 0x1E |
Simple Pairing Randomizer R-256 |
简单配对随机发生器R-256 |
#define GAP_ADTYPE_SERVICE_DATA_32BIT 0x20 |
Service Data - 32-bit UUID |
服务数据- 32位UUID |
#define GAP_ADTYPE_SERVICE_DATA_128BIT 0x21 |
Service Data - 128-bit UUID |
服务数据- 128位UUID |
#define GAP_ADTYPE_3D_INFO_DATA 0x3D |
3D Information Data |
三维信息数据 |
#define GAP_ADTYPE_MANUFACTURER_SPECIFIC 0xFF |
Manufacturer Specific Data: first 2 octets contain tde Company Identifier Code followed by tde additionamanufacturer specific data |
特定于制造商的数据: 前两个字节包含设备公司标识码, 然后是设备附加的特定于制造商的数据 |
16bit 转为128 bit uuid
https://www.cnblogs.com/Free-Thinker/p/11375265.html
熟悉BLE技术同学应该对UUID不陌生,服务、特征值、描述都是有UUID格式定义。
蓝牙广播中对服务UUID格式定义都有三种16 bit UUID、32 bit UUID、128 bit UUID。
但是熟悉安卓开发的小伙伴都知道接口都UUID格式,fromString时候16bit的UUID该咋办呢?
16bit和32bit的UUID与128bit的值之间转换关系:
128_bit_UUID = 16_bit_UUID * 2^96 + Bluetooth_Base_UUID
128_bit_UUID = 32_bit_UUID * 2^96 + Bluetooth_Base_UUID
其中 Bluetooth_Base_UUID定义为 00000000-0000-1000-8000-00805F9B34FB
如果你想说这是啥呀,那我这样说你应该可以明白点:
若16 bit UUID为xxxx,那么128 bit UUID为0000xxxx-0000-1000-8000-00805F9B34FB
若32 bit UUID为xxxxxxxx,那么128 bit UUID为xxxxxxxx-0000-1000-8000-00805F9B34FB