Appearance
设备广播规范
本文档定义FDP配网设备的BLE广播格式规范。
设计约束
BLE广播支持32位和128位两种UUID格式:
- 32位UUID:共4字节,本规范使用全部4字节
- 128位UUID:共16字节,本规范使用前4字节(字节[0]~[3])
为同时兼容两种格式,可用于自定义数据的空间限制为4字节。
比特结构
4字节共32位,采用小端序:
| 位 | 位数 | 取值范围 | 字段名 | 说明 | 取值 |
|---|---|---|---|---|---|
| [0] | 1 | 0~1 | configured | 配网状态 | 0=未配网,1=已配网 |
| [1] | 1 | 0~1 | sleeping | 休眠状态 | 0=唤醒,1=休眠 |
| [2] | 1 | 0~1 | 预留 | 保留开关 | 0 |
| [3] | 1 | 0~1 | 预留 | 保留开关 | 0 |
| [4:9] | 6 | 0~63 | device_type | 设备类型 | 见设备类型表 |
| [10] | 1 | 0~1 | 预留 | 保留开关 | 0 |
| [11] | 1 | 0~1 | 预留 | 保留开关 | 0 |
| [12:15] | 4 | 0~15 | vendor | 厂商标识 | 见厂商标识表 |
| [16:23] | 8 | - | 预留 | 保留位 | 0 |
| [24:31] | 8 | - | protocol_id | 协议标识 | 0xFD(253) |
设备类型
| 值 | 类型 |
|---|---|
0x00 | 预留 |
0x01 | 网关 |
0x02 | 门锁 |
0x03~0x3F | 预留 |
厂商标识
| 值 | 厂商 |
|---|---|
0x0 | 公版 |
0x1 | 芯连 |
0x2 | 鑫泓佳 |
0x3~0xF | 预留 |
配网状态
APP添加设备页面的设备列表中,只应显示configured=0(未配网)的设备。
休眠状态
部分低功耗设备(如门锁)在待机时单片机处于休眠状态,此时BLE芯片仍在广播但无法响应连接请求。
APP扫描到sleeping=1的设备时,应提示用户唤醒设备(如触摸门锁键盘),待广播中sleeping变为0后再发起连接。
示例解析
公版未配网网关(唤醒):
32位值: 0xFD000010
├─ [0]: 0 → 未配网
├─ [1]: 0 → 唤醒
├─ [2:3]: 0 → 预留
├─ [4:9]: 0x01 → 网关
├─ [10:11]: 0 → 预留
├─ [12:15]: 0x0 → 公版
├─ [16:23]: 0 → 预留
└─ [24:31]: 0xFD → 协议标识芯连已配网门锁(休眠):
32位值: 0xFD001023
├─ [0]: 1 → 已配网
├─ [1]: 1 → 休眠
├─ [2:3]: 0 → 预留
├─ [4:9]: 0x02 → 门锁
├─ [10:11]: 0 → 预留
├─ [12:15]: 0x1 → 芯连
├─ [16:23]: 0 → 预留
└─ [24:31]: 0xFD → 协议标识APP扫描过滤
APP扫描到的32位UUID格式为FDxxxxxx-0000-1000-8000-00805F9B34FB,取前8个字符即为广播数据的十六进制表示。
解析与过滤:将前8个字符转为32位整数后按位提取,通过protocolId判断是否为FDP设备。
javascript
function parseAdvertising(uuid) {
const hex = uuid.substring(0, 8)
const value = parseInt(hex, 16)
return {
configured: (value >> 0) & 0x1,
sleeping: (value >> 1) & 0x1,
deviceType: (value >> 4) & 0x3F,
vendor: (value >> 12) & 0xF,
protocolId: (value >> 24) & 0xFF
}
}
function isFDPDevice(uuid) {
return parseAdvertising(uuid).protocolId === 0xFD
}设备端实现示例(C语言)
以下是ESP-IDF平台的广播实现示例:
c
#include <stdint.h>
#include <stdbool.h>
// 协议标识
#define FDP_PROTOCOL_ID 0xFD
// 设备类型
#define FDP_DEVICE_TYPE_GATEWAY 0x01
#define FDP_DEVICE_TYPE_LOCK 0x02
// 厂商标识
#define FDP_VENDOR_PUBLIC 0x0
#define FDP_VENDOR_XINLIAN 0x1
#define FDP_VENDOR_XHJ 0x2
// 广播数据结构
typedef struct {
uint8_t configured : 1; // [0] 配网状态
uint8_t sleeping : 1; // [1] 休眠状态
uint8_t reserved1 : 2; // [2:3] 预留
uint8_t device_type : 6; // [4:9] 设备类型
uint8_t reserved2 : 2; // [10:11] 预留
uint8_t vendor : 4; // [12:15] 厂商标识
uint8_t reserved3; // [16:23] 预留
uint8_t protocol_id; // [24:31] 协议标识
} __attribute__((packed)) fdp_adv_data_t;
// 构建32位广播UUID
uint32_t fdp_build_adv_uuid(uint8_t device_type, uint8_t vendor,
bool configured, bool sleeping) {
fdp_adv_data_t adv = {
.configured = configured ? 1 : 0,
.sleeping = sleeping ? 1 : 0,
.reserved1 = 0,
.device_type = device_type,
.reserved2 = 0,
.vendor = vendor,
.reserved3 = 0,
.protocol_id = FDP_PROTOCOL_ID
};
return *(uint32_t*)&adv;
}
// 使用示例
void example_start_advertising(void) {
// 公版未配网网关(唤醒状态)
uint32_t uuid = fdp_build_adv_uuid(
FDP_DEVICE_TYPE_GATEWAY, // 设备类型
FDP_VENDOR_PUBLIC, // 厂商
false, // 未配网
false // 唤醒
);
// uuid = 0xFD000010
// 将uuid转换为128位UUID格式用于广播
// 格式: xxxxxxxx-0000-1000-8000-00805F9B34FB
uint8_t uuid128[16] = {
0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80,
0x00, 0x10, 0x00, 0x00,
(uuid >> 0) & 0xFF, // 字节[12]
(uuid >> 8) & 0xFF, // 字节[13]
(uuid >> 16) & 0xFF, // 字节[14]
(uuid >> 24) & 0xFF // 字节[15]
};
// 调用BLE API设置广播数据...
}