Matter ASR 平台桥接示例(Bridge App)构建、配网与动态端点实战指南
【免费下载链接】connectedhomeipMatter (formerly Project CHIP) creates more connections between more objects, simplifying development for manufacturers and increasing compatibility for consumers, guided by the Connectivity Standards Alliance.项目地址: https://gitcode.com/GitHub_Trending/co/connectedhomeip
本指南以 connectedhomeip 仓库中的 examples/bridge-app/asr/README.md 为核心,系统讲解 Matter Bridge 应用在 ASR 平台上的实现原理与完整实操流程。你将掌握:桥接设备如何通过动态端点(Dynamic Endpoint)挂载非 Matter 设备、如何用build_examples.py构建固件、如何联合 chip-tool 与 DOGO 工具完成配网、ACL 授权与 Binding 绑定,以及如何通过实体按键验证桥接的灯控链路。
概述:什么是 Matter Bridge 与动态端点
Bridge(桥接)是 Matter 中一种典型的聚合型设备形态:一个 Matter 节点(桥)同时承载多个"子设备",把这些子设备以Endpoint(端点)的形式暴露给整个 Matter 网络,使得子设备可以被统一配网、统一控制。本示例是一个原型应用(prototype application),演示了动态端点(dynamic endpoint)机制结合设备配网(commissioning)与集群控制(cluster control)的完整流程:将 4 个非 CHIP(非 Matter)设备作为端点添加到桥(Matter 设备)上。
从 examples/bridge-app/asr/subdevice/subdevice_test.cpp 可以看到,本示例添加了 4 个支持On/Off 集群的灯设备作为端点:
- Light1位于端点 3
- Light2位于端点 4
- Light3位于端点 5
- Light4位于端点 6
也就是说,该桥接节点自身的端点布局为:
| Endpoint | 设备类型 | 说明 |
|---|---|---|
| 0 | 根节点(Root Node) | 承载基础与网络配网集群 |
| 1 | 聚合节点(Aggregate Node / Bridge) | 桥的"本身" |
| 2 | (固定占位端点) | 运行时被禁用(详见下文) |
| 3 ~ 6 | 桥接灯(LO_ON_OFF_LIGHT + BRIDGED_NODE) | 动态添加的 4 盏灯 |
其中端点 3~6 的映射关系在源码中有明确注释:Add lights 1..4 --> will be mapped to ZCL endpoints 3..6(见 subdevice_test.cpp)。
目录结构与源码模块
ASR 平台的 Bridge 示例位于examples/bridge-app/asr/,其核心源码构成如下:
examples/bridge-app/asr/ ├── include/ # AppConfig.h / AppTask.h / CHIPProjectConfig.h / DeviceCallbacks.h ├── src/ │ ├── AppTask.cpp # 应用任务入口:初始化 Matter 栈、服务器与网络配网实例 │ ├── DeviceCallbacks.cpp # 设备事件(IPv4/IPv6 连接、MDNS 等)回调 │ └── main.cpp # 主函数:初始化 ASR 平台并启动 FreeRTOS 调度器 ├── subdevice/ │ ├── SubDevice.h/.cpp # 子设备抽象类:状态、可达性、名称/位置与变更回调 │ ├── SubDeviceManager.cpp # 动态端点增删、外部属性读写回调与状态上报 │ └── subdevice_test.cpp # 添加 Light1~4 到端点 3~6 的测试例程 ├── BUILD.gn # GN 构建脚本,产出 chip-asr-bridge-example.out ├── args.gni / cfg.gni # 构建参数 └── README.md # 本指南对应的官方说明子设备抽象:SubDevice 类
每个桥接子设备都由 SubDevice 类建模。该类维护了子设备的核心状态:
- 开关状态
mState:kState_On/kState_Off,通过IsOn()/SetOnOff()访问; - 可达性
mReachable:表示该子设备当前是否在线,通过IsReachable()/SetReachable()访问; - 名称与位置
mName/mLocation:各 32 字节缓冲,对应 Bridged Device Basic Information 集群中的 NodeLabel 属性; - 端点号
mEndpointId:子设备被分配到的动态端点号; - 变更回调
mChanged_CB:状态、可达性、位置、名称任一变化时触发,由Changed_t掩码(kChanged_Reachable/kChanged_State/kChanged_Location/kChanged_Name)标识变化类型。
在 SubDevice.cpp 中可以看到,当SetOnOff(true)时除了更新内部状态并打印SubDevice[xxx]: ON日志外,在启用了CONFIG_ENABLE_ASR_APP_MESH的情况下,还会把开关命令下发给 ASR 应用 Mesh 层(app_mesh_control_light/app_mesh_control_fan),实现真正的物理设备控制。
动态端点管理:SubDeviceManager
SubDeviceManager.cpp 实现了桥的核心能力——动态端点(dynamic endpoint)的注册与注销:
AddDeviceEndpoint():在gSubDevices[]表中找到空槽,调用emberAfSetDynamicEndpoint()将子设备挂载到当前端点号;若端点号已被占用(CHIP_ERROR_ENDPOINT_EXISTS)则递增端点号并回绕到gFirstDynamicEndpointId重试;RemoveDeviceEndpoint():通过emberAfClearDynamicEndpoint()摘除子设备对应的动态端点并清空槽位。
桥在启动时通过Init_Bridge_Endpoint()(SubDeviceManager.cpp)完成初始化:
- 清空
gSubDevices数据库; - 计算第一个动态端点号
gFirstDynamicEndpointId(= 最后一个固定端点号 + 1); - 禁用最后一个固定占位端点(它仅为让 ZAP 生成全部所需集群代码而存在);
- 为端点 0 设置
DEVICE_TYPE_ROOT_NODE、为端点 1 设置DEVICE_TYPE_BRIDGE设备类型。
这些动态端点的属性并不存储在本地 ZCL 属性表中,而是通过外部属性读写回调动态提供:emberAfExternalAttributeReadCallback负责响应 On/Off 与 Bridged Device Basic Information 集群的属性读取(例如Reachable、NodeLabel、OnOff),emberAfExternalAttributeWriteCallback则响应 OnOff 属性的写入(SubDeviceManager.cpp)。此外,HandleDeviceStatusChanged()会在子设备可达性、状态或名称变化时,通过MatterReportingAttributeChangeCallback主动向 Matter 网络推送属性变更报告(subscription/reporting),保证桥对端点的状态总是最新。
构建固件
ASR 平台的完整构建与烧录环境准备,请先阅读平台的入门指南 docs/platforms/asr/asr_getting_started_guide.md(其 "Building the example application" 一节说明了 SDK 环境与工具链配置),然后执行以下命令构建 Bridge 示例:
./scripts/build/build_examples.py --target asr-$ASR_BOARD-bridge build其中$ASR_BOARD需要替换为你使用的 ASR 开发板标识(具体取值以 docs/platforms/asr/asr_getting_started_guide.md 中列出的板型为准)。该命令会通过仓库根目录下的 GN 构建流水线,产出名为chip-asr-bridge-example.out的可执行固件(见 examples/bridge-app/asr/BUILD.gn)。
从构建脚本 examples/bridge-app/asr/BUILD.gn 还可以看到,该示例默认启用ENABLE_ASR_BRIDGE_SUBDEVICE_TEST宏(即上文的子设备测试例程会被编译进固件),并复用测试用 Setup PIN Code 与 Discriminator 作为配网参数。
配网与功能验证
完成构建烧录后,按以下步骤完成配网与桥接验证。验证过程需要额外的一台 light-switch(灯开关)设备,用于作为 Matter 控制器侧的发起来源。
第一步:分别配网两台设备
- 将桥(bridge)设备配网,节点 ID(node-id)记为
1; - 将 light-switch 设备配网,节点 ID(node-id)记为
2。
配网通常通过 Matter 控制器(如 chip-tool / DOGO)扫描桥的配网二维码或 on-network 广播完成。桥设备启动后会在串口日志中打印 onboarding 二维码信息(见 AppTask.cpp,根据CONFIG_NETWORK_LAYER_BLE决定打印 BLE 或 on-network 方式的配网码)。
第二步:同步子设备并写入 ACL
两台设备均配网成功后:
- 使用 ASR 平台的GUI 工具
DOGO连接桥设备,输入AT 命令subdevice sync,触发桥执行Sync_SubDevice_test()——将 Light1~Light4 全部置为可达(SetReachable(true))、注册状态变更回调,并逐个挂载到动态端点 3~6(见 subdevice_test.cpp); - 使用 chip-tool 向桥设备(节点 1,端点 0)写入ACL(Access Control List),为控制器授予管理权限、为 light-switch 授予操作权限:
./chip-tool accesscontrol write acl \ '[{"fabricIndex": 1, "privilege": 5, "authMode": 2, "subjects": [112233], "targets": null }, {"fabricIndex": 1, "privilege": 3, "authMode": 2, "subjects": [2], "targets": null }]' \ 1 0对上述 ACL 条目的说明:
| 字段 | 含义 |
|---|---|
fabricIndex | 所属 Fabric 索引,1表示默认(首个)Fabric |
privilege | 授予的权限等级:5= Administer(管理),3= Operate(操作) |
authMode | 认证方式:2= CASE(基于证书的认证会话) |
subjects | 被授权的节点(Subject):112233为控制器自身节点 ID,2为 light-switch 节点 ID |
targets | 授权目标范围,null表示不限目标端点/集群 |
第一条为 chip-tool 控制器自身授予 Administer 权限(ACL 写入操作本身也需要管理权限),第二条为 light-switch 节点授予 Operate 权限,使其后续可以对桥的端点发起控制。
第三步:写入 Binding 绑定
使用 chip-tool 将 light-switch 的端点 1 与桥设备的端点 3(即 Light1)进行Binding 绑定:
./chip-tool binding write binding '[{"fabricIndex": 1, "node":1, "endpoint":3, "cluster":6}]' 2 1该命令的参数含义:
| 参数位置 | 含义 |
|---|---|
[{"fabricIndex": 1, "node":1, "endpoint":3, "cluster":6}] | 绑定目标:桥节点(node 1)的端点 3(Light1),cluster 6即 On/Off 集群(集群 ID0x0006) |
2 | 被写入 Binding 属性的目标节点:light-switch(节点 2) |
1 | 目标端点:light-switch 的端点 1 |
Binding 建立后,light-switch 便"认识"了桥上 Light1 所在的具体端点,后续按键即可触发对该端点的 On/Off 控制。
第四步:按键测试
本示例使用实体按键演示开关 Light1 的效果,按键定义如下:
| 名称 | Pin |
|---|---|
| BUTTON | PAD12 |
按下PAD12 上的 BUTTON后,light-switch 通过已建立的 Binding 向桥的端点 3 发送 On/Off 命令,桥的emberAfExternalAttributeWriteCallback会命中HandleWriteOnOffAttribute(SubDeviceManager.cpp),将状态写入 Light1 的SubDevice实例并触发SubDevice[Light 1]: ON/OFF日志输出。在桥设备的串口日志中即可观察到对应变化。
动态端点的底层工作方式小结
从上面的流程可以看到,ASR Bridge 示例的动态端点机制可归纳为三条主线:
- 注册:
AddDeviceEndpoint()+emberAfSetDynamicEndpoint()把子设备映射到连续端点号(3~6),桥对端点 0/1 分别声明 Root Node 与 Bridge 设备类型; - 读写:端点属性不落本地存储,全部经由
emberAfExternalAttributeReadCallback/emberAfExternalAttributeWriteCallback转发到SubDevice对象,真正实现"状态存于应用、属性动态呈现"; - 上报:子设备状态变化通过
HandleDeviceStatusChanged()主动触发 Matter 属性变更报告,让网络中的订阅方实时感知桥接设备状态。
这套"子设备对象 + 动态端点 + 外部属性回调"的设计,正是 Matter Bridge 接入非 Matter 生态设备(例如 ASR 应用 Mesh 灯)的通用范式,可直接推广到温度计、窗帘电机等更多 On/Off 或传感器类设备的桥接场景。
【免费下载链接】connectedhomeipMatter (formerly Project CHIP) creates more connections between more objects, simplifying development for manufacturers and increasing compatibility for consumers, guided by the Connectivity Standards Alliance.项目地址: https://gitcode.com/GitHub_Trending/co/connectedhomeip
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考