Matter(connectedhomeip)Minimal mDNS 示例实战:构建 mDNS Server、Client 与 Advertiser

Matter(connectedhomeip)Minimal mDNS 示例实战:构建 mDNS Server、Client 与 Advertiser Matter(connectedhomeip)Minimal mDNS 示例实战:构建 mDNS Server、Client 与 Advertiser【免费下载链接】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本篇技术指南围绕 Matter SDK 中的 Minimal mDNS 示例(examples/minimal-mdns/)展开,讲解如何用 SDK 内置的 mDNS 实现启动一个可应答查询的双向 mDNS Server、一个可发送广播查询的 Client、一个按 Matter 规范广播服务记录(_matter/_matterc/_matterd)的 Advertiser,并结合src/lib/dnssd/源码说明服务命名规则、记录应答器(Responder)机制以及如何用dns-sd命令验证广告与发现流程,读完后可独立完成 Matter 发现协议栈的调试与验证。示例定位与构建配置Minimal mDNS 示例演示 Matter 中的组播 DNS(multicast DNS, mDNS)协议功能。它直接使用 SDK 自带的极简版mDNS 实现,而不是系统级的 Avahi 或 mDNSResponder 后端。这一选择由构建配置决定,见 args.gni:import(//build_overrides/chip.gni) import(${chip_root}/config/standalone/args.gni) chip_mdns minimalchip_mdns minimal指定使用src/lib/dnssd/minimal_mdns下的实现作为 mDNS 后端;同时导入config/standalone/args.gni的 standalone 平台参数。BUILD.gn 中定义了 5 个构建目标:目标类型源文件关键依赖minimal-mdns-example-commonstatic_libraryPacketReporter.cppsrc/lib、src/lib/dnssd/minimal_mdnsminimal-mdns-testerexecutabletester.cpp上述公共库 arg_parserminimal-mdns-clientexecutableclient.cpp上述公共库 arg_parserlogging:defaultminimal-mdns-serverexecutableserver.cpp额外依赖src/lib/dnssd/minimal_mdns/respondersmdns-advertiserexecutableadvertiser.cpp依赖src/lib/dnssd(含Advertiser.h)所有目标都加入了-Wconversion编译警告,产物输出到root_out_dir,即./out/minimal_mdns/目录。共享的 PacketReporter.h 实现chip::Dnssd::ParserDelegate接口,用于把收到的 mDNS 报文逐段(header/query/record)打印出来,是调试发现协议时最直观的工具。minimal-mdns-server:可应答查询的双向 Serverserver.cpp 实现了一个 mDNS Server,它可以监听 IPv4 与 IPv6 接口,应答 mDNS 查询,同时把收到的查询和网络上观察到的广告打印出来。运行方式与命令行参数./out/minimal_mdns/minimal-mdns-server -4不加参数时监听 IPv6,加-4后同时监听 IPv4,默认端口 5353。完整参数(来自源码中的OptionSet定义)如下:短选项长选项说明默认值-p number--listen-port number监听端口5353-4--enable-ip-v4同时启用 IPv4 监听关闭(仅 IPv6)-i name--instance-name name广告的实例名chip-mdns-demo-t dest--trace-to dest将 tracing 输出到指定目标无运行期间 Server 会打印出收到的所有查询(QUERY from: ...)以及网络上观察到的所有广告,并尝试对可应答的查询发出响应。服务端应答链路解析从源码结构看,Server 的核心流程是注册应答器 → 建连监听 → 委托分发:创建带容量的 Server 实例:mdns::Minimal::Server10 /* endpoints */ gMdnsServer;模板参数表示最多可监听 10 个端点,与接口数量相关。按 Matter 服务命名规则构造各条记录名。命名常量定义在 ServiceNaming.h 中:inline constexpr char kOperationalServiceName[] _matter; inline constexpr char kCommissionableServiceName[] _matterc; inline constexpr char kCommissionerServiceName[] _matterd; inline constexpr char kOperationalProtocol[] _tcp; inline constexpr char kCommissionProtocol[] _udp; inline constexpr char kLocalDomain[] local; inline constexpr char kSubtypeServiceNamePart[] _sub;Server 据此构造了 TCP 服务名(chip-mdns-demo._matter._tcp.local)、UDP 可配置服务名(chip-mdns-demo._matterc._udp.local),以及三个按 discriminator 细分的子类型查询名:S52._sub._matterc._udp.local、V123._sub._matterc._udp.local、L840._sub._matterc._udp.local。注册各类应答器(Responder)到QueryResponder中。每个应答器对应一种 DNS 记录类型,实现位于 responders 目录(IP.h、Ptr.h、Srv.h、Txt.h、QueryResponder.h):mdns::Minimal::QueryResponder16 /* maxRecords */ queryResponder; // ... queryResponder.AddResponder(ptrTcpResponder) .SetReportInServiceListing(true) .SetReportAdditional(tcpServerServiceName); // ... queryResponder.AddResponder(tcpSrvResponder).SetReportAdditional(serverName);其中:PtrResponder把服务类型名映射到实例名,SetReportInServiceListing(true)表示该 PTR 记录参与_services._dns-sd._udp.local这类服务列举查询;SrvResponder应答 SRV 记录,SetReportAdditional(serverName)表示应答时附带主机名的 A/AAAA 附加记录;TxtResponder应答 TXT 记录,示例中注册了如下字段:const char * txtEntries[] { D0840yes, VP123456, PH3, OTHSome text here..., };VP(vendor id product id)、PH(pairing hint)等字段与 Matter 规范的发现 TXT 字段一致;IPv4Responder/IPv6Responder分别应答主机 A/AAAA 记录,IPv4 应答器仅在传入-4时注册。把ResponseSender挂到 Server 上,并通过委托ReplyDelegate(同时实现mdns::Minimal::ServerDelegate与chip::Dnssd::ParserDelegate)处理收发:收到查询后先打印来源地址/端口/接口,再用chip::Dnssd::ParseMdnsPacket解析,把消息 ID 和查询项交给ResponseSender::Respond生成应答。监听端点取自全局地址策略:(void) chip::Dnssd::GlobalMinimalMdnsServer::Instance(); // 触发内置策略加载 auto endpoints mdns::Minimal::GetAddressPolicy()-GetListenEndpoints(); gMdnsServer.Listen(DeviceLayer::UDPEndPointManager(), endpoints.get(), gOptions.listenPort);AddressPolicy(见 AddressPolicy.h)决定在多网卡环境下选择哪些地址参与 mDNS 监听,默认实现位于 AddressPolicy_DefaultImpl.cpp。minimal-mdns-client:广播查询与应答解析client.cpp 演示 mDNS 客户端。默认查询_services._dns-sd._udp.local(DNS-SD 服务列举),并请求单播(unicast)应答。示例运行:./out/minimal_mdns/minimal-mdns-client该查询通常会列出本地网络上大量服务。也可以自定义查询:./out/minimal_mdns/minimal-mdns-client -q chip-mdns-demo._matter._tcp.local完整参数(源码中的Options结构默认值与OptionSet定义):长选项短选项说明默认值--listen-port number—接收应答的监听端口5388--query name-q name要发送的查询名_services._dns-sd._udp.local--type TYPE-t TYPE查询类型(ANY/PTR/A/AAAA/SRV/TXT/CNAME)ANY--query-port number—查询广播的目标端口5353--timeout-ms number—等待应答的时长500--multicast-reply—不请求单播应答(允许组播应答)请求单播应答--trace-to dest—tracing 输出目标无发送查询的实现细节客户端把查询字符串按.切分成 QName 各段(见QuerySplitter类),用 QueryBuilder.h 组包:builder.Header().SetMessageId(kTestMessageId); builder.AddQuery(query.MdnsQuery() .SetClass(chip::Dnssd::QClass::IN) .SetType(gOptions.type) .SetAnswerViaUnicast(gOptions.unicastAnswers));SetAnswerViaUnicast(true)会把查询类的 CD 位置(bit 15)置位,即 mDNS 的仅单播应答标志;随后通过server-BroadcastUnicastQuery(packet, port)向 mDNS 组播组广播。若未收到预期应答,可加--multicast-reply让应答方以组播回复。客户端在--timeout-ms到期后自动关闭 socket 并退出事件循环;收到的每条 QUERY/RESPONSE 都会经PacketReporter打印完整解析结果。mdns-advertiser:按 Matter 规范广播服务记录advertiser.cpp 使用 SDK 内置的 Service Advertiser(核心接口见 Advertiser.h,minimal 后端实现于 Advertiser_ImplMinimalMdns.cpp)。README 给出的三个典型运行:# 已配置设备(operational)模式 ./out/minimal_mdns/mdns-advertiser -4 -m operational # 可配置设备(commissionable node)模式 ./out/minimal_mdns/mdns-advertiser -4 -m commissionable-node --vendor-id 123 --product-id 456 # 配置器(commissioner)模式 ./out/minimal_mdns/mdns-advertiser -4 -m commissioner --vendor-id 123 --product-id 456 --device-type 35广告模式与参数源码中AdvertisingMode枚举定义了 4 种模式,均通过-m / --advertising-mode选择:模式值广播内容主要 TXT 字段commissionable-node(默认)_matterc._udp服务D(长 discriminator)、VP、PH、M(配置模式)等operational_matter._tcp服务(实例名由 Fabric ID Node ID 生成)无operational-multi-admin连续三个 Fabric 的 operational 记录(端口依次 1/2)无commissioner_matterd._udp服务D、VP、DT(device type)完整命令行参数:长选项短选项说明默认值--enable-ip-v4-4启用 IPv4 监听(编译时受INET_CONFIG_ENABLE_IPV4控制)关闭--advertising-mode mode-m mode广告模式commissionable-node--short-discriminator value-s短 discriminator52--long-discriminator value-l长 discriminator840--vendor-id value—vendor id未设置--product-id value-pproduct id未设置--commissioning-mode value—配置模式:0disabled,1basic,2enhanceddisabled--device-type value—设备类型 id未设置--device-name value—设备名未设置--rotating-id value—轮换设备 id未设置--pairing-instruction value—配对说明未设置--pairing-hint value—配对提示未设置--fabric-id value-foperational Fabric ID(十六进制)12345--node-id value-noperational Node ID(十六进制)6789--trace-to dest-ttracing 输出目标无实现上,所有模式最终都调用ServiceAdvertiser::Instance().Advertise(...),参数对象分别为CommissionAdvertisingParameters与OperationalAdvertisingParameters(链式设置端口、MAC、discriminator、vendor/product id 等)。operational 模式的实例名由PeerId(Fabric ID Node ID)生成,对应 ServiceNaming.h 中的MakeInstanceName;operational-multi-admin模式会连续发起三次 Advertise,分别使用fabricId/NodeID、1、2组合与CHIP_PORT1/2端口,用于验证多 Fabric 设备的服务广告。用 dns-sd 验证广告与发现在有 macOS(或可通过 opkg 安装dns-sd)的环境中,可以用它模拟 Matter 设备并与示例程序互相验证。模拟未配置节点(uncommissioned node)dns-sd -R DD200C20D25AE5F7 _matterc._udp,S52,L840,V123 . 11111 D840 VP123456会创建如下记录:_matterc._udp.local. PTR DD200C20D25AE5F7._matterc._udp.local. S52._sub._matterc._udp.local. PTR DD200C20D25AE5F7._matterc._udp.local. L840._sub._matterc._udp.local. PTR DD200C20D25AE5F7._matterc._udp.local. V123._sub._matterc._udp.local. PTR DD200C20D25AE5F7._matterc._udp.local. DD200C20D25AE5F7._matterc._udp.local. TXT D840 VP123456 DD200C20D25AE5F7._matterc._udp.local. SRV 0 0 11111 B75AFB458ECD.local. B75AFB458ECD.local. AAAA ba2a:b311:742e:b44c:f515:576f:9783:3f30模拟配置器(commissioning node)dns-sd -R DD200C20D25AE5F7 _matterd._udp,S52,L840,V123 . 11111 D840 VP123456 PH3会创建如下记录:_matterd._udp.local. PTR DD200C20D25AE5F7._matterd._udp.local. S52._sub._matterd._udp.local. PTR DD200C20D25AE5F7._matterd._udp.local. V123._sub._matterd._udp.local. PTR DD200C20D25AE5F7._matterd._udp.local. D840._sub._matterd._udp.local. PTR DD200C20D25AE5F7._matterd._udp.local. DD200C20D25AE5F7._matterd._udp.local. TXT D840 VP123456 PH3 DD200C20D25AE5F7._matterd._udp.local. SRV 0 0 11111 B75AFB458ECD.local. B75AFB458ECD.local. AAAA ba2a:b311:742e:b44c:f515:576f:9783:3f30模拟已配置节点dns-sd -R 2906C908D115D362-8FC7772401CD0696 _matter._tcp . 22222发现命令按节点类型浏览:dns-sd -B _matterc._udp # 待配置节点 dns-sd -B _matterc._udp,S52 # 短 discriminator 为 52 的待配置节点 dns-sd -B _matterc._udp,L840 # 长 discriminator 为 840 的待配置节点 dns-sd -B _matterc._udp,V123 # vendor id 为 123 的待配置节点 dns-sd -B _matterd._udp # 配置器(commissionable nodes) dns-sd -B _matterd._udp,S52 # 短 discriminator 为 52 的配置器 dns-sd -B _matterd._udp,L840 # 长 discriminator 为 840 的配置器 dns-sd -B _matterd._udp,V123 # vendor id 为 123 的配置器解析地址:dns-sd -L 2906C908D115D362-8FC7772401CD0696 _matter._tcp # 查找服务器地址 dns-sd -Gv6 B75AFB458ECD.local # 获取 IPv6 地址注意子类型查询名中S短discriminator、L长discriminator、Vvendor id的构造方式,与 server 中udpDiscriminator1/2/3三个 QName 完全对应,因此dns-sd -R手工广告可以被minimal-mdns-server应答,反之示例程序广播的记录也能被dns-sd -B发现。测试与质量保障该示例背后的 minimal mDNS 实现配有完整的单元与模糊测试,可作为行为验证的依据:应答器测试:TestPtrResponder.cpp、TestIPResponder.cpp、TestQueryResponder.cpp;Server/发送链路测试:TestResponseSender.cpp、TestQueryReplyFilter.cpp;报文解析模糊测试:如fuzz-minmdns-packet-parsing等目标(在 testing/fuzz_testing.md 中有引用),覆盖恶意构造的 mDNS 报文。此外,minimal-mdns-tester(由 tester.cpp 构建)是一个 SRV 应答的专项测试程序,默认监听 5353、运行 500ms 后自动退出,可作为 server 应答链路的独立回归工具。小结Minimal mDNS 示例以最小的代码量串起了 Matter 发现协议的三个关键环节:Server 演示了从AddressPolicy选端点、QueryResponder注册记录应答器到ResponseSender生成应答的完整应答链路;Client 演示了带仅单播应答标志的 DNS-SD 列举查询;Advertiser 则通过ServiceAdvertiser按 Matter 规范广播_matter/_matterc/_matterd三类服务及其 TXT 字段。配合dns-sd命令,可以在不依赖完整 Matter 设备的情况下,对服务命名规则(ServiceNaming.h 中的常量)、子类型过滤器(S/L/V PTR 记录)和 TXT 字段格式进行逐条验证。【免费下载链接】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),仅供参考