BLE 怎样添加 Characteristic
来源:互联网 发布:松翰单片机官网 编辑:程序博客网 时间:2024/06/11 18:18
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,下图每一行为anattribute,每个attribute包含a handle, a type,a set of permissions, and a value
Attribute Handles
这个AttributeHandle唯一的标明一个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)
AttributePermissions
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 Declarationattribute
这个attribute的type总是0x2800,其handle依赖于group中拥有多少个attribute
这个attribute的permissions总是Read Only withoutany authentication or authorization required
这个attribute的value是一个UUID表明这个service的类型
Characteristic Declarationattribute
Service Declarationattribute下面就是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,还需要thecharacteristic 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 Declarationattribute
这个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 manycharacteristicsgrouped 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 characteristicattributes(也就是一个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_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和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
- BLE概念,profile,service,characteristic, UUID
- BLE 读取characteristic时,为什么没有 'BLE_GATTS_EVT_READ' ?
- BLE之添加服务
- TI BLE 添加自己UUID
- 蓝牙4.0ble文件添加
- 【BLE】CC2541之添加特征值
- 【BLE】CC2541之添加特征值
- 给 TI BLE 添加自己UUID
- <蓝牙BLE>cc2540如何添加特征值
- 给 TI BLE 添加自己UUID
- 【BLE】CC2541之添加自定义服务
- 【BLE】CC2541之添加自定义任务
- 【BLE-CC2640】CC2640之添加自定义服务
- BLE-CC2640之添加自定义服务
- 给 TI BLE 添加自己UUID
- BLE
- ble
- HTTP请求与响应示例
- 1099: 角谷猜想(多实例测试)
- http介绍及网络安全
- 数据结构
- kerberos安全机制原理
- BLE 怎样添加 Characteristic
- HDU 4799 LIKE vs CANDLE ACM/ICPC 2013 Changsha(树形dp)
- SF笔试编程1:幸运数
- [日常问题]升级gradle后renderscript出现android.os.DeadObjectException
- Oxford Deep NLP学习笔记2:Overview of the Practicals
- 内存泄漏、越界、溢出
- 训练3+ C-Lunch Break
- SpringBoot01--入门实例
- JS怎么动态命名变量名