Files

150 lines
6.6 KiB
Markdown
Raw Permalink Normal View History

# 平台注册火山与设备取参
2026-09-15 · 新流程:平台代注册,绑定直接下发凭据;设备本地初始化 SDK 后直接 chat/start,不再登记 boot_id 或上报初始化回执。第 3、4 节仅供旧固件兼容,新设备不要实现。
## 1. 业务分工
平台在 ble-bind 请求中绑定老人、调用火山 DynamicRegister,保存物理设备的专属密钥和 RTCAppID,拿齐配置后才返回成功。后台任务保留作恢复兜底,与请求处理共用同一注册记录,不重复注册。设备不拿 product_secret,不调用 DynamicRegister。
物理设备只注册一次。重新绑定老人不重复注册;聊天时的 bot_id 跟随老人变化。注册超时不等于失败,平台标记待核对,不自动重复消耗注册流程。
## 2. 绑定时直接返回 5 个字段
`POST https://82.157.201.114/api/v1/device/ble-bind`
输入:`{"bind_token":"<原令牌>"}`。
成功 data(不再包含 voice_status / voice):
```json
{
"status":"success",
"instance_id":"<实例>",
"product_key":"<产品>",
"device_name":"<火山设备名>",
"device_secret":"<本设备的火山密钥>",
"RTCAppID":"<应用ID>"
}
```
success 必须带齐以上字段;设备保存它们和 Wi-Fi 后再向小程序报告 success。无需另调取参接口等待 ready。开机读取本地凭据初始化 SDK,聊天请求只需 device_id 和 session_id。
设备请求超时设 45 秒,平台取参等待上限 35 秒。HTTP 504 / VOICE_REGISTRATION_TIMEOUT 表示等待超时;502 / VOICE_REGISTRATION_FAILED 表示失败或结果未确认;503 / VOICE_REGISTRATION_PAUSED 表示服务暂停;502 / VOICE_CONFIG_INVALID 表示配置不完整;409 / VOICE_MIGRATION_REQUIRED 表示旧设备需补交凭据。它们都不返回成功或空配置,也不删除已完成的绑定。网络超时、5xx 保留原 bind_token 和 X-Request-ID 重试,刷新时间、nonce 和签名;注册结果不确定时由平台核对,不盲目重复注册。
若等待期间解绑,返回 409 / BINDING_CHANGED,不下发凭据。成功响应丢失后,即使原令牌已过期,只要原绑定仍有效,也能用原令牌重新取得相同配置。
以下是**可选恢复接口,正常绑定不需要调用**:
`POST https://82.157.201.114/api/v1/device/voice-config`
输入:`{}`。可在绑定后直接调用,不要求先完成本次 boot 登记。
成功 data 示例:
```json
{
"voice_status":"ready",
"voice":{
"instance_id":"<实例>",
"product_key":"<产品>",
"device_name":"<火山设备名>",
"device_secret":"<本设备的火山密钥>",
"RTCAppID":"<应用ID>"
}
}
```
preparing 时每 5 秒重试;paused、reconcile_required 时提示平台处理;migration_required 见第 5 节。非 ready 时 voice=null。解绑后返回 409 DEVICE_UNBOUND,不下发旧凭据。
## 3. 旧固件兼容:开机获取 SDK 配置(新设备不调用)
设备照常完成 time-challenges → register 后,调用:
`POST https://82.157.201.114/api/v1/device/voice-runtime`
输入:
```json
{"boot_id":"<本次已登记的开机UUID>"}
```
输出 data 中有:
| 字段 | 用途 |
|---|---|
| voice_status / voice | 与 voice-config 相同的状态和 5 个字段 |
| state | 当前绑定和激活状态 |
| command | ready 时的配置命令;未就绪时可为 null |
| command.payload.config_b64 | Base64URL 编码的配置,下例为解码后的内容 |
| command.payload.config_mac | 现有 CFG1 配置签名 |
| call_contract | 旧兼容字段,不据此切回旧聊天接口 |
```json
{
"contract_version":"ONBOARDING-1.1",
"device_id":"KP01-020000260914",
"activation_id":"<平台激活任务UUID>",
"config_version":1,
"binding_generation":1,
"expires_at_ms":1789459200000,
"iot":{
"instance_id":"<实例>",
"product_key":"<产品>",
"device_name":"<火山设备名>",
"device_secret":"<本设备的火山密钥>",
"RTCAppID":"<应用ID>"
},
"bot_id":"<兼容的默认值,实际聊天仍用chat/start返回值>"
}
```
校验 `config_mac=小写hex(HMAC_SHA256(烧录设备密钥, UTF8("CFG1\n"+config_b64)))`,再 Base64URL 解码 config_b64 并解析 JSON。核对 device_id、binding_generation 与 state 一致,expires_at_ms 未过期。新固件沿用此封装,不再提取 product_secret。
preparing 时自动等待,每 5 秒再次请求;不要把 preparing 当成需要解绑。获取配置后保存 5 个语音字段,以及 activation_id、config_version,再初始化 RTC SDK。
## 4. 旧固件兼容:SDK 初始化完成通知(新设备不调用)
`POST https://82.157.201.114/api/v1/device/activation-acks`
输入:
```json
{"activation_id":"<上一步UUID>","config_version":1,"local_generation":1}
```
activation_id、config_version 使用最新配置原值,local_generation 可使用 config_version。输出 data 中 accepted=true 表示平台已记录配置保存和 SDK 初始化完成;不是说用户已经完成第一次聊天。
随后每次聊天调用 chat/start,结合平台下发的凭据,用 SDK 获取 RTC 房间并收发音频。聊天结束继续调用 chat/end。
新设备不再调用 activation-attempts,也不发送 SDK_REGISTER activation-results。旧结果接口保留用于尚未上报完成的旧固件任务恢复。
## 5. 已注册旧设备的一次性迁移
旧固件可能只把火山密钥保存在本机,平台只有“已注册”记录。此时返回 migration_required,**不能重新注册这台设备**。
更新后的固件读取本机原凭据,调用:
`POST https://82.157.201.114/api/v1/device/voice-credentials`
输入:
```json
{
"instance_id":"<本机原实例>",
"product_key":"<本机原产品>",
"device_name":"<本机原火山设备名>",
"device_secret":"<本机原火山密钥>",
"RTCAppID":"<本机原应用ID>"
}
```
输出 data:`{"accepted":true}`。然后重新调用 voice-runtime。
平台只接受本设备已完成注册、身份匹配的旧凭据;相同内容重试不会重复写入,不允许覆盖平台已有的不同凭据。如果旧设备密钥已丢失,或注册结果不确定,需要运维核对,不能伪造凭据或盲目注册。
## 6. 接入与发布说明
以上设备 HTTP 接口均使用已有 DEVREQ1 请求头和 `{ok,code,request_id,server_time_ms,data}` 外层。设备凭据不经过小程序/蓝牙,不打印日志。平台凭据沿用既有加密存储格式。
后端 API 和 worker 已部署新服务器,旧 IP 暂时转发到新服务器。尚需用受控实物验证真实火山注册、设备持久化、SDK 初始化和实际通话。已有设备先备份运行凭据,不能把测试用凭据写入实物。