OTA 更新提供者 Cluster(OtaSoftwareUpdateProvider)

Cluster ID: 0x0029  |  所在 Endpoint: 固定在 Endpoint 0(Root Endpoint) |  角色: Client Cluster(由 Provider 节点实现)

OtaSoftwareUpdateProvider 是 Matter OTA(Over-The-Air)固件更新机制的服务端 Cluster —— 它运行在提供固件镜像的节点上(通常是 Hub、网关或云端代理),负责响应其他设备的固件查询请求、 管控更新节奏、以及接收更新完成通知。

在 Matter 的 OTA 架构中,需要更新的设备叫做 Requestor(请求者), 提供固件的节点叫做 Provider(提供者)。Requestor 主动向 Provider 发起查询, Provider 告诉它有没有新版本、从哪里下载、是否需要用户同意。整个流程是「拉取」模式,不是推送。

Client Cluster 说明

OtaSoftwareUpdateProvider 是一个 Client Cluster —— 它定义的是 Provider 端接收的命令, 而不是暴露的属性。因此这个 Cluster 没有属性可读取,所有交互都通过命令完成。 与之配对的 OtaSoftwareUpdateRequestor(0x002A) 是 Server Cluster, 运行在需要更新的设备上,负责发起查询和执行下载。

命令(Commands)

OtaSoftwareUpdateProvider Cluster 共有 3 个请求命令,其中 2 个有对应的响应命令,1 个是单向通知。 这三个命令构成了完整的 OTA 更新生命周期:查询 → 确认安装 → 通知完成。 点击下方表格中的命令 ID 可跳转到对应的详细说明。

Requestor → Provider(请求命令)

ID 名称 说明 响应
0x00 QueryImage 查询是否有可用的固件更新 QueryImageResponse
0x02 ApplyUpdateRequest 下载完成,请求确认是否安装 ApplyUpdateResponse
0x04 NotifyUpdateApplied 通知 Provider 更新已成功安装 无响应

Provider → Requestor(响应命令)

ID 名称 说明 对应请求
0x01 QueryImageResponse 返回固件查询结果(有无更新、下载地址等) QueryImage
0x03 ApplyUpdateResponse 返回是否允许安装更新 ApplyUpdateRequest

QueryImage —— 查询固件更新(0x00)

Requestor 发送此命令询问 Provider:「我是这个型号、这个版本的设备,你那有没有更新给我?」 这是整个 OTA 流程的第一步。Provider 根据 Requestor 提供的厂商 ID、产品 ID、 当前版本号等信息,判断是否有适用的固件镜像。

参数类型必选说明
VendorID vendor-id 是 Requestor 的厂商 ID(与 BasicInformation Cluster 中的一致)
ProductID uint16 是 Requestor 的产品 ID
SoftwareVersion uint32 是 Requestor 当前运行的固件版本号
ProtocolsSupported list<DownloadProtocolEnum> 是 Requestor 支持的下载协议列表(如 BDX、HTTPS)
HardwareVersion uint16 否 Requestor 的硬件版本号(某些固件仅适用于特定硬件版本)
Location String (2 字符) 否 ISO 3166-1 alpha-2 国家代码(如 "CN"),用于区域限定的固件分发
RequestorCanConsent bool 否 Requestor 是否有能力向用户展示更新同意对话框(如带屏幕的设备)
MetadataForProvider octstr 否 厂商自定义的元数据(Provider 可据此做额外判断)

QueryImageResponse 响应字段

字段类型条件说明
Status StatusEnum 始终 查询结果状态
DelayedActionTime uint32(秒) 可选 当 Status 为 Busy 时,建议 Requestor 等待这么多秒后重试
ImageURI String (max 256) UpdateAvailable 固件镜像的下载地址(BDX URI 或 HTTPS URL)
SoftwareVersion uint32 UpdateAvailable 新固件的版本号
SoftwareVersionString String (max 64) UpdateAvailable 新固件的版本字符串(人类可读,如 "2.0.0")
UpdateToken octstr (max 32) UpdateAvailable 更新令牌 —— 后续 ApplyUpdateRequest 和 NotifyUpdateApplied 必须携带此令牌
UserConsentNeeded bool 可选 是否需要用户在 Requestor 侧手动确认更新(默认 false)
MetadataForRequestor octstr 可选 Provider 返回给 Requestor 的厂商自定义数据
UpdateToken 的重要性

UpdateToken 是贯穿整个 OTA 流程的凭据。Requestor 在后续的 ApplyUpdateRequest 和 NotifyUpdateApplied 中必须携带同一个 Token,Provider 借此追踪更新会话。 Token 最长 32 字节,由 Provider 生成,内容和格式由厂商自定义。

使用场景与注意事项

Requestor 通常在以下时机调用 QueryImage:周期性检查(如每 24 小时)、设备重启后、或收到管理员的检查指令。 Provider 可能返回 Busy 并附带 DelayedActionTime,让 Requestor 稍后重试 —— 这在大规模设备场群中很常见,Provider 通过错峰控制避免同时下载导致的网络拥塞。

ApplyUpdateRequest —— 请求安装更新(0x02)

Requestor 下载完固件镜像并校验通过后,发送此命令询问 Provider:「我准备好安装了,可以继续吗?」 Provider 可以在此刻做最后的决策 —— 批准安装、要求等待、或者取消更新。 这一步的存在让 Provider 对整个更新流程拥有最终控制权。

参数类型说明
UpdateToken octstr QueryImageResponse 中返回的更新令牌
NewVersion uint32 即将安装的新固件版本号(应与 QueryImageResponse 中的 SoftwareVersion 一致)

ApplyUpdateResponse 响应字段

字段类型说明
Action ApplyUpdateActionEnum Provider 对安装请求的决策
DelayedActionTime uint32(秒) 当 Action 为 AwaitNextAction 时,Requestor 应等待这么多秒后再次请求
Provider 的更新控制权

即使 Requestor 已经下载好了固件,Provider 仍然可以通过 AwaitNextAction 延迟安装时间 (比如等到凌晨低峰期),或通过 Discontinue 直接取消更新(比如发现这个版本有严重 bug)。 这种设计让 Provider 在整个 OTA 流程中始终保持控制力。

使用场景与注意事项

典型流程:Requestor 下载完固件 → 校验 OTA Image 签名 → 发送 ApplyUpdateRequest → 收到 Proceed → 执行安装并重启。 如果 Provider 返回 AwaitNextAction,Requestor 应等待 DelayedActionTime 秒后重新发送 ApplyUpdateRequest。 如果收到 Discontinue,Requestor 应放弃安装并丢弃已下载的镜像。

NotifyUpdateApplied —— 通知更新已完成(0x04)

Requestor 成功安装固件并重启后,发送此命令告知 Provider 更新已完成。 这是整个 OTA 流程的最后一步 —— 一个单向通知,没有响应命令。 Provider 收到后可以更新自己的记录(如标记该设备已更新到新版本)。

参数类型说明
UpdateToken octstr 本次更新会话的令牌(与 QueryImageResponse 中的一致)
SoftwareVersion uint32 更新后的当前固件版本号
为什么没有响应?

NotifyUpdateApplied 是纯通知性质的 —— Requestor 不需要 Provider 的确认。 设备已经成功重启运行在新版本上,即使 Provider 没收到这个通知,也不影响设备正常工作。 Provider 端通常用这个通知来更新统计数据(如「已有多少设备升级到新版本」)。

使用场景与注意事项

设备重启后应尽快发送此通知。如果 Requestor 在重启后无法立即连接到 Provider(如网络恢复需要时间), 它应该在恢复连接后补发。规范建议 Requestor 在重启后的首次 Idle 状态下发送 NotifyUpdateApplied。

枚举定义

StatusEnum(查询结果状态)

QueryImageResponse 的 Status 字段使用此枚举,表示 Provider 对固件查询的回答。

0
UpdateAvailable 有可用更新 —— 响应中包含下载地址、版本号、UpdateToken 等完整信息
1
Busy Provider 当前繁忙 —— Requestor 应等待 DelayedActionTime 秒后重试
2
NotAvailable 无可用更新 —— 当前固件已是最新版本
3
DownloadProtocolNotSupported 下载协议不支持 —— Requestor 声明的协议列表中没有 Provider 能提供的
Status 处理速查

UpdateAvailable → 开始下载 ImageURI 指向的固件; Busy → 等待 DelayedActionTime 秒后重新 QueryImage; NotAvailable → 无事可做,按正常周期下次再查; DownloadProtocolNotSupported → 检查 Requestor 的 ProtocolsSupported 列表,确认是否遗漏了 Provider 支持的协议。

ApplyUpdateActionEnum(安装决策)

ApplyUpdateResponse 的 Action 字段使用此枚举,表示 Provider 对安装请求的决策。

0
Proceed 允许安装 —— Requestor 可以立即执行固件安装并重启
1
AwaitNextAction 暂缓安装 —— Requestor 应等待 DelayedActionTime 秒后再次请求
2
Discontinue 取消更新 —— Requestor 应放弃安装并丢弃已下载的镜像

DownloadProtocolEnum(下载协议)

QueryImage 的 ProtocolsSupported 参数使用此枚举,声明 Requestor 支持哪些固件下载方式。

0
BDXSynchronous BDX 同步传输 —— Matter 内置的块数据交换协议(最常用,适合局域网内传输)
1
BDXAsynchronous BDX 异步传输 —— 允许传输过程中穿插其他 Matter 消息
2
HTTPS HTTPS 下载 —— 从 Web 服务器下载,适合设备能直接访问互联网的场景
3
VendorSpecific 厂商自定义协议 —— 使用厂商私有的传输方式
BDX vs HTTPS

大多数 Matter 设备使用 BDX(Bulk Data Exchange) 协议下载固件, 因为它走 Matter 消息通道,不需要设备有独立的互联网连接能力。 HTTPS 适合有 Wi-Fi 的设备直接从云端下载,速度更快但需要设备能访问外网。 Thread 设备(如门锁、传感器)通常只支持 BDX,因为它们通过 Border Router 联网,不一定能直接发起 HTTPS 请求。

示例数据

QueryImage 交互示例

Requestor 向 Provider 查询可用更新 —— Provider 回复「有新版本可用」:

// Requestor → Provider:查询是否有可用固件
{
  "invokeRequests": [{
    "commandPath": {
      "endpointId": 0,
      "clusterId": "0x0029",
      "commandId": "0x00"          // QueryImage
    },
    "commandFields": {
      "vendorID": 65521,           // 厂商 ID(0xFFF1 = 测试厂商)
      "productID": 32769,          // 产品 ID
      "softwareVersion": 1,        // 当前固件版本号
      "protocolsSupported": [0],   // 支持的下载协议:BDXSynchronous
      "hardwareVersion": 0,        // 可选:硬件版本
      "location": "CN",            // 可选:ISO 3166-1 国家代码
      "requestorCanConsent": true, // 可选:Requestor 能否向用户展示同意确认
      "metadataForProvider": null  // 可选:厂商自定义数据
    }
  }]
}

// Provider → Requestor:有可用更新
{
  "status": 0,                     // UpdateAvailable
  "delayedActionTime": 0,         // 无需等待,立即可下载
  "imageURI": "bdx://provider-node-id/firmware-v2.ota",
  "softwareVersion": 2,           // 新固件版本号
  "softwareVersionString": "2.0.0",
  "updateToken": "dXBkYXRlLXRva2VuLXYy", // Base64 编码的更新令牌
  "userConsentNeeded": false,      // 无需用户额外确认
  "metadataForRequestor": null     // 无厂商自定义数据
}

ApplyUpdateRequest 交互示例

Requestor 下载完成,向 Provider 确认是否可以安装:

// Requestor → Provider:下载完成,请求应用更新
{
  "invokeRequests": [{
    "commandPath": {
      "endpointId": 0,
      "clusterId": "0x0029",
      "commandId": "0x02"          // ApplyUpdateRequest
    },
    "commandFields": {
      "updateToken": "dXBkYXRlLXRva2VuLXYy",  // QueryImageResponse 中的令牌
      "newVersion": 2              // 即将安装的版本号
    }
  }]
}

// Provider → Requestor:确认继续安装
{
  "action": 0,                     // Proceed(允许安装)
  "delayedActionTime": 0           // 无需等待
}

NotifyUpdateApplied 示例

Requestor 安装成功并重启后,通知 Provider 更新已完成:

// Requestor → Provider:已成功安装并重启
{
  "invokeRequests": [{
    "commandPath": {
      "endpointId": 0,
      "clusterId": "0x0029",
      "commandId": "0x04"          // NotifyUpdateApplied
    },
    "commandFields": {
      "updateToken": "dXBkYXRlLXRva2VuLXYy",  // 原始更新令牌
      "softwareVersion": 2         // 更新后的当前版本号
    }
  }]
}
// 此命令无响应(单向通知)
开发提示

在开发 OTA Provider 时,最核心的逻辑在 QueryImage 的处理 —— 你需要根据 VendorID + ProductID + SoftwareVersion 匹配正确的固件,并通过 ProtocolsSupported 选择合适的下载方式。 如果你的设备群规模较大,善用 Busy 状态和 DelayedActionTime 做错峰分发。

常见场景

场景 1:标准固件更新流程
  1. Requestor 向 Provider 发送 QueryImage (0x00),携带自身的厂商 ID、产品 ID、当前版本号和支持的下载协议
  2. Provider 回复 QueryImageResponse,Status = UpdateAvailable,包含 ImageURI、新版本号和 UpdateToken
  3. Requestor 通过 ImageURI 下载固件镜像(BDX 或 HTTPS)
  4. 下载完成后,Requestor 校验镜像签名(OTA Image 头部包含厂商签名)
  5. 校验通过,Requestor 发送 ApplyUpdateRequest (0x02),携带 UpdateToken 和 NewVersion
  6. Provider 回复 ApplyUpdateResponse,Action = Proceed
  7. Requestor 执行固件安装并重启
  8. 重启后,Requestor 发送 NotifyUpdateApplied (0x04),告知 Provider 更新成功

整个流程从查询到安装完成,通常需要数分钟到数十分钟,取决于固件大小和网络条件。

场景 2:固件回滚(紧急撤回有问题的版本)
  1. 厂商发现新版本 v2.0.0 有严重 bug,需要紧急撤回
  2. Provider 端下架 v2.0.0 的固件,改为提供 v1.0.1(修复版或回退版)
  3. 已更新到 v2.0.0 的设备下次 QueryImage 时,Provider 回复 UpdateAvailable,指向 v1.0.1
  4. 尚未更新的设备 QueryImage 时,Provider 回复 NotAvailable(跳过 v2.0.0)
  5. 如果有设备已下载 v2.0.0 但还没安装(在 ApplyUpdateRequest 阶段),Provider 回复 Discontinue 取消安装

关键点:Matter OTA 规范允许「降级」更新 —— SoftwareVersion 可以比当前版本低。 但实际能否降级取决于设备端的实现:部分设备的 bootloader 可能会拒绝安装低于当前版本的固件。

场景 3:多设备批量更新(错峰分发)
  1. 厂商发布新固件,设备群中有 10,000 台设备需要更新
  2. Provider 不希望所有设备同时下载,避免网络拥塞
  3. 前 100 台设备 QueryImage 时,Provider 回复 UpdateAvailable,立即允许下载
  4. 第 101 台开始,Provider 回复 Busy,DelayedActionTime = 3600(1 小时后重试)
  5. 每批完成后,Provider 逐步放开下一批的配额
  6. 如果某设备下载完成后 Provider 希望它等到凌晨再安装,ApplyUpdateRequest 回复 AwaitNextAction,DelayedActionTime 设为到凌晨的秒数

实现建议:Provider 可以维护一个更新队列和并发计数器。 通过灵活使用 Busy(控制下载并发)和 AwaitNextAction(控制安装时机), 实现从容的灰度发布和错峰分发。

场景 4:需要用户同意的更新
  1. Requestor 在 QueryImage 中声明 RequestorCanConsent = true(设备有屏幕,可以展示确认对话框)
  2. Provider 回复 UpdateAvailable,UserConsentNeeded = true
  3. Requestor 收到响应后,在设备屏幕上弹出确认对话框:「有新版本 v2.0.0 可用,是否更新?」
  4. 用户点击「确认」后,Requestor 才开始下载固件
  5. 如果用户拒绝,Requestor 暂不下载,下次检查周期再次询问

无屏设备:如果 Requestor 没有屏幕(RequestorCanConsent = false), Provider 通常不会设置 UserConsentNeeded = true。对于这类设备,用户同意可以通过手机 App 中的 OTA 管理界面来实现(App 作为中间人传达用户意图)。