Attribute Protocol (ATT)

BLE protocol如下图

1:ATT is based on  aClient <–> Server relationship

The server  holds一些信息如 sensor value等,这些信息以atable的形式组织起来,也就是 attribute table

table中的每一个attribute 是一个value 或者一些相关的属性信息

a client想要获取sensorvalue指的是获取table中的某行的信息

Bluetooth Core Specification V4.2解释ATT如下:

ATT(attribute protocol)定义了两个角色:a server and a client;允许 a server 暴露若干attributes 给client

an attribute是一个有如下三个properties和a value

(1)  an attribute type, defined by a UUID

(2)  an attribute handle

(3)  a set of permissions

(4)  a value

attribute type表示the attribute代表什么,SIG协会已经定义了。

如下是一个常用的应用:the Heart RateProfile,下图每一行为an attribute ,每个attribute 包含a handle, a type,a set of permissions, and a value

Attribute Handles

这个Attribute Handle唯一的标明一个server上的一个 attribute,允许a client 在一个read/write请求中引用the Attribute,简言之,Attribute Handle可以被看作是the attribute table的行标,尽管AttributeHandle的值不一定是连续的,Attribute Handle是一个16-bit 的值,你将会看到softdevice广泛的用handle来引用attributes,这是一个有效的在functions之间传递值和信息方式,AttributeHandle的值会依赖你拥有多少attributes

Attribute Types (UUIDs)

UUID是一个16-bit or 128bit值,用于表明每一个attribute的type,如上图中,有5个不同的types of attributes

one of type “Service Declaration” (0x2800)

two of type “Characteristic Declaration” (0x2803)

one of type “Heart Rate Measurement Characteristic Value”(0x2A37)

one of type “Body Sensor Location Characteristic Value” (0x2A38)

one of type “Descriptor Declaration” (0x2902)

Attribute Permissions

Permissions定义了你能与一个指定的attribute之间怎么交互,他会定义an attribute是否有readable and/or writeable 和需要什么授权才能交互,注意,Permissions只会应用于attribute value,不会应用于thehandle, type, and the permission,这允许aclient可以全部浏览a server’s attribute table,查看这个server提供了那些Attribute,即使没有对这些Attribute 没有read and write权限

Attribute Values

这个值可以是anything,一些时候,他包含的信息是在哪获取其他attributes 及其properties

例如上表中,Service Declaration的attribute 的value是a UUID(0x1800),表明这个server的类型, CharacteristicDeclaration的attribute 的value是关于 CharacteristicValue Declaration 这个attribute 的一些信息(Properties, Handle, and Type),最后,Characteristic Value Declaration 这个attribute的value才是每分钟心率的准确值

The Generic Attribute Profile (GATT)

GATT的概念是:以a veryspecific and logical order去(group )组织attributes 形成一个anattribute table

如上的heart rate profile 就是一个(group)an attribute table

ServiceDeclaration attribute

每一个group的最上面你总会看到aService Declaration attribute

这个attribute的type总是0x2800,其handle依赖于group中拥有多少个attribute

这个attribute的permissions总是Read Only withoutany authentication or authorization required

这个attribute的value是一个UUID表明这个service的类型

Characteristic Declaration attribute

Service Declaration attribute下面就是Characteristic Declaration attribute,这个类似于Service Declaration attribute

type总是0x2803

permissions 总是Read Only withoutany authentication or authorization required

value则包含了一些有趣的信息,a handle,a UUID,a set of properties,这三个元素描述了Characteristic Value Declaration attribute,

handle指向attribute table中Characteristic Value Declaration attribute,

UUID标明我们可以从CharacteristicValue Declarationattribute找到什么类型的 informationor value,例如,一个温度值等,

properties描述how thecharacteristic value can be interacted with,下表显示一些properties

这是你可能会疑惑,为什么an attribute有了 read/write permissions,还需要the characteristic value有read/write properties

The properties for thecharacteristic value are actually only guidelines for theclient, used in the GATT and application layers.

The permissions for theattribute (on the ATT layer) will always overrule the characteristic valueproperties (on the GATT layer)

Characteristic Value Declaration attribute

这个attribute 的type is same as CharacteristicDeclaration attribute的value

这个attribute 的permissions在application layer定义

这个attribute 的value是最终包含值的,也许是atemperature value

Descriptor Declaration

在Characteristic Value Declaration attribute后面可能会是

1:a new Characteristic Declaration (therecan be many characteristics grouped in aservice).

2:a new ServiceDeclaration (there can be many services in a table).

3:a DescriptorDeclaration.

Descriptor Declaration attribute是包含这个characteristic的额外信息的,有许多类型,本章我们只会处理theClient Characteristic Configuration Descriptor (CCCD)

以下为一个例子

To-do list

Step 1: Add service. This was completed in the last tutorial when we madeour own custom service with a custom base UUID and a service UUID.

Step 2: Declare and configure the characteristic.

Step 3: Add a CCCD to let the characteristic send notifications at regularintervals or whenever the temperature values are changing.

Step 2: Add the Characteristic

调用SoftDevice 的函数sd_ble_gatts_characteristic_add()

这个函数会添加 the CharacteristicDeclaration and the CharacteristicValue Declaration  to our attribute table

sd_ble_gatts_characteristic_add() takes fourparameters:

@param[in]  uint16_t                        service_handle.

@param[in]  ble_gatts_char_md_t const *     p_char_md

@param[in]  ble_gatts_attr_t const *        p_attr_char_value

@param[out] ble_gatts_char_handles_t *      p_handles

The three input parameters need to be populated with detailsthat will define the characteristic attributes(也就是一个group中的所有attributes)

These parameters define the properties, read/write permissions,descriptors, characteristic values

我们所要做的是选择在哪存储thecharacteristic attributes(也就是一个group中的所有attributes) 并定义

a characteristic value type using our custom UUID

如下三个变量比较重要

1:ble_gatts_attr_md_tattr_md:The  Attribute  Metadata:这个结构体保存:

访问characteristicvalue attributes要求的授权等级及permissions

同时也保存thecharacteristic value是否有可变长度及其存于memory何处

2:ble_gatts_char_md_tchar_md:The Characteristic Metadata:这个结构体保存:

thecharacteristic value的valueproperties

CCCD和可能的其他descriptors

3:ble_gatts_attr_t attr_char_value:The Characteristic Value Attribute: 这个结构体保存:

thecharacteristic真实的value(like thetemperature value)

value最大的长度(如4bytes)和UUID

Step 2.A, Use custom UUID to define characteristic valuetype:用定制的UUID定义characteristicvalue的类型

类似在Service UUID中一样:

uint32_t            err_code;
ble_uuid_t          char_uuid;
ble_uuid128_t       base_uuid = BLE_UUID_OUR_BASE_UUID;
char_uuid.uuid      = BLE_UUID_OUR_CHARACTERISTC_UUID;
err_code = sd_ble_uuid_vs_add(&base_uuid, &char_uuid.type);

这将会使用与service相同的base UUID,但是不同的16-bitUUID for the characteristic,例如我们定义成0xBEEF

这个base UUID在我们创建定制的service时会加入到 to the vendor specific table

所有的的调用同一个base UUID将会返回对表中相同ID的引用,This way wewill save some memory by not needing to store a large array of 128-bit long IDs

Step 2.B, Configure the Attribute Metadata

以下三行是我们需要描述the attributes ofthe characteristic的最低限度

这几行只做了一件事就是决定在哪存储 theattributes,我们将其存储在Softdevice可以控制的memory,因此我们使用BLE_GATTS_VLOC_STACK使用BLE_GATTS_VLOC_USER将属性存储在用户控制的内存部分

ble_gatts_attr_md_t attr_md;
memset(&attr_md, 0, sizeof(attr_md));
attr_md.vloc        = BLE_GATTS_VLOC_STACK;

在attribute metadata structure ble_gatts_attr_md_t中,你可以定义访问characteristicvalue attributes要求的授权等级及permissions

For example if you need Man In The Middleprotection (MITM) or a passkey to access your attribute

Step 2.C, Configure the CharacteristicValue Attribute :配置Characteristic Value这个Attribute

此时我们需要创建了自己的UUID,并决定在哪存储 thecharacteristic,我们将会存储到theCharacteristic Value Attribute中

ble_gatts_attr_t    attr_char_value;
memset(&attr_char_value, 0, sizeof(attr_char_value));
attr_char_value.p_uuid      = &char_uuid;
attr_char_value.p_attr_md   = &attr_md;

Step 2.D, Add handles for the characteristicto our struct:为我们的结构添加characteristic 的句柄

我们需要添加一个变量来保存我们的service结构体中的characteristic 相关的handles

所以添加如下:

typedef struct
{
uint16_tconn_handle;
uint16_t                    service_handle;
// OUR_JOB: Step 2.D, Add handles for our characteristic
ble_gatts_char_handles_t    char_handles;
}ble_os_t;

这个ble_os_t有一个域保存了 servicedeclaration handle

conn_handle这个handle用于当前connection保持track

如果你查看的到ble_gatts_char_handles_t的定义,你可以看到这个变量可以为thecharacteristic value保存16-bit handles,用户的描述,自身的CCCD,其他一些如SCCD

Step 2.E, Add the new characteristic to theservice

此时我们就可以增加一个newcharacteristic 到我们的attributetable 中,类似如下

err_code = sd_ble_gatts_characteristic_add(p_our_service->service_handle,
&char_md,
&attr_char_value,
&p_our_service->char_handles);

通过这个我们告诉SofteDevice:这个characteristic依附于那个service(service_handle), theCharacteristic Metadata, and the Characteristic Value Attributes

随后,协议栈就会处理这些参数并初始化这个characteristic,然后将对应的handle存于我们定义的结构体(p_our_service)

Step 2.F, Add read/write properties to ourcharacteristic value

按上面的操作,可以给我们的service添加新的characteristic ,但是对于characteristic  value既不能读也不能写

添加如下:

ble_gatts_char_md_t char_md;
memset(&char_md, 0, sizeof(char_md));
char_md.char_props.read = 1;
char_md.char_props.write = 1;

此时,仍然对characteristic  value既不能读也不能写,这是因为我们只是设置了 characteristicdeclaration中的properties

Step 2.G, Set read/write permissions to ourcharacteristic

基于上,我们将设置简单的可读可写权限,Nosecurity, encryption, or passkey needed

一个简单的方法是使用宏BLE_GAP_CONN_SEC_MODE_SET_OPEN() 添加如下:

BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);

此时我们会读出value为0,因为我们没有给characteristic  value分配一个value和value length

当你试图写数据进去时,会报错,提示characteristic  value length初始化为0

Step 2.H, Set characteristic length

为characteristic  value length初始化

attr_char_value.max_len     = 4;
attr_char_value.init_len    = 4;
uint8_t value[4]            = {0x12,0x34,0x56,0x78};
attr_char_value.p_value     = value;

设置初始化值为12-34-56-78

Step 3: Client Characteristic Configuration Descriptor (CCCD)

BLE 怎样添加 Characteristic相关推荐

  1. ESP32学习笔记十九之BLE协议GAPGATT

    GAP GAP全名是Generic Access Profile,通用访问配置文件,它定义了蓝牙设备的角色,中心和外设,并且控制他们的连接和广播数据.广播数据有两种方式:广播数据和扫描回复数据,数据包 ...

  2. 基于富芮坤的FR801 BLE芯片开发

    基于富芮坤的FR801 BLE芯片开发 前言:本篇主要讲解如何利用官方的SDK和ble 协议栈知识开发所需的功能 注意:因为官方是每个工程都导入同一个底层-所以一旦修改了components ,全部工 ...

  3. android蓝牙BLE 有源码 有视频

    前序 ​ Google在android 4.3(API Level 18)的android版本中引入了低功耗蓝牙BLE核心API.低功耗蓝牙BLE也就是我们经常说的蓝牙4.0, 该技术拥有极低的运行和 ...

  4. android 蓝牙 广播,android蓝牙BLE(三) —— 广播

    ​ 在蓝牙开发中,有些情况是不需要连接的,只要外设广播自己的数据即可,例如苹果的ibeacon.自Android 5.0更新蓝牙API后,手机可以作为外设广播数据. 广播包有两种: 广播包(Adver ...

  5. ESP32的BLE使用学习

    UUID生成网站: Online UUID Generator Tool 0.前言 什么是低功耗蓝牙? BLE之所以被称为低功耗蓝牙,就是需要通讯的时候才握手,数据传输完成后,就断开连接.在通讯过程中 ...

  6. 从ESP32 BLE应用理解GATT

    目录 1.背景 1.1参考资料 1.2 GATT是什么玩意 2.ESP32 例程分析 2.1 GATT 服务器的架构组织 2.2 从GATT回调函数注册程序esp_ble_gatts_register ...

  7. (Android)低功耗蓝牙(BLE)开发一文全(详)解

    前言:如果你是刚开始接触android关于低功耗(ble)蓝牙的开发,还是应该花点是时间了解一下BLE协议,因为哪怕你把蓝牙ble协议梳理个一知半解,那么开发就只剩下调用API了... 为了快速编辑, ...

  8. 物联网专题--基于APP Inventor的BLE蓝牙4.0数据通信

    本文原文为本人新浪博客:http://blog.sina.com.cn/s/blog_12f79c9b90102wbde.html 本科毕业设计要用到蓝牙4.0(芯片选用TI公司的CC254x系列)与 ...

  9. BLE MESH组网(一)简介和基本概念

    BLE MESH组网(一) BLE MESH简介 BLE MESH来源 BLE MESH用处 BLE MESH的通讯方式 管理洪水 市场内蓝牙设备支持 安全性 BLE MESH协议栈模型 BLE ME ...

  10. BLE MESH组网(七)真机配置

    BLE MESH(三) 一.在nRF5 SDK中为Mesh示例配置承载器 二.可用示例 三.要开始使用nRF Mesh移动应用程序评估示例,请完成以下三个配置阶段: 四.配置步骤 第一步:nRF Me ...

最新文章

  1. linux at查看进程命令,at命令 - Linux命令大全 | linux教程
  2. github api常用操作
  3. MVC面试问题与答案
  4. 基于jmeter测试web接口,看完都说学会了
  5. windows server 2012 AD 活动目录部署系列(二)创建域控制器
  6. 运用数学软件matlab求无穷积分,matlab积分的计算及其简单应用论文.doc
  7. 计算机考试用户没有注册类,电脑中出现没有注册类别的错误提示怎么解决
  8. java项目开发团队协作重要性_Java1班项目实战 | 团队协作,我们是认真的!
  9. 智能驾驶软件测试,智能驾驶实车测试系统-VDAS
  10. 时间t与时间管理——柳比歇夫、德鲁…
  11. TASKCTL5.0线上支付购买授权
  12. 助力篇|常见金融风控数据分析内容汇总,助你面试道路畅通无阻
  13. [译] 基于 Python 的图论和网络分析
  14. 码元速率估计-速率信号法
  15. 诺基亚 android,诺基亚当年为什么走向没落也没用安卓系统?
  16. 黑马全套Java教程(八):集合进阶
  17. 在Qt Creator中的pro文件添加lib库
  18. 个性印章在线生成下载网站
  19. 飞思卡尔 p1010 gpio linux驱动开发
  20. C#双行计算器和单行计算器

热门文章

  1. autosar—com模块
  2. js版本飞机大战(完整代码)
  3. 关于拼多多的一些分析//2021-2-26
  4. 【蓝桥单片机】51单片机(stc15f)的两个寄存器TCON和TMOD
  5. 超级表格全新升级,这些功能你不可能在其他软件上看到
  6. .net之微信企业号开发(二) 企业号人员身份认证与开发
  7. spring security自定义登录失败返回错误信息
  8. 『自己的工作4』TensorFlow2.0自动微分和手工求导的结果对比!
  9. matlab如何求反渐开线函数,inv函数(inv函数查询表)
  10. labview信号频域分析算法