ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Matter(Project CHIP)Echo 回声协议解析:从 Exchange 机制到 chip-echo-requester / chip-echo-responder 示例应用

2026/9/19 4:46:31 拓冰建站 浏览量
Matter(Project CHIP)Echo 回声协议解析:从 Exchange 机制到 chip-echo-requester / chip-echo-responder 示例应用 MatterProject CHIPEcho 回声协议解析从 Exchange 机制到 chip-echo-requester / chip-echo-responder 示例应用【免费下载链接】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/connectedhomeipMatter前身 Project CHIP在src/messaging/tests/echo/目录下提供了一个非常小巧但完整的协议实现示例——CHIP Echo 协议。它模仿 ICMP 的 Echo Request/Echo Response 语义在 CHIP 传输层之上构建发送请求→对端回显响应的对话是理解 CHIP 协议、CHIP Exchange 会话对象、消息传输层乃至安全会话建立机制的绝佳切入点。本文以仓库中的 示例说明文档 为主线结合 echo_requester.cpp、echo_responder.cpp 与 Echo 协议实现 等源码完整讲解该示例的构建、运行、协议原理与实现细节读完你既能亲手跑通一次 Echo 双向通信也能掌握在 CHIP 栈上实现自定义协议应用的标准套路。一、背景知识CHIP 协议、CHIP Exchange 与消息层在动手构建之前需要先理解 README 中强调的三个核心概念它们构成了整个 Echo 示例的骨架CHIP 协议CHIP Protocol本质上是在 CHIP 传输之上实现的特定协议。CHIP 协议栈已经内置了多种标准协议见 src/protocols/Protocols.hEcho 协议即其中之一其协议标识为CHIP_STANDARD_PROTOCOL(Echo, 0x0004)注释中注明Echo Protocol. To be removed or standardized.说明它是一个以教学和测试为主要目的的内置协议。CHIP Exchange会话当两个 CHIP 节点就某个特定协议交换消息时它们在一种称为 CHIP Exchange 的结构上进行——它描述了一次基于 CHIP 协议的对话。每一次 Exchange 都由ExchangeContext对象来刻画任何 CHIP 节点在发起一次 CHIP 对话之前都必须先创建一个ExchangeContext对象。在 Echo 示例中EchoClient::SendEchoRequest()通过mExchangeMgr-NewContext(...)创建 ExchangeContext见 EchoClient.cpp而EchoServer则作为UnsolicitedMessageHandler被动接收对方发起会话的消息见 Echo.h。消息传输层构造好ExchangeContext之后CHIP 消息通过ChipMessageLayer类即代码中的SessionManager/TransportMgr体系在选定的传输方式UDP、TCP 或 MRP上收发。Echo 示例同时演示了 UDP 与 TCP 两种底层传输的配置方式。二、构建示例三步产出两个可执行文件README 给出了标准的 GN 构建流程在仓库根目录依次执行source scripts/activate.sh gn gen out/debug ninja -C out/debugsource scripts/activate.sh激活项目的构建环境激活 Pigweed/编译环境相关脚本仓库中位于 scripts/activate.sh。gn gen out/debug生成 GN 构建目录。ninja -C out/debug编译全部目标。构建完成后两个可执行文件会出现在构建目录中README 明确给出的路径out/debug/chip-echo-requester out/debug/chip-echo-responder二进制之所以直接落在out/debug根目录是因为 BUILD.gn 中两个executable目标都设置了output_dir root_out_dir。该 BUILD.gn 的结构也很清晰source_set(common)打包了请求方与响应方共享的全局对象和初始化逻辑common.cpp随后分别构建chip-echo-requester与chip-echo-responder两个executable最后由group(echo)聚合方便通过ninja -C out/debug echo单独编译这一示例。三、示例应用走读Requester 与 Responder 的角色划分这个示例由两个程序组成对应 README 的 Example Applications Walk Through 一节ChipEchoRequester扮演客户端周期性地向对端发送 EchoRequest 消息ChipEchoResponder扮演服务端接收 EchoRequest 并回送 EchoResponse 消息。共享的初始化骨架common两个程序共用 common.h / common.cpp 中定义的全局组件这正好对应 README 所讲的协议运行于 CHIP 传输之上gFabricTableFabric 表、gSessionManager会话管理即消息层核心、gExchangeManagerExchange 管理负责创建 ExchangeContext、gMessageCounterManager消息计数器防重放、gStorageTestPersistentStorageDelegate测试持久化与gSessionKeystore默认会话密钥库。InitializeChip()依次调用chip::Platform::MemoryInit()初始化系统内存再调用chip::DeviceLayer::PlatformMgr().InitChipStack()初始化 CHIP 协议栈。ShutdownChip()按逆序关闭 MessageCounterManager、ExchangeManager、SessionManager 并PlatformMgr().Shutdown()。Echo 协议的本体EchoClient 与 EchoServer协议实体定义在 src/protocols/echo/Echo.h 中只用了两个消息类型Echo.h消息类型枚举值语义EchoRequest0x01请求方发送负载为任意数据EchoResponse0x02响应方原样回显负载EchoClient暴露三个关键 APIInit(ExchangeManager *, const SessionHandle )绑定 Exchange 管理器并持有安全会话句柄SendEchoRequest(PacketBufferHandle , SendFlags)核心发送逻辑见 EchoClient.cpp——先丢弃旧 ExchangeContext保证同一时刻与单个节点只有一个 Echo Exchange再NewContext创建新会话SetResponseTimeout(800ms)设置响应超时最后以SendMessageFlags::kExpectResponse标志发送EchoRequest消息SetEchoResponseReceived(callback)注册收到 EchoResponse 时的应用回调。响应超时由OnResponseTimeout处理会打印 Time out! failed to receive echo response... 日志见 EchoClient.cpp。EchoServer则通过OnUnsolicitedMessageReceived拦截对方主动发起的 EchoRequestOnMessageReceived中校验消息类型后回送 EchoResponse。四、运行示例在 IP 网络上Ping一台设备启动服务端按 README直接运行编译好的可执行文件即可让服务端进入 Echo 模式./chip-echo-responder [--tcp]服务端默认监听 UDP传入--tcp则改用 TCP 传输。程序启动后会打印Listening for Echo requests...见 echo_responder.cpp随后进入PlatformMgr().RunEventLoop()事件循环等待请求。收到 EchoRequest 时注册的回调会打印请求长度例如Echo Request, len14... sending response.值得一提的是源码还支持一个 README 未提及的--disable参数传入后服务端不初始化 EchoServerecho_responder.cpp可用来验证对端不响应时的客户端超时行为。启动客户端客户端需要传入服务端地址作为位置参数./chip-echo-requester Servers IP address [--tcp]按 README 的描述提供合法值后客户端会周期性地向指定服务端地址发送消息共发送三次。这一行为在源码中有明确对应kMaxEchoCount 3echo_requester.cpp、发送间隔gEchoInterval 1 秒echo_requester.cpp。客户端收到响应时HandleEchoResponseReceivedecho_requester.cpp会打印带统计信息的日志格式为Echo Response: 1/1(100.00%) len14 time0.xxx s依次为已收到响应数/已发送请求数百分比 负载长度 往返耗时。关于 IP 地址类型的一个重要说明需要特别提醒README 写作时描述为 Servers IPv4 address但当前仓库源码中的客户端对地址类型做了严格的 IPv6 校验——main()中调用IPAddress::FromString解析后若地址类型不是kIPv6会直接报错退出if (gDestAddr.Type() ! chip::Inet::IPAddressType::kIPv6) { printf(Echo Server IP address: %s is not of type IPv6\n, argv[1]); ExitNow(err CHIP_ERROR_INVALID_ARGUMENT); }见 echo_requester.cpp因此在当前版本下请使用服务端的 IPv6 地址如::1或链路本地地址运行客户端README 中的 IPv4 表述已相对过时。五、运行链路源码级解析客户端从参数解析到三次 Echo 的完整流程chip-echo-requester的main()echo_requester.cpp流程如下参数校验无参数时提示 Missing Echo Server IP address超过 3 个参数报 Too many arguments specified!第三个参数匹配--tcp时启用 TCP 传输。传输初始化TCP 模式下以TcpListenParameters(...).SetListenPort(ECHO_CLIENT_PORT)初始化 TCP 管理器UDP 模式对应UdpListenParameters注意客户端监听端口为ECHO_CLIENT_PORT CHIP_PORT 1echo_requester.cpp而 CHIP 默认端口CHIP_PORT定义为5540见 src/lib/core/CHIPConfig.h。栈初始化依次初始化SessionManager、ExchangeManager、MessageCounterManager顺序与 common.cpp 的 shutdown 顺序严格相反。建立安全会话EstablishSecureSession()通过gSessionManager.InjectPaseSessionWithTestKey(...)以测试密钥注入一个 PASE 安全会话节点 IDkTestDeviceNodeId、Fabric Index 0、角色kInitiator见 echo_requester.cpp。TCP 模式下会先走EstablishTCPConnection()HandleConnectionAttemptComplete()的建连回调链再建立会话并把会话与 TCP 连接关联。初始化 EchoClientgEchoClient.Init(gExchangeManager, gSession.Get().Value())并注册HandleEchoResponseReceived回调。定时驱动SystemLayer().StartTimer(kZero, EchoTimerHandler, ...)立即触发第一次发送。EchoTimerHandlerecho_requester.cpp的逻辑是若上次请求没等到响应先打印 No response received若gEchoCount kMaxEchoCount则继续发送否则停止事件循环。每次SendEchoRequest()会先构造Echo Message %llu\n格式的负载、记录发送时间戳gLastEchoTime、启动 1 秒定时器再调用gEchoClient.SendEchoRequest(...)echo_requester.cpp。响应到达后HandleEchoResponseReceived用gLastEchoTime计算往返时间并更新计数——这是 Echo 用于连通性/延迟测量的天然用途。退出清理关闭 UDP/TCP 管理器、Shutdown()取消定时器并gEchoClient.Shutdown()。服务端被动响应 测试会话注入chip-echo-responder的main()echo_responder.cpp与之对称初始化传输管理器时不指定监听端口即监听 CHIP 默认端口 5540初始化EchoServer后以kTestControllerNodeId、角色kResponder注入测试会话echo_responder.cpp然后进入事件循环。整个服务端是被动的收到 EchoRequest → 打印日志 → 由 EchoServer 自动回送 EchoResponse。六、对照实验把 Echo 示例当作协议应用模板对希望在 CHIP 栈上实现自己的协议应用的开发者这个示例给出了一个可直接套用的最小骨架README 中描述的三层结构可以一一对应到代码协议定义层在src/protocols/下仿照 Echo.h 定义MsgType枚举、客户端/服务端类并实现MessageTypeTraits特化传输与会话层复用 common.h 中的SessionManager/ExchangeManager/MessageCounterManager全局组件选择 UDP/TCP 传输应用入口层仿照echo_requester.cpp/echo_responder.cpp编写main()在事件循环PlatformMgr().RunEventLoop()中用定时器驱动发送、用回调处理接收。构建时只需仿照 BUILD.gn 声明source_set与executable目标并把依赖指向src/messaging、src/protocols、src/platform等现有 target 即可——整个示例从协议定义到构建产物构成了一条完整、可运行、可扩展的链路。七、常见问题与排查建议客户端报 Echo Server IP address: ... is not of type IPv6当前源码要求 IPv6 地址请使用 IPv6 形式如::1测试本机回环。客户端打印 No response received说明 1 秒内未收到响应常见原因是服务端未启动、端口5540/5541被防火墙拦截或测试会话未成功建立。TCP 模式下连接失败源码中 TCP 建连最多尝试kMaxTCPConnectAttempts 3次echo_requester.cpp超限会直接退出可先确认--tcp在请求方与响应方两侧同时启用。README 与源码不一致的地方除 IPv4/IPv6 差异外README 未提及服务端--disable参数与客户端详细的退出统计逻辑以上均已结合当前源码版本说明请以本仓库源码行为为准。【免费下载链接】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),仅供参考