Just Works 配对
使用技术:BLE SMP 配对、绑定、加密
前置阅读:Hello Notify
学习目标
- 理解 BLE 配对的完整流程和协议栈自动处理的机制
- 理解 Just Works 配对模型的原理——无用户交互,信任首次连接
- 掌握配对 API 的回调链:连接 → 配对 → 加密 → 服务发现
- 理解绑定(Bonding)与配对的区别
规格与功能
连接后 Central 发起配对,双方自动完成加密,Bonding 保存密钥到 NV。重连后自动恢复加密,无需重新配对。
基本概念
BLE 配对三阶段
sequenceDiagram
participant C as Central
participant P as Peripheral
C->>P: Phase 1: 交换 IO Capability<br/>(Just Works = NoInputNoOutput)
Note over C,P: 双方确认 Just Works 模式
C->>P: Phase 2: 生成 STK/LTK<br/>(TK = 000000 for Just Works)
Note over C,P: 加密链路建立
C->>P: Phase 3: 密钥分发<br/>(IRK/CSRK/Identity Address)
Note over C,P: Bonding 完成
Just Works vs Passkey Entry vs OOB
| Just Works | Passkey Entry | OOB | |
|---|---|---|---|
| 用户交互 | 无 | 输入 6 位 PIN | 无(走带外通道) |
| MITM 防护 | 无 | 有 | 有 |
| 适用 | 无屏幕/无键盘设备 | 一方有显示一方有输入 | NFC/其他通道 |
| IO Capability | NoInputNoOutput | DisplayOnly/KeyboardOnly | KeyboardDisplay |
绑定 vs 不绑定
| 不绑定 | 绑定(Bonding) | |
|---|---|---|
| 密钥存储 | 仅内存 | NV 持久化 |
| 重连 | 每次重新配对 | 自动恢复加密 |
| 适用 | 一次性连接 | 长期配对(产品级) |
涉及 API
| API | 谁调用 | 用途 |
|---|---|---|
gap_ble_set_io_cap() |
Peripheral | 设置 IO Capability = NoInputNoOutput |
gap_ble_set_auth_require() |
双方 | 设置绑定/Bonding 需求 |
gap_ble_security_req() |
Central | 发起配对请求 |
gap_ble_register_callbacks() |
双方 | 注册 GAP 回调(含 pairing_complete_cb、encryption_change_cb) |
案例操作指导
配对成功串口打印 paired successfully。断开重连后自动恢复加密,无需再次配对。
关键配置
- IO Capability:
NOINPUTNOOUTPUT(Just Works) - Bonding:启用
代码详解
Central 端配对发起
static void conn_state_cb(uint16_t conn_id, gap_ble_conn_state_t state)
{
if (state == CONNECTED) {
g_conn_id = conn_id;
// 连接成功后立即发起配对
gap_ble_security_req(conn_id);
}
}
static void pairing_complete_cb(uint16_t conn_id, uint8_t status)
{
if (status == PAIRING_SUCCESS) {
printf("paired successfully\n");
// 配对完成 → 服务发现
gattc_discovery_service_service(conn_id);
} else {
printf("pairing failed: %d\n", status);
}
}
IO Capability 配置
// 初始化时配置
gap_ble_set_io_cap(NOINPUTNOOUTPUT); // Just Works
gap_ble_set_auth_require(BONDING | MITM_NOT_REQUIRED); // 启用绑定
断开重连自动加密
static void conn_state_cb(uint16_t conn_id, gap_ble_conn_state_t state)
{
if (state == CONNECTED) {
// 已绑定设备重连 — 检查加密状态
if (already_bonded(conn_id)) {
// 加密自动恢复,无需调 gap_ble_security_req
printf("encryption restored from bonding\n");
gattc_discovery_service_service(conn_id);
}
}
}
BLE vs SLE 配对对比
| BLE Just Works | SLE Just Works | |
|---|---|---|
| 配对发起方 | Central | Client |
| TK 值 | 固定 000000 | 协议层面处理 |
| Bonding 存储 | LTK + IRK + CSRK | link_key (16B) |
| 安全级别 | LE Security Mode 1 Level 1 | 协议默认级别 |
| Passkey 可选 | 是 | 否(仅 Just Works) |