BLE协议简介
GATT
句柄handle和UUID
1、属性句柄——handle:区分数据的属性,是温度?设备名称?
2、属性类型——uuid:区分数据的类型,是温度?时间?体积类型?
3、蓝牙技术联盟UUIDS
4、供应商特定的UUID
虚拟环境的创建及使用
模拟智能门锁
1、 环境:树莓派3
2、创建虚拟门锁
3、安装控制客户端
使用
1、开启虚拟智能门
2、连接
GATT是BLE里面的通用属性协议,属于HOST层,关系到应用层数据的传输,为属性协议的传输和存储数据建议一些通用的操作和框架,其中的数据都是实际发送的,也就是蓝牙事件所产生的协议栈事件都是在这里发生的。
该框架定义了服务(Server)和服务属性(characteristic)的过程(Procedure)及格式。
总体架构如下:
GATT中最上层是Profile,Profile由一个或多个服务(Service)组成,服务是由Characteristics组成,或是其他服务的引用 (Reference),Characteristic包含一个值(Value),可能包含该Value的相关信息。
服务是数据和完成设备或设备的某些部分的特定功能或特征的相关行为的集合。服务可能涉及其它主要或次要服务或构成该服务的特征集合。
服务分为两种类型:主要服务和次要服务。主要服务提供设备的主要功能。次要服务提供设备的辅助功能,引用自该设备至少一项主要服务。
特征,连同属性和有关如何访问该值的配置信息以及有关如何显示或表述该值的信息,是用于服务的值。特征定义包含特征声明、特征属性和值。它还可能包含描述该值或允许服务器配置有关特征值的描述符。
Procedure定义了characteristic的发现、读、写、通知(Notifing)、指示(Indicating) 及配置characteristic的广播。
1、属性句柄——handle:
区分数据的属性,是温度?设备名称?
一台设备可以有许多的属性,例如温度传感器可能包含温度属性、设备名称属性和电池电量属性。表面看来,通过属性类型似乎足以判别某种属性。比如使用温度属性来获取温度,通过设备名称属性来获取设备名等。但是,如果设备包含了两种温度属性,比如一个室内温度传感器加上室外温度传感器,情况会变得怎样。这时你便无法直接读取温度传感器,而必须读取第一个或第二个温度属性。考虑到可能有任意多个温度传感器,问题将变得更加复杂。为了解决这个同题,我们使用了一个16位的地址,也就是属性句柄。有效的句柄范围从0x0001–xFFFF。0x0000为无效句柄,不能用于寻址属性。
2、属性类型——uuid:
区分数据的类型,是温度?时间?体积类型?
可以被公开的数据有许许多多的类型:温度、压强、体积、距离、功率、时间、充电状态、开关状态、状态机的状态等。 所公开的数据的种类称作属性类型。为了区分如此多的数据类型,一串128位的数字被用来标识属性的类型。这个唯一标识码就叫做通用唯一识别码(UUID),128位的UUID相当长,设备间为了识别数据的类型需要发送长达16个字节的数 据。为了提高传输效率,蓝牙技术联盟( SIG)定义了一种称为“蓝牙UUID基数”的128位通用唯一识别码,结合一个较短的16位数使用。二者仍然遵循通用唯一识别码的分配规则,只不过在设备间传输常用的UUID时,只发送较短的16位版本,接收方收到后补上蓝牙的UUID基数即可。
3、蓝牙技术联盟UUIDS
蓝牙核心规范制定了两种不同的UUID,1、基本的UUID;2、代替基本UUID的16位UUID。 所有的蓝牙技术联盟定义UUID共用了一个基本的UUID:
0x0000xxxx‑0000‑1000‑8000‑00805F9B34FB。总共 128位,换算成8位位组(octet)也就是16个8位位组(8*16=128嘛)。为了进一步简化基本UUID,每一个蓝牙技术 联盟定义的属性有一个唯一的16位UUID,以代替上面的基本UUID的‘x’部分,也就是第12、13个八位位组。
例如:
蓝牙UUID基数如下: 00000000—0000—1000—8000—00805F9B34FB
例如要发送的16位识别码位0X2A01,完整的128位UUID便是: 00002A01—0000—1000—8000—00805F9B34FB
4、供应商特定的UUID
与蓝牙技术联盟定义的UUID类似,供应商特定的UUID也有基本UUID和16位的UUID(类似一个别名,再加载在基 本UUID之上)。
基本UUID由nRFgo Studio产生,16位UUID可以按照自己的意图来任意分配
所有对特征值的操作,都是通过对UUID的搜索得到对应的handle之后(也就是找到某种类型,然后再确定这个具体的属性),通过handle来操作特征值的。对于蓝牙通信来说,其都是通过一个个不同的UUID来标识区分不同的服务,区分不同的特性,甚至服务和特性之间的类别。
模拟智能门锁
1、 环境:树莓派3
树莓派硬件中已经集成了蓝牙设备,可以接受和发送蓝牙数据,模拟智能门锁使用的ble,树莓派已经符合条件,直接安装模拟环境就行。
2、创建虚拟门锁
树莓派使用的node版本是0.10,这个需要进行升级处理
$ sudo apt-get remove --purge node* npm*
$ curl -sL https://deb.nodesource.com/setup_4.x | sudo bash -
$ sudo apt-get install nodejs libbluetooth-dev bluez-hcidump bluez-tools
此时可以使用bluz协议的工具了:
pi@raspberrypi:~ $ hciconfig hci0: Type: BR/EDR Bus: UART
BD Address: B8:27:EB:90:28:E1 ACL MTU: 1021:8 SCO MTU: 64:1
UP RUNNING
RX bytes:4925 acl:133 sco:0 events:234 errors:0 TX bytes:7512 acl:233 sco:0 commands:86 errors:0
查看蓝牙接口信息
pi@raspberrypi:~ $ hciconfig hci0
version hci0: Type: BR/EDR Bus: UART
BD Address: B8:27:EB:90:28:E1 ACL MTU: 1021:8 SCO MTU: 64:1
HCI Version: 4.1 (0x7) Revision: 0xb6
LMP Version: 4.1 (0x7) Subversion: 0x2209
Manufacturer: Broadcom Corporation (15)
可以看到版本号是4.1
创建智能门锁需要的蓝牙版本至少是4.0
然后创建智能门锁设备:
npm install hackmelock
3、安装控制客户端
客户端在google play上面,地址是:https://play.google.com/store/apps/details?id=com.smartlockpicking.hackmelock
1、开启虚拟智能门
$ cd node_modules/hackmelock
$ node peripheral
advertising...
看到 advertising...说明智能门锁已经开始运行了
2、连接
打开app扫描设备,会发现有个门锁设备,点击链接后
树莓派设备上的日志:(第一次连接会有初始化过程):
Config loaded - iBeaconMajor: 18887 iBeaconMinor: 55453
advertising...
Client 7c:b2:0e:6d:6e:c3 connected!
Status read request:
AUTH INIT: returning random challenge : 9edcc1391c208ba0b503fe9a22574251 >> received cmd: d6057edfe0cff109dc10946fb795d6e500
KEY ID: 0
AUTH RESP: d6057edfe0cff109dc10946fb795d6e5
CRYPTED step 1: 6aacd2d578b83e6c0542ee581292ece1
CRYPTED final: d6057edfe0cff109dc10946fb795d6e5
链接后app的界面变为:
点击上面的图标树莓派上就会显示:
AUTHENTICATION OK!
>> received cmd: aa010203040506070809101112131415 Open lock!
>> received cmd: aa010203040506070809101112131415 Open lock!
>> received cmd: bb010203040506070809101112131415 Close lock!
>> received cmd: bb010203040506070809101112131415 Close lock!
>> received cmd: aa010203040506070809101112131415 Open lock!
模拟开锁和关闭锁的两个状态。
此时树莓派已经可以当做智能门锁了。