属性协议(Attribute Protocol)简称ATT。
ATT层定义了属性实体的概念,包括UUID、句柄和属性值等,也规定了属性的读、写、通知等操作方法和细节,
这些与属性操作相关的内容称为属性协议。ATT层规定了ATT_MTU值,如果属性值很长,超过了ATT_MTU限制,将使用特殊的读写方法进行操作。
基于ATT层,可以构建出通用属性操作规范。
属性
在蓝牙协议中, 属性是指一个数据实体,它包含标识符,句柄,数据内容,访问权限,安全问题等。
属性协议规定了属性的发现和读写访问的方法。
类型
属性类型由一个UUID(Universally Unique Identifier)表示。UUID是指从时间尺度和空间尺度都具有唯一性的一串128-bit的数字,该数字串在全球范围内不会重复,并且在未来也不会出现重复。
一个典型的16字节UUID格式为XXXX-XX-XX-XX-XXXXXX。
蓝牙协议设定了一个蓝牙基础UUID: 00000000 – 0000 – 1000 – 8000 – 00805F9B34FB。
利用该基础UUID,可以使用16-bit或32-bit的UUID来代替128-bit的UUID,当传递到对端设备,再还原成128-bit的UUID。
假如16-bit的UUID为YYYY,则还原后的128-bit的UUID为:0000YYYY – 0000 – 1000 – 8000 – 00805F9B34FB。
假如32-bit的UUID为YYYYYYYY,则还原后的128-bit的UUID为:YYYYYYYY – 0000 – 1000 – 8000 – 00805F9B34FB。
ATT层支持使用16-bit和128-bit两种UUID,32-bit的UUID在使用前必须转换成128-bit。
句柄
属性句柄犹如指向属性实体的指针,对端设备通过句柄来访问该属性。
属性句柄是一个2字节数,有效范围为0x0001-0xFFFF。
属性句柄为有序排列,后面的句柄值会大于前面的句柄,通常下一个属性的句柄值是上一个属性的句柄加1。
分组
多个属性可以合成一组,一组属性包含的参数为:开始句柄、结束句柄。
*值
属性值可以是一个数字或一个字符串。属性值的长度信息不包含在PDU中,所以需要从PDU的长度间接推算出属性值的长度信息。
属性值通常在一个PDU中发送,如果属性值太长,也可以分成多个PDU进行发送。
权限
属性的读写权限由ATT层之上的协议层规定,有效的读写权限包括:可读、可写、读写。
在读写属性之前,客户端设备还需要具有足够的安全权限,包括:
加密权限:需要加密、无需加密
认证权限:需要认证、无需认证
授权权限:需要授权、无需授权
如果权限不足,将触发错误处理机制。
控制点属性
控制点属性是一类特殊属性,它不可读,只能写。
协议方法
对属性的操作称为协议方法,包括:命令(Command),请求(Request),响应(Response),通知(Notification),指示(Indication)和确认(Confirmation),某些属性PDU还涉及授权签名方法。
交换MTU Size
ATT_MTU表示ATT层间传输的数据包的最大长度。两端设备可以通过Exchange MTU Request/Response进行交换MTU。
长包属性
对于读属性的数据包,最大长度为(ATT_MTU-1)个字节。其中减去的1表示1字节的操作码。
对于写属性数据包,最大长度为(ATT_MTU-3)个字节。其中减去的3表示1字节的操作码和2字节的属性句柄。
如果数据包超过这个长度,则称为长包属性。
读长包属性,需要使用Read Blob Request,写长包属性,需要使用Prepare Write Request和Execute Write Request。
如果使用普通Read操作读长包属性,仅能读取前(ATT_MTU – 1)个字节,使用普通Write操作写长包属性,仅能写前(ATT_MTU-3)个字节。
无论普通属性还是长包属性,属性值的最大长度均为512字节。
原子操作
一个请求或一个命令,称为一个原子操作。一个原子操作结束后,才能进行新的原子操作。
读写长包属性无法在一个原子操作内完成。
**属性PDU
在ATT层协议框架内,拥有一组属性的设备称为服务端(Server),读写该属性值的设备称为客户端(Client)。