Documentation Index
Fetch the complete documentation index at: https://mintlify.com/dsyx/docs.silabs.com_zh/llms.txt
Use this file to discover all available pages before exploring further.
Bluetooth Profile Toolkit 是一个基于 XML 的标记语言,用于以易于理解且机器可读的形式描述 Bluetooth GATT 数据库(Services 和 Characteristics)——无需为其编写代码。本指南详细讲解 Profile Toolkit 中使用的 XML 语法,指导如何描述自己的 Bluetooth Services 和 Characteristics、配置访问权限和安全属性,并将 GATT 数据库作为固件的一部分编译。
如在 Simplicity Studio 内开发,推荐使用 GATT Configurator 可视化工具替代手动编写 XML。Profile Toolkit 适用于 Simplicity Studio 之外的开发场景,或在 IAR Embedded Workbench 项目中使用 BGBuild 工具链。
概念回顾
Profile、Service 与 Characteristic 的关系
- Profile:描述数据交换结构,由一个或多个 Service 组成,完成高级用例(如心率监测)。标准化 Profile 允许不同厂商的设备和软件互操作。
- Service:由一个或多个 Characteristic 组成的数据集合,完成设备特定功能(如电池监视、温度数据)。
- Characteristic:Service 中使用的值,包含访问方式、安全要求及可选的 Descriptor(描述符)。
- Attribute Protocol(ATT):使数据在 GATT Server 和 Client 之间交换,提供 Query、Write、Indicate 和 Notify 等操作。
GATT Database 的局限性(EFR32BG 设备)
| 项目 | 限制 | 备注 |
|---|
| Characteristics 最大数量 | 不限(受 Attribute 总数限制) | 非 const="true" 的 Characteristic 计入此数 |
type="user" Characteristic 最大长度 | 255 字节 | 不支持 Write Long、Reliable Writes 和 Read Multiple |
type="utf-8/hex" Characteristic 最大长度 | 255 字节 | const="false" 时 RAM 分配大小 |
| 单个 GATT 数据库的最大 Attribute 数量 | 255 | 单个 Characteristic 通常需要 3–5 个 Attribute |
| 最大可通知 Characteristic 数量 | 64 | |
| 最大 Capability 数量 | 16 | Capability 决定 Service/Characteristic 的可见性 |
XML 语法详解
<gatt> 根元素
必须在 <gatt> 内部描述整个 GATT 数据库:
<?xml version="1.0" encoding="UTF-8" ?>
<gatt out="my_gatt_db.c"
header="my_gatt_db.h"
db_name="my_gatt_db_"
prefix="my_gatt_"
generic_attribute_service="true"
name="My GATT database">
<!-- Services 定义在此处 -->
</gatt>
| 参数 | 默认值 | 说明 |
|---|
out | gatt_db.c | 生成的 GATT C 源文件名 |
header | gatt_db.h | 生成的 GATT C 头文件名 |
db_name | bg_gattdb_data | GATT 数据库结构名及数据结构前缀 |
prefix | gattdb_ | 每个 id 名称的前缀(用于 C 句柄宏) |
generic_attribute_service | false | 为 true 时自动添加 Generic Attribute Service 并启用 GATT 缓存(BT 5.1) |
gatt_caching | 跟随 generic_attribute_service | 可单独设置为 false 禁用 GATT 缓存 |
<capabilities_declare> 与 <capability>
通过 Capabilities 可以动态控制 Service 和 Characteristic 的可见性:
<capabilities_declare>
<!-- 默认启用,标识符为 cap_light -->
<capability enable="true">cap_light</capability>
<!-- 默认禁用,标识符为 cap_color -->
<capability enable="false">cap_color</capability>
</capabilities_declare>
可见性规则:
- Service 启用至少一个 Capability → 该 Service 及其所有 Characteristics 可见
- Service 禁用所有 Capabilities → 该 Service 及其所有 Characteristics 不可见
- 未声明 Capabilities 的 Service/Characteristic 遵循继承规则(继承父级或全局的所有 Capabilities)
<service> 元素
<!-- 标准 GAP Service(16-bit UUID) -->
<service uuid="1800">
<!-- Characteristics 定义在此处 -->
</service>
<!-- 厂商自定义 Service(128-bit UUID) -->
<service uuid="25be6a60-2040-11e5-bd86-0002a5d5c51b">
<!-- Characteristics 定义在此处 -->
</service>
<!-- 带广告、ID 的 Heart Rate Service -->
<service uuid="180D" id="hrs" advertise="true">
<!-- Characteristics 定义在此处 -->
</service>
| 参数 | 说明 |
|---|
uuid | Service UUID,16-bit 为 SIG 标准,128-bit 为厂商自定义 |
id | Service 标识符,用于 <include> 引用 |
type | primary(默认)或 secondary |
advertise | true 时将 UUID 包含在广告数据中(广告数据最多含 13 个 16-bit 或 1 个 128-bit UUID) |
包含(Include)另一个 Service:
<service uuid="1800">
<!-- 将 Heart Rate Service 包含进来 -->
<include id="hrs" />
</service>
<characteristic> 元素
必须在 <service> 标签内定义:
<!-- 标准 Device Name Characteristic -->
<service uuid="1800">
<characteristic uuid="2a00">
<!-- 属性、值、描述符定义在此处 -->
</characteristic>
</service>
<!-- 厂商自定义 Characteristic,带 ID -->
<service uuid="25be6a60-2040-11e5-bd86-0002a5d5c51b">
<characteristic uuid="59cd69c0-2043-11e5-a717-0002a5d5c51b" id="mydata">
<!-- 属性、值、描述符定义在此处 -->
</characteristic>
</service>
<properties> 访问属性
<!-- 只读 Device Name(常量值) -->
<characteristic const="true" uuid="2a00">
<properties>
<read authenticated="false" bonded="false" encrypted="false"/>
</properties>
</characteristic>
<!-- 可读写 Device Name -->
<characteristic uuid="2a00">
<properties>
<read authenticated="false" bonded="false" encrypted="false"/>
<write authenticated="false" bonded="false" encrypted="false"/>
</properties>
</characteristic>
<!-- 带 Notify 的 Heart Rate Measurement -->
<characteristic uuid="180D">
<properties>
<notify authenticated="false" bonded="false" encrypted="false"/>
</properties>
</characteristic>
<!-- 需要加密才能读取 -->
<characteristic uuid="1234">
<properties>
<read authenticated="false" bonded="false" encrypted="true"/>
</properties>
</characteristic>
<!-- 需要认证才能写入 -->
<characteristic uuid="1234">
<properties>
<write authenticated="true" bonded="false" encrypted="false"/>
</properties>
</characteristic>
<!-- 需要认证才能接收 Indication -->
<characteristic uuid="2A7D">
<properties>
<indicate authenticated="true" bonded="false" encrypted="false"/>
</properties>
</characteristic>
安全属性说明:
| 属性 | 说明 |
|---|
authenticated | 需要带 MITM 保护的绑定认证,且连接必须加密 |
encrypted | 需要加密连接(iOS 9.1+ 还需至少 Just Works 绑定) |
bonded | 需要加密连接且必须已绑定(至少 Just Works 配对) |
<value> 数据值定义
<!-- 固定长度 2 字节的 Characteristic(hex 类型) -->
<characteristic uuid="180D">
<value length="2" type="hex" variable_length="false"/>
<properties>
<notify authenticated="false" bonded="false" encrypted="false"/>
</properties>
</characteristic>
<!-- 可变长度,最大 20 字节的厂商自定义 Characteristic -->
<characteristic uuid="59cd69c0-2043-11e5-a717-0002a5d5c51b" id="mydata">
<value variable_length="true" length="20" type="hex"/>
<properties>
<notify authenticated="false" bonded="false" encrypted="false"/>
</properties>
</characteristic>
<!-- 带初始值的字符串 Characteristic(utf-8 类型) -->
<characteristic const="true" id="device_name" name="Device Name"
uuid="2A00">
<value length="17" type="utf-8" variable_length="false">EFR32 BGM111</value>
<properties>
<read authenticated="false" bonded="false" encrypted="false"/>
</properties>
</characteristic>
<!-- user 类型:由应用自行处理读写 -->
<characteristic uuid="59cd69c0-2043-11e5-a717-0002a5d5c51b" id="mydata">
<value type="user" length="20" variable_length="true"/>
<properties>
<read authenticated="false" bonded="false" encrypted="false"/>
<write authenticated="false" bonded="false" encrypted="false"/>
</properties>
</characteristic>
当 type="user" 时,Bluetooth Stack 不会自动初始化或提供 Characteristic 值——应用程序需要在 gatt_server_user_read_request 和 gatt_server_user_write_request 事件中自行处理。
<descriptor> 描述符定义
<characteristic uuid="2a4d" id="hid_input">
<properties notify="true" read="true" />
<value length="3" />
<!-- 添加 UUID 为 2908 的自定义 Descriptor -->
<descriptor const="false" discoverable="true"
id="" name="Custom Descriptor"
uuid="2908">
<properties>
<read authenticated="false" bonded="false" encrypted="false"/>
</properties>
<value length="0" type="hex" variable_length="false">00</value>
</descriptor>
</characteristic>
如果手动添加 CCCD(Client Characteristic Configuration Descriptor,UUID: 0x2902),其值将覆盖 Characteristic 的 notify/indicate 属性设置。未手动添加时,若 Characteristic 启用了通知或指示,CCCD 将自动生成。
完整 GATT 示例
示例一:完整 GAP Service
<?xml version="1.0" encoding="UTF-8" ?>
<gatt>
<!-- Generic Access Service -->
<service advertise="false" name="Generic Access"
type="primary" uuid="1800">
<informativeText>
Abstract: The generic_access service contains generic information
about the device. All available Characteristics are readonly.
</informativeText>
<!-- Device Name(常量只读) -->
<characteristic const="true" id="device_name"
name="Device Name" uuid="2A00">
<value length="17" type="utf-8" variable_length="false">
EFR32 BGM111
</value>
<properties>
<read authenticated="false" bonded="false" encrypted="false"/>
</properties>
</characteristic>
<!-- Appearance(常量只读) -->
<characteristic const="true" name="Appearance" uuid="2A01">
<value length="2" type="hex" variable_length="false">0000</value>
<properties>
<read authenticated="false" bonded="false" encrypted="false"/>
</properties>
</characteristic>
</service>
</gatt>
<?xml version="1.0" encoding="UTF-8" ?>
<gatt>
<!-- Link Loss Service -->
<service id="link_loss" name="Link Loss"
type="primary" uuid="1803">
<!-- Alert Level Characteristic(可读写) -->
<characteristic id="alert_level" name="Alert Level"
uuid="2A06">
<value length="1" type="hex" variable_length="false"/>
<properties>
<read authenticated="false" bonded="false" encrypted="false"/>
<write authenticated="false" bonded="false" encrypted="false"/>
</properties>
</characteristic>
</service>
<!-- Immediate Alert Service -->
<service id="immediate_alert" name="Immediate Alert"
type="primary" uuid="1802">
<!-- Alert Level Characteristic(Write Without Response) -->
<characteristic id="alert_level" name="Alert Level"
uuid="2A06">
<value length="1" type="hex" variable_length="false"/>
<properties>
<write_no_response authenticated="false" bonded="false"
encrypted="false"/>
</properties>
</characteristic>
</service>
</gatt>
示例三:带 Capabilities 的 GATT 数据库
<?xml version="1.0" encoding="UTF-8" ?>
<gatt generic_attribute_service="true">
<!-- 声明 Capabilities -->
<capabilities_declare>
<capability enable="true">cap_light</capability>
<capability enable="false">cap_color</capability>
</capabilities_declare>
<!-- 带 Capabilities 的 Service -->
<service uuid="180A" name="Device Information">
<capabilities>
<capability>cap_light</capability>
</capabilities>
<characteristic uuid="2A29" name="Manufacturer Name String">
<value type="utf-8" length="12" variable_length="false">
Silicon Labs
</value>
<properties>
<read authenticated="false" bonded="false" encrypted="false"/>
</properties>
</characteristic>
</service>
</gatt>
生成代码文件
在 Simplicity Studio 中生成
保存 .btconf 文件后,GATT 数据库会作为预构建步骤自动转换为 .c 和 .h 文件,包含在应用程序项目中。
使用 BGBuild 工具生成(命令行/IAR 项目)
# 将 GATT XML 定义文件转换为 C 代码
bgbuild.exe gatt.xml
BGBuild 将生成 gatt_db.c 和 gatt_db.h,可通过 Bluetooth Stack 的 GATT API 或远程 Bluetooth 设备访问生成的 GATT 数据库。