如何自定义低功耗蓝牙服务
本文档介绍了如何利用 ESP-AT 提供的低功耗蓝牙服务源文件在 ESP32 设备上自定义低功耗蓝牙服务。
低功耗蓝牙服务被定义为 GATT 结构的多元数组,该数组至少包含一个属性类型 (attribute type) 为 0x2800 的首要服务 (primary service)。每个服务总是由一个服务定义和几个特征组成。每个特征总是由一个值和可选的描述符组成。更多相关信息请参阅 《蓝牙核心规范》 中的 Generic Attribute Profile (GATT) 一节。
所有支持低功耗蓝牙的芯片共用同一份 gatts_data.csv 格式。下文说明在 ESP32 上各字段是否生效。
低功耗蓝牙服务源文件介绍
低功耗蓝牙服务源文件是 ESP-AT 工程创建低功耗蓝牙服务所依据的文件,文件位于 customized_partitions/raw_data/ble_data/gatts_data.csv,内容如下表所示。
index |
uuid_len |
uuid |
perm |
val_max_len |
val_cur_len |
value |
|---|---|---|---|---|---|---|
0 |
16 |
0x2800 |
0x01 |
2 |
2 |
A002 |
1 |
16 |
0x2803 |
0x01 |
1 |
1 |
02 |
2 |
16 |
0xC300 |
0x01 |
1 |
1 |
30 |
3 |
16 |
0x2901 |
0x11 |
1 |
1 |
30 |
… |
… |
… |
… |
… |
… |
… |
以下内容是对上表的说明。
perm字段描述属性权限。当某行的perm生效时(见下文规则),它在 ESP-AT 工程中的定义如下所示:/* relate to BTA_GATT_PERM_xxx in bta/bta_gatt_api.h */ /** * @brief Attribute permissions */ #define ESP_GATT_PERM_READ (1 << 0) /* bit 0 - 0x0001 */ /* relate to BTA_GATT_PERM_READ in bta/bta_gatt_api.h */ #define ESP_GATT_PERM_READ_ENCRYPTED (1 << 1) /* bit 1 - 0x0002 */ /* relate to BTA_GATT_PERM_READ_ENCRYPTED in bta/bta_gatt_api.h */ #define ESP_GATT_PERM_READ_ENC_MITM (1 << 2) /* bit 2 - 0x0004 */ /* relate to BTA_GATT_PERM_READ_ENC_MITM in bta/bta_gatt_api.h */ #define ESP_GATT_PERM_WRITE (1 << 4) /* bit 4 - 0x0010 */ /* relate to BTA_GATT_PERM_WRITE in bta/bta_gatt_api.h */ #define ESP_GATT_PERM_WRITE_ENCRYPTED (1 << 5) /* bit 5 - 0x0020 */ /* relate to BTA_GATT_PERM_WRITE_ENCRYPTED in bta/bta_gatt_api.h */ #define ESP_GATT_PERM_WRITE_ENC_MITM (1 << 6) /* bit 6 - 0x0040 */ /* relate to BTA_GATT_PERM_WRITE_ENC_MITM in bta/bta_gatt_api.h */ #define ESP_GATT_PERM_WRITE_SIGNED (1 << 7) /* bit 7 - 0x0080 */ /* relate to BTA_GATT_PERM_WRITE_SIGNED in bta/bta_gatt_api.h */ #define ESP_GATT_PERM_WRITE_SIGNED_MITM (1 << 8) /* bit 8 - 0x0100 */ /* relate to BTA_GATT_PERM_WRITE_SIGNED_MITM in bta/bta_gatt_api.h */ #define ESP_GATT_PERM_READ_AUTHORIZATION (1 << 9) /* bit 9 - 0x0200 */ #define ESP_GATT_PERM_WRITE_AUTHORIZATION (1 << 10) /* bit 10 - 0x0400 */
上表第一行是服务定义。该行的属性类型为
0x2800(首要服务),其valueA002表示 16 位服务 UUID0xA002。第二行是特征声明。UUID
0x2803表示该行是特征声明。value:表示下一行特征值属性的特征属性 (characteristic properties)。该字段为 1 字节(8 位),每一位表示是否支持对应属性,1表示支持,0表示不支持。
例如,
value为02表示下一行特征具备 READ 属性。位
特征属性
0
BROADCAST
1
READ
2
WRITE WITHOUT RESPONSE
3
WRITE
4
NOTIFY
5
INDICATE
6
AUTHENTICATION SIGNED WRITES
7
EXTENDED PROPERTIES
第三行定义该特征的特征值属性。该行的
uuid是特征 UUID,value是特征的初始值。第四行定义了特征的描述符(可选)。
value字段可以缺省。若缺省(留空),ESP-AT 在初始化时会将该属性自动填充为全0。例如,默认表中特征0xC301一行的value为空,则该特征会初始化为全0。
字段规则
对于
0x2803行,perm与value均生效:perm是声明属性自身的权限(一般为0x01,可读),value是下一行特征的属性。对于特征值行,
perm生效,且不得与上一行0x2803的特征属性冲突。特征属性向客户端声明该特征支持哪些操作;perm决定协议栈是否真正允许这些操作。例如,若属性声明为只读,但特征值行的perm却是只写,客户端按声明去读时会失败。常见对应关系如下(若需要安全访问,可改用对应的加密、签名等权限变体):
若特征属性包含
特征值行的
perm至少应包含READ
READ(即
0x01),或相关的加密、授权读变体WRITE
WRITE(即
0x10),或相关的加密、授权、签名写变体WRITE WITHOUT RESPONSE
WRITE(即
0x10),或相关的加密、授权、签名写变体NOTIFY 或 INDICATE
特征值行通常为 READ;需自行添加 CCCD(即
0x2902),其perm一般为 READ | WRITE(即0x11)特征属性可以组合。例如
0A(即 READ | WRITE)应与特征值行perm0x11(即 READ | WRITE)配对。若特征支持 NOTIFY 或 INDICATE,需在表中自行添加
0x2902行。其他描述符(如0x2901)也会按表添加,且各描述符行的perm生效。
有关 UUID 的更多信息请参考 蓝牙技术联盟分配符。
如果直接在 ESP32 设备上使用默认源文件,不做任何修改,并建立低功耗蓝牙连接,那么在客户端查询服务器服务后,会得到如下结果。
编译时自定义低功耗蓝牙服务
请根据以下步骤自定义低功耗蓝牙服务。
修改低功耗蓝牙服务源文件
可定义多个服务,例如,若要定义三个服务(Server_A、Server_B 和 Server_C),则需要将这三个服务按顺序排列。由于定义每个服务的操作大同小异,这里我们以定义一个服务为例,其他服务你可以按照此例进行定义。
添加服务定义。
本例定义了一个值为 0xFF01 的主要服务。
index
uuid_len
uuid
perm
val_max_len
val_cur_len
value
31
16
0x2800
0x01
2
2
FF01
添加特征说明和特征值。
本例定义了一个 UUID 为 0xC300 的可读可写特征,并将其值设置为 0x30。
声明行
perm为0x01。特征值行perm为0x11(需与 READ | WRITE 属性对应)。index
uuid_len
uuid
perm
val_max_len
val_cur_len
value
32
16
0x2803
0x01
1
1
0A
33
16
0xC300
0x11
1
1
30
添加特征描述符(可选)。
步骤 2 中的特征属性为
0A(表示 READ | WRITE),不需要 CCCD。下方内容是针对支持 NOTIFY 或 INDICATE 的特征的 独立可选示例,与上面的0A示例无关。若需要 NOTIFY,请相应设置0x2803的属性(例如1A表示 READ | WRITE | NOTIFY)。若特征支持 NOTIFY 或 INDICATE,需自行添加客户端特征配置(
0x2902)。下表示例将value设为0000(通知和指示关闭)。CCCD 行示例:
index
uuid_len
uuid
perm
val_max_len
val_cur_len
value
34
16
0x2902
0x11
2
2
0000
完成以上步骤后,自定义的低功耗蓝牙服务可如下定义。下表将步骤 1–2 的服务与特征,与步骤 3 的可选 CCCD 示例合并展示。若仅使用
0A(READ | WRITE)特征,可省略0x2902行。index
uuid_len
uuid
perm
val_max_len
val_cur_len
value
31
16
0x2800
0x01
2
2
FF01
32
16
0x2803
0x01
1
1
0A
33
16
0xC300
0x11
1
1
30
34
16
0x2902
0x11
2
2
0000
请根据自己的需求修改 GATTS 配置,然后生成 mfg_nvs.bin 文件。
生成 mfg_nvs.bin 文件
请参考 生成 mfg_nvs.bin 文档生成带有低功耗蓝牙的服务配置的 mfg_nvs.bin。
下载 mfg_nvs.bin 文件
请参考 下载 mfg_nvs.bin 文档。
下载完成后,重新建立低功耗蓝牙连接,在客户端查询的服务器服务如下所示。