OTA 更新请求者 Cluster(OtaSoftwareUpdateRequestor)

Cluster ID: 0x002A  |  所在 Endpoint: Endpoint 0(Root Endpoint) |  角色: Server(设备作为 OTA 客户端)

OtaSoftwareUpdateRequestor 是 Matter OTA 升级体系中的客户端侧 —— 即需要被升级的设备。 它负责向 OTA Provider(升级提供者,对应 Cluster 0x0029)查询是否有新版本、下载固件、应用更新。 所有支持 OTA 的 Matter 设备都必须实现这个 Cluster。

OTA 双 Cluster 架构

Matter 的 OTA 升级由两个 Cluster 配合完成: OtaSoftwareUpdateProvider(0x0029) 是「服务端」,负责托管固件并响应查询; OtaSoftwareUpdateRequestor(0x002A) 是「客户端」,负责发起查询、下载并应用更新。 本页描述的是后者 —— 设备侧的行为。

命令(Commands)

OtaSoftwareUpdateRequestor 只有 1 个命令。它不是由设备自己发起的,而是由外部节点 (通常是 OTA Provider 或管理节点)发送给设备,告知设备可以去某个 Provider 查询更新。

ID 名称 说明 方向
0x00 AnnounceOTAProvider 通知设备有可用的 OTA Provider Client → Server

AnnounceOTAProvider —— 通告 OTA 提供者(0x00)

外部节点通过此命令告知设备:「有一个 OTA Provider 可以为你提供更新」。 收到此命令后,设备应尽快向指定的 Provider 发起更新查询(调用 Provider 的 QueryImage 命令)。 这是推送式 OTA 的核心触发机制 —— 让设备不必一直轮询,而是被动通知后再查询。

参数类型必填说明
ProviderNodeID node-id 是 OTA Provider 节点的 Node ID
VendorID vendor-id 是 Provider 的 Vendor ID,设备可据此判断是否信任该 Provider
AnnouncementReason AnnouncementReasonEnum 是 通告原因(见枚举说明)
MetadataForNode octstr 否 Provider 传给设备的自定义元数据(最长 512 字节,可选)
Endpoint endpoint-no 是 Provider 节点上 OTA Provider Cluster 所在的 Endpoint
使用场景

管理后台发布了新固件,通过 Hub 或管理节点向所有目标设备发送 AnnounceOTAProvider 命令。 设备收到后,会向指定的 Provider 查询可用更新。如果 AnnouncementReason 是 UrgentUpdateAvailable, 设备应优先处理,可能跳过用户确认直接开始下载。

属性详解

OtaSoftwareUpdateRequestor 有 4 个应用属性,分为「Provider 配置」和「更新状态」两组。

ID 名称 类型 分组 说明
0x0000 DefaultOTAProviders list<ProviderLocation> Provider 配置 默认 OTA Provider 列表
0x0001 UpdatePossible bool 更新状态 设备是否可以接受更新
0x0002 UpdateState UpdateStateEnum 更新状态 当前 OTA 更新状态机的状态
0x0003 UpdateStateProgress uint8 / null 更新状态 更新进度百分比(0-100)

Provider 配置(0x0000)

配置设备应该向哪些 OTA Provider 查询更新。每个 Fabric 最多配置一个 Provider。

ID 名称 类型 说明
0x0000 DefaultOTAProviders(默认 OTA 提供者) list<ProviderLocation> 设备默认查询的 OTA Provider 列表。每个条目是一个 ProviderLocation 结构体。 写入需要 manage 权限(Administrator 角色)。 每个 Fabric 最多包含一个条目 —— 同一 Fabric 写入新的会覆盖旧的

ProviderLocation 结构体

字段类型说明
ProviderNodeID node-id OTA Provider 的 Node ID
Endpoint endpoint-no Provider 上 OTA Provider Cluster 所在的 Endpoint
FabricIndex fabric-idx 此条目所属的 Fabric 索引(由系统自动填入)
Fabric 级别隔离

DefaultOTAProviders 是按 Fabric 隔离的 —— 每个 Fabric(管理域)只能看到和修改自己的条目。 这意味着设备同时加入多个 Fabric 时,各个 Fabric 的管理者可以各自指定自己的 OTA Provider,互不影响。

更新状态(0x0001 - 0x0003)

反映设备当前的 OTA 更新状态。这些属性均为只读,App 端通过订阅这些属性来跟踪更新进度。

ID 名称 类型 说明
0x0001 UpdatePossible(可否更新) bool 设备当前是否能够接受 OTA 更新。true 表示可以,false 表示设备当前不允许更新 (例如正在执行关键操作、电量过低等)。默认值为 true
0x0002 UpdateState(更新状态) UpdateStateEnum 设备 OTA 状态机的当前状态(见枚举说明)。 从这个属性可以知道设备正在查询、下载、应用还是空闲
0x0003 UpdateStateProgress(更新进度) uint8 / null 当前更新操作的进度百分比,取值 0-100。Nullable —— null 表示进度不可用 (例如设备处于 Idle 状态,或所处阶段无法计算进度时为 null)
进度百分比的含义随状态变化

UpdateStateProgress 的含义取决于 UpdateState 的当前值。 在 Downloading 状态下表示下载进度,在 Applying 状态下表示安装/写入进度。 状态切换时进度可能重置为 0 或 null。不要假设它是一个线性增长的全局进度值。

枚举速查

UpdateStateEnum —— 更新状态

描述设备 OTA 状态机的完整生命周期,共 9 个状态:

0
Unknown 未知 —— 设备刚启动、尚未确定更新状态
1
Idle 空闲 —— 无更新活动,正常运行中
2
Querying 查询中 —— 正在向 Provider 查询是否有可用更新
3
DelayedOnQuery 查询延迟 —— Provider 要求设备等待一段时间后再重试查询
4
Downloading 下载中 —— 正在从 Provider 下载固件镜像
5
Applying 应用中 —— 正在将下载的固件写入闪存并验证
6
DelayedOnApply 应用延迟 —— 固件已就绪,等待合适时机重启应用(例如等待用户确认或低峰期)
7
RollingBack 回滚中 —— 更新失败,正在恢复到之前的固件版本
8
DelayedOnUserConsent 等待用户同意 —— 更新已就绪,等待用户在设备或 App 上确认后再继续

AnnouncementReasonEnum —— 通告原因

AnnounceOTAProvider 命令中使用,告知设备此次通告的原因:

0
SimpleAnnouncement 普通通告 —— 仅告知存在一个 Provider,设备可自行决定是否查询
1
UpdateAvailable 有更新可用 —— 明确告知有新版本,设备应尽快查询
2
UrgentUpdateAvailable 紧急更新 —— 有安全补丁或严重 bug 修复,设备应立即查询并优先更新

ChangeReasonEnum —— 状态变更原因

在 StateTransition 事件中使用,说明状态机发生状态转移的原因:

0
Unknown 未知原因
1
Success 上一步操作成功,正常推进到下一阶段
2
Failure 操作失败(如下载中断、校验失败)
3
TimeOut 操作超时(如 Provider 无响应)
4
DelayByProvider Provider 要求延迟 —— Provider 返回了 Busy 或指定了重试等待时间

事件(Events)

OtaSoftwareUpdateRequestor 定义了 3 个事件,覆盖了 OTA 生命周期的关键节点。 订阅这些事件可以实时跟踪设备的更新流程,比轮询属性更及时。

ID 名称 优先级 说明
0x00 StateTransition Info OTA 状态机发生状态转移时触发
0x01 VersionApplied Critical 新固件版本成功应用后触发
0x02 DownloadError Info 固件下载过程中发生错误时触发

StateTransition —— 状态转移事件(0x00)

每当 OTA 状态机从一个状态转移到另一个状态时触发。这是追踪更新流程最核心的事件 —— 通过监听它可以知道设备从空闲到查询、从下载到应用的每一步。

字段ID类型说明
PreviousState 0x00 UpdateStateEnum 转移前的状态
NewState 0x01 UpdateStateEnum 转移后的新状态
Reason 0x02 ChangeReasonEnum 触发此次转移的原因
TargetSoftwareVersion 0x03 uint32 / null 目标固件版本号。null 表示尚未确定(例如从 Idle 到 Querying 时还不知道目标版本)

事件上报示例 —— 从 Idle 转入 Downloading:

{
  "eventReports": [{
    "eventData": {
      "path": {
        "endpointId": 0,
        "clusterId": "0x002A",
        "eventId": "0x00"          // StateTransition
      },
      "eventNumber": 15,
      "priority": "INFO",
      "data": {
        "0": 1,                    // PreviousState = Idle
        "1": 4,                    // NewState = Downloading
        "2": 1,                    // Reason = Success(查询成功,开始下载)
        "3": 5                     // TargetSoftwareVersion = 5
      }
    }
  }]
}

VersionApplied —— 版本已应用事件(0x01)

新固件版本成功应用后触发(通常在设备重启后上报)。这个事件是确认「更新真正完成」的标志。 优先级为 Critical,确保即使在事件队列满时也不会被丢弃。

字段ID类型说明
SoftwareVersion 0x00 uint32 刚刚应用的新固件版本号
ProductID 0x01 uint16 设备的产品 ID

事件上报示例:

{
  "eventReports": [{
    "eventData": {
      "path": {
        "endpointId": 0,
        "clusterId": "0x002A",
        "eventId": "0x01"          // VersionApplied
      },
      "eventNumber": 18,
      "priority": "CRITICAL",
      "data": {
        "0": 5,                    // SoftwareVersion = 5(刚刚应用的版本号)
        "1": 4                     // ProductID = 4(产品 ID)
      }
    }
  }]
}

DownloadError —— 下载错误事件(0x02)

固件下载过程中遇到错误时触发。此事件提供了出错时的上下文信息(已下载量、进度等), 有助于诊断网络问题或 Provider 端故障。

字段ID类型说明
SoftwareVersion 0x00 uint32 正在下载的目标固件版本号
BytesDownloaded 0x01 uint64 出错前已成功下载的字节数
ProgressPercent 0x02 uint8 / null 出错时的下载进度百分比(0-100),null 表示无法计算
PlatformCode 0x03 int64 / null 平台特定的错误码,null 表示无额外信息。具体含义由设备厂商定义

事件上报示例 —— 下载到 75% 时出错:

{
  "eventReports": [{
    "eventData": {
      "path": {
        "endpointId": 0,
        "clusterId": "0x002A",
        "eventId": "0x02"          // DownloadError
      },
      "eventNumber": 16,
      "priority": "INFO",
      "data": {
        "0": 5,                    // SoftwareVersion = 5
        "1": 512,                  // BytesDownloaded = 512
        "2": 75,                   // ProgressPercent = 75(下载到 75% 时出错)
        "3": -1                    // PlatformCode = -1(平台错误码,nullable)
      }
    }
  }]
}

示例数据

一个处于空闲状态的设备的 OtaSoftwareUpdateRequestor Cluster 属性读取结果:

{
  // --- 默认 OTA 提供者 ---
  "0x0000": [                     // DefaultOTAProviders(可配置多个)
    {
      "providerNodeID": 12345,    // Provider 的 Node ID
      "endpoint": 0,              // Provider 上 OTA Provider Cluster 所在的 Endpoint
      "fabricIndex": 1            // 所属 Fabric 索引
    }
  ],

  // --- 更新能力 ---
  "0x0001": true,                 // UpdatePossible = true(设备当前可以接受更新)

  // --- 更新状态 ---
  "0x0002": 0,                    // UpdateState = Idle(当前空闲,未在更新流程中)
  "0x0003": null                  // UpdateStateProgress = null(无进度信息)
}
开发提示

OTA Requestor Cluster 位于 Endpoint 0(Root Endpoint),不在功能端点上。 读取属性时注意指定正确的 Endpoint。此外,DefaultOTAProviders 是 Fabric-scoped 列表, 你只能看到当前 Fabric 的条目。

常见场景

场景 1:正常 OTA 更新流程

一次完整的 OTA 更新从通告到应用的典型流程:

  1. 管理节点向设备发送 AnnounceOTAProvider (0x00),告知有可用的 Provider
  2. 设备向 Provider 发起 QueryImage 请求 —— UpdateState 从 Idle 变为 Querying
  3. Provider 返回可用更新 —— 设备开始下载,UpdateState 变为 Downloading
  4. 下载过程中,UpdateStateProgress 从 0 逐渐增长到 100
  5. 下载完成,设备验证固件并开始写入 —— UpdateState 变为 Applying
  6. 写入完成,设备重启应用新固件 —— 重启后触发 VersionApplied 事件
  7. UpdateState 回到 Idle,整个流程结束
场景 2:Provider 通告触发更新

通过 AnnounceOTAProvider 命令的不同原因触发不同的设备行为:

  1. SimpleAnnouncement (0):设备可以在方便时查询,不急迫。适合常规固件发布场景
  2. UpdateAvailable (1):明确告知有新版本,设备应尽快查询。适合功能更新
  3. UrgentUpdateAvailable (2):紧急安全补丁,设备应立即查询并优先下载。 此时设备可能跳过 DelayedOnUserConsent 直接进入下载,确保安全漏洞尽快修补

App 端在收到 StateTransition 事件时,可根据 Reason 字段判断是否需要向用户展示通知。 UrgentUpdateAvailable 触发的更新建议弹出醒目提示。

场景 3:更新进度跟踪

App 端实时展示 OTA 更新进度的实现方式:

  1. 订阅 UpdateState (0x0002) 和 UpdateStateProgress (0x0003) 属性
  2. 同时订阅 StateTransition、VersionApplied、DownloadError 三个事件
  3. 根据 UpdateState 的值显示不同的 UI 状态:
    • Idle → 显示「固件已是最新」或「检查更新」按钮
    • Querying → 显示「正在检查更新...」
    • Downloading → 显示下载进度条,数值来自 UpdateStateProgress
    • Applying → 显示「正在安装更新,请勿断电...」
    • DelayedOnUserConsent → 显示确认对话框,等待用户同意
    • RollingBack → 显示「更新失败,正在恢复...」
  4. 收到 VersionApplied 事件 → 显示「更新成功!已升级到版本 X」
  5. 收到 DownloadError 事件 → 显示「下载失败」并展示已下载进度,提供重试按钮

注意:UpdateStateProgress 在状态切换时可能变为 null 或重置为 0, UI 应处理好 null 的情况(例如隐藏进度条或显示不确定进度指示器)。