第一句子网 - 唯美句子、句子迷、好句子大全
第一句子网 > BLE 怎样添加 Characteristic

BLE 怎样添加 Characteristic

时间:2019-04-01 16:56:57

相关推荐

BLE 怎样添加 Characteristic

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是否有readableand/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 ValueDeclaration这个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 Declarationattribute

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/writepermissions,还需要thecharacteristic value有read/writeproperties

Thepropertiesfor thecharacteristic value are actually onlyguidelinesfor theclient, used in the GATT and application layers.

Thepermissionsfor theattribute (on the ATT layer) will always overrule the characteristic valueproperties (on the GATT layer)

Characteristic Value Declaration attribute

这个attribute的typeis 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()

这个函数会添加 theCharacteristicDeclarationand theCharacteristicValue Declarationto 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_tattr_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_t conn_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和valuelength

当你试图写数据进去时,会报错,提示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)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。