xiaozhi/py-xiaozhi-main/documents/docs/guide/08_设备激活流程.md
2025-07-18 13:14:28 +08:00

14 KiB
Executable File
Raw Blame History

设备激活流程 v2

概述

当前流程是虾哥设备认证v2版本

激活流程

每个设备都有一个唯一的序列号(Serial Number)和HMAC密钥(HMAC Key),用于身份验证和安全通信。新设备首次使用时需要通过以下流程进行激活:

  1. 客户端启动时向服务器发送设备信息包括序列号、MAC地址和客户端ID
  2. 服务器检查设备是否已激活:
    • 如果已激活,客户端正常工作
    • 如果未激活服务器返回包含验证码和Challenge的激活请求
  3. 客户端显示验证码提示用户前往xiaozhi.me网站输入验证码
  4. 客户端使用HMAC密钥对Challenge进行签名并发送给服务器验证
  5. 客户端通过轮询方式等待服务器确认验证结果:
    • 如果验证成功,设备激活完成
    • 如果验证失败或超时,设备激活失败

小智 ESP32 设备激活流程图

┌────────────────────┐
│     设备启动       │
└──────────┬─────────┘
           ↓
┌────────────────────┐
│   初始化各组件     │
│   连接WiFi/网络    │
└──────────┬─────────┘
           ↓
┌────────────────────┐
│  调用CheckVersion  │
│  访问OTA服务器     │──→ POST /xiaozhi/ota/
└──────────┬─────────┘
           ↓
┌────────────────────┐
│  解析服务器响应    │
└──────────┬─────────┘
           ↓
     ┌─────┴─────┐
     ↓           ↓
┌─────────┐ ┌─────────┐
│是否有新版本│ │是否需要激活│
└─────┬───┘ └─────┬───┘
      │           │
┌─────▼───┐       └───┬─── 否 ──┐
│升级固件  │           ↓         ↓
└─────────┘  ┌─────────────┐ ┌─────────────┐
             │是否有激活码  │ │初始化协议连接│
             └──────┬──────┘ │MQTT/WebSocket│
                    │        └─────────────┘
              ┌────▼───┐
              │   是   │
              └────┬───┘
                   ↓
        ┌──────────────────┐
        │显示激活码给用户   │
        │播放语音提示      │
        └────────┬─────────┘
                 ↓
        ┌──────────────────┐
        │ 开始激活流程      │
        └────────┬─────────┘
                 ↓
┌────────────────────────────────┐
│        检查设备序列号          │
└───────────────┬────────────────┘
                ↓
         ┌──────┴───────┐
         ↓              ↓
    ┌─────────┐    ┌─────────┐
    │  有序列号 │    │ 无序列号 │
    └─────┬────┘    └────┬────┘
          │              │
┌─────────▼────────┐    │
│构造激活载荷JSON:  │    │
│- serial_number    │    │
│- challenge        │    │
│- hmac签名         │    │
└─────────┬─────────┘    │
          │              │
          └──────┬───────┘
                 ↓
    ┌───────────────────────┐
    │发送POST请求到激活端点  │──→ POST /xiaozhi/ota/activate
    └────────────┬──────────┘
                 ↓
     ┌───────────┴───────────┐
     ↓           ↓           ↓
┌─────────┐ ┌─────────┐ ┌─────────┐
│状态码200 │ │状态码202 │ │其他状态码│
│激活成功  │ │超时重试  │ │激活失败  │
└────┬────┘ └────┬────┘ └────┬────┘
     │           │           │
     │      ┌────▼─────┐     │
     │      │延迟后重试 │     │
     │      │最多10次   │     │
     │      └────┬─────┘     │
     │           │           │
     └───────────┼───────────┘
                 ↓
        ┌──────────────────┐
        │设置激活状态标志位 │
        └────────┬─────────┘
                 ↓
        ┌──────────────────┐
        │  继续正常运行     │
        │  连接MQTT/WS协议  │
        └──────────────────┘

激活数据交互详细流程

┌────────────┐                      ┌────────────┐                      ┌────────────┐
│            │                      │            │                      │            │
│  设备客户端  │                      │   服务器    │                      │  用户浏览器  │
│            │                      │            │                      │            │
└─────┬──────┘                      └─────┬──────┘                      └─────┬──────┘
      │                                   │                                   │
      │  请求设备状态 (MAC, ClientID, SN)   │                                   │
      │ ────────────────────────────────> │                                   │
      │                                   │                                   │
      │  返回激活请求 (验证码, Challenge)    │                                   │
      │ <──────────────────────────────── │                                   │
      │                                   │                                   │
      │ 显示验证码                          │                                   │
      │ ┌─────────────┐                   │                                   │
      │ │请前往网站输入 │                   │                                   │
      │ │验证码: 123456│                   │                                   │
      │ └─────────────┘                   │                                   │
      │                                   │                                   │
      │                                   │          用户访问xiaozhi.me        │
      │                                   │ <─────────────────────────────────│
      │                                   │                                   │
      │                                   │          输入验证码 123456          │
      │                                   │ <─────────────────────────────────│
      │                                   │                                   │
      │ 计算HMAC签名                        │                                   │
      │ ┌─────────────┐                   │                                   │
      │ │ HMAC(密钥,   │                   │                                   │
      │ │  Challenge) │                   │                                   │
      │ └─────────────┘                   │                                   │
      │                                   │                                   │
      │  发送激活请求 (SN, Challenge, 签名)  │                                   │
      │ ────────────────────────────────> │                                   │
      │                                   │  ┌───────────────┐                │
      │                                   │  │ 等待用户输入验证码 │                │
      │                                   │  │ 超时返回202    │                │
      │                                   │  └───────────────┘                │
      │                                   │                                   │
      │  轮询等待 (HTTP Long Polling)       │                                   │
      │ ────────────────────────────────> │                                   │
      │  HTTP 202 (Pending)               │                                   │
      │ <──────────────────────────────── │                                   │
      │                                   │                                   │
      │  继续轮询...                        │                                   │
      │ ────────────────────────────────> │                                   │
      │                                   │                                   │
      │                                   │          验证码验证成功             │
      │                                   │───────────────────────────────────│
      │                                   │                                   │
      │  激活成功 (HTTP 200)                │                                   │
      │ <──────────────────────────────── │                                   │
      │                                   │                                   │
      │ ┌─────────────┐                   │                                   │
      │ │设备激活成功! │                   │                                   │
      │ └─────────────┘                   │                                   │
      │                                   │                                   │

设备与服务器通信内容详解

1. 设备信息请求 (POST /xiaozhi/ota/)

请求头:

Activation-Version: 2  // 表示支持序列号激活
Device-Id: AA:BB:CC:DD:EE:FF  // MAC地址 
Client-Id: xxxx-xxxx-xxxx-xxxx  // 设备UUID
User-Agent: BOARD_NAME/1.0.0  // 开发板名称和固件版本
Content-Type: application/json

请求体 (POST时):

{
  "version": 2,
  "flash_size": 16777216,
  "psram_size": 8388608,
  "minimum_free_heap_size": 7265024,
  "mac_address": "你的mac地址",
  "uuid": "你的client_id",
  "chip_model_name": "esp32s3",
  "chip_info": {
    "model": 9,
    "cores": 2,
    "revision": 0,
    "features": 20
  },
  "application": {
    "name": "xiaozhi",
    "version": "1.6.0",
    "compile_time": "2025-04-16T12:00:00Z",
    "idf_version": "v5.3.2"
  },
  "partition_table": [
    {
      "label": "nvs",
      "type": 1,
      "subtype": 2,
      "address": 36864,
      "size": 24576
    },
    {
      "label": "otadata",
      "type": 1,
      "subtype": 0,
      "address": 61440,
      "size": 8192
    },
    {
      "label": "app0",
      "type": 0,
      "subtype": 0,
      "address": 65536,
      "size": 1966080
    },
    {
      "label": "app1",
      "type": 0,
      "subtype": 0,
      "address": 2031616,
      "size": 1966080
    },
    {
      "label": "spiffs",
      "type": 1,
      "subtype": 130,
      "address": 3997696,
      "size": 1966080
    }
  ],
  "ota": {
    "label": "app0"
  },
  "board": {
    "type": "lc-esp32-s3",
    "name": "立创ESP32-S3开发板",
    "features": ["wifi", "ble", "psram", "octal_flash"],
    "ip": "你的ip地址",
    "mac": "你的mac地址"
  }
}

2. 服务器响应

响应体:

{
  "firmware": {
    "version": "1.0.1",
    "url": ""
  },
  "activation": {
    "message": "请访问xiaozhi.me输入激活码",
    "code": "123456",
    "challenge": "randomstring123456",
    "timeout_ms": 30000
  },
  "mqtt": {
    "endpoint": "mqtt.xiaozhi.me",
    "client_id": "device123",
    "username": "user123",
    "password": "pass123",
    "publish_topic": ""
  },
  "websocket": {
    "url": "wss://api.tenclass.net/xiaozhi/v1/",
    "token": "test-token"
  }
}

3. 设备激活请求 (POST /xiaozhi/ota/activate)

请求体:

{
  "Payload": {
    "algorithm": "hmac-sha256",
    "serial_number": "SN-5CD8467B47FB4920",
    "challenge": "dac852d6-4ac4-4650-ba1a-c2a5bf00a766",
    "hmac": "ada4775e3ed93cf9c0eb9ed00444138554ba416af41283a0e5603c77681a8022"
  }
}

4. 激活响应

  • 成功: 状态码 200
  • 等待用户输入验证码: 状态码 202
  • 失败: 状态码 4xx (如401表示未授权400表示请求错误)

响应体 (失败时):

{
  "error": "错误原因描述"
}

安全机制

设备激活流程v2版本采用以下安全机制

  1. 设备唯一标识:每个设备有一个唯一的序列号(Serial Number)
  2. HMAC签名验证使用HMAC-SHA256算法对Challenge进行签名确保设备身份的真实性
  3. 验证码验证:通过要求用户在网页端输入验证码,防止自动化的激活攻击
  4. 轮询等待机制使用HTTP Long Polling等待服务器验证结果适应各种网络环境