From 121890459ecc389ead2a16e4bcd38fbbad6e919b Mon Sep 17 00:00:00 2001 From: chrisdecenzo <61757564+chrisdecenzo@users.noreply.github.com> Date: Wed, 30 Jun 2021 21:27:21 -0700 Subject: [PATCH] Implement User Directed Commissioning - Phase 1 (#8034) --- examples/minimal-mdns/server.cpp | 33 ++++++----- src/app/server/Mdns.cpp | 7 +++ src/app/server/Mdns.h | 3 + .../ChipDeviceController-ScriptBinding.cpp | 2 +- src/lib/mdns/Advertiser.h | 55 ++++++++++++++----- src/lib/mdns/Advertiser_ImplMinimalMdns.cpp | 48 +++++++++++----- src/lib/mdns/Advertiser_ImplNone.cpp | 6 ++ src/lib/mdns/Discovery_ImplPlatform.cpp | 19 ++++++- src/lib/mdns/Discovery_ImplPlatform.h | 3 + src/lib/mdns/Resolver.h | 13 ++++- src/lib/mdns/Resolver_ImplMinimalMdns.cpp | 25 ++++++++- src/lib/mdns/ServiceNaming.cpp | 3 + src/lib/mdns/ServiceNaming.h | 2 +- src/lib/mdns/tests/TestServiceNaming.cpp | 8 ++- 14 files changed, 172 insertions(+), 55 deletions(-) diff --git a/examples/minimal-mdns/server.cpp b/examples/minimal-mdns/server.cpp index 53e6ebfff5950c..73c4848e3dad75 100644 --- a/examples/minimal-mdns/server.cpp +++ b/examples/minimal-mdns/server.cpp @@ -188,22 +188,27 @@ int main(int argc, char ** args) mdns::Minimal::Server<10 /* endpoints */> mdnsServer; mdns::Minimal::QueryResponder<16 /* maxRecords */> queryResponder; - mdns::Minimal::QNamePart tcpServiceName[] = { kOperationalServiceName, kOperationalProtocol, kLocalDomain }; - mdns::Minimal::QNamePart tcpServerServiceName[] = { gOptions.instanceName, kOperationalServiceName, kOperationalProtocol, - kLocalDomain }; - mdns::Minimal::QNamePart udpServiceName[] = { kCommissionableServiceName, kCommissionProtocol, kLocalDomain }; - mdns::Minimal::QNamePart udpServerServiceName[] = { gOptions.instanceName, kCommissionableServiceName, kCommissionProtocol, - kLocalDomain }; + mdns::Minimal::QNamePart tcpServiceName[] = { chip::Mdns::kOperationalServiceName, chip::Mdns::kOperationalProtocol, + chip::Mdns::kLocalDomain }; + mdns::Minimal::QNamePart tcpServerServiceName[] = { gOptions.instanceName, chip::Mdns::kOperationalServiceName, + chip::Mdns::kOperationalProtocol, chip::Mdns::kLocalDomain }; + mdns::Minimal::QNamePart udpServiceName[] = { chip::Mdns::kCommissionableServiceName, chip::Mdns::kCommissionProtocol, + chip::Mdns::kLocalDomain }; + mdns::Minimal::QNamePart udpServerServiceName[] = { gOptions.instanceName, chip::Mdns::kCommissionableServiceName, + chip::Mdns::kCommissionProtocol, chip::Mdns::kLocalDomain }; // several UDP versions for discriminators - mdns::Minimal::QNamePart udpDiscriminator1[] = { "S52", kSubtypeServiceNamePart, kCommissionableServiceName, - kCommissionProtocol, kLocalDomain }; - mdns::Minimal::QNamePart udpDiscriminator2[] = { "V123", kSubtypeServiceNamePart, kCommissionableServiceName, - kCommissionProtocol, kLocalDomain }; - mdns::Minimal::QNamePart udpDiscriminator3[] = { "L840", kSubtypeServiceNamePart, kCommissionableServiceName, - kCommissionProtocol, kLocalDomain }; - - mdns::Minimal::QNamePart serverName[] = { gOptions.instanceName, kLocalDomain }; + mdns::Minimal::QNamePart udpDiscriminator1[] = { "S52", chip::Mdns::kSubtypeServiceNamePart, + chip::Mdns::kCommissionableServiceName, chip::Mdns::kCommissionProtocol, + chip::Mdns::kLocalDomain }; + mdns::Minimal::QNamePart udpDiscriminator2[] = { "V123", chip::Mdns::kSubtypeServiceNamePart, + chip::Mdns::kCommissionableServiceName, chip::Mdns::kCommissionProtocol, + chip::Mdns::kLocalDomain }; + mdns::Minimal::QNamePart udpDiscriminator3[] = { "L840", chip::Mdns::kSubtypeServiceNamePart, + chip::Mdns::kCommissionableServiceName, chip::Mdns::kCommissionProtocol, + chip::Mdns::kLocalDomain }; + + mdns::Minimal::QNamePart serverName[] = { gOptions.instanceName, chip::Mdns::kLocalDomain }; mdns::Minimal::IPv4Responder ipv4Responder(serverName); mdns::Minimal::IPv6Responder ipv6Responder(serverName); diff --git a/src/app/server/Mdns.cpp b/src/app/server/Mdns.cpp index 208aa5e34ea453..cba43450896688 100644 --- a/src/app/server/Mdns.cpp +++ b/src/app/server/Mdns.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #if CONFIG_DEVICE_LAYER #include @@ -87,6 +88,12 @@ chip::ByteSpan FillMAC(uint8_t (&mac)[8]) } // namespace +CHIP_ERROR GetCommissionableInstanceName(char * buffer, size_t bufferLen) +{ + auto & mdnsAdvertiser = chip::Mdns::ServiceAdvertiser::Instance(); + return mdnsAdvertiser.GetCommissionableInstanceName(buffer, bufferLen); +} + /// Set MDNS operational advertisement CHIP_ERROR AdvertiseOperational() { diff --git a/src/app/server/Mdns.h b/src/app/server/Mdns.h index 7c13968fe8de50..4e071428286e3c 100644 --- a/src/app/server/Mdns.h +++ b/src/app/server/Mdns.h @@ -42,6 +42,9 @@ void StartServer(); CHIP_ERROR GenerateRotatingDeviceId(char rotatingDeviceIdHexBuffer[], size_t rotatingDeviceIdHexBufferSize); +/// Generates the (random) instance name that a CHIP device is to use for pre-commissioning DNS-SD +CHIP_ERROR GetCommissionableInstanceName(char * buffer, size_t bufferLen); + } // namespace Mdns } // namespace app } // namespace chip diff --git a/src/controller/python/ChipDeviceController-ScriptBinding.cpp b/src/controller/python/ChipDeviceController-ScriptBinding.cpp index dbb6699e4cb287..afd53121b54336 100644 --- a/src/controller/python/ChipDeviceController-ScriptBinding.cpp +++ b/src/controller/python/ChipDeviceController-ScriptBinding.cpp @@ -252,7 +252,7 @@ CHIP_ERROR pychip_DeviceController_ConnectIP(chip::Controller::DeviceCommissione CHIP_ERROR pychip_DeviceController_DiscoverAllCommissionableNodes(chip::Controller::DeviceCommissioner * devCtrl) { - Mdns::DiscoveryFilter filter(Mdns::DiscoveryFilterType::kNone, 0); + Mdns::DiscoveryFilter filter(Mdns::DiscoveryFilterType::kNone, (uint16_t) 0); return devCtrl->DiscoverCommissionableNodes(filter); } diff --git a/src/lib/mdns/Advertiser.h b/src/lib/mdns/Advertiser.h index 6752df04200b90..89380ac42d4f41 100644 --- a/src/lib/mdns/Advertiser.h +++ b/src/lib/mdns/Advertiser.h @@ -25,6 +25,7 @@ #include #include #include +#include namespace chip { namespace Mdns { @@ -179,34 +180,55 @@ class CommissionAdvertisingParameters : public BaseAdvertisingParams::Value(static_cast(sDeviceName)); + chip::Platform::CopyString(mDeviceName, sizeof(mDeviceName), deviceName.Value()); + mDeviceNameHasValue = true; + } + else + { + mDeviceNameHasValue = false; } return *this; } - Optional GetDeviceName() const { return mDeviceName; } + Optional GetDeviceName() const + { + return mDeviceNameHasValue ? Optional::Value(mDeviceName) : Optional::Missing(); + } CommissionAdvertisingParameters & SetRotatingId(Optional rotatingId) { if (rotatingId.HasValue()) { - strncpy(sRotatingId, rotatingId.Value(), min(strlen(rotatingId.Value()) + 1, sizeof(sRotatingId))); - mRotatingId = Optional::Value(static_cast(sRotatingId)); + chip::Platform::CopyString(mRotatingId, sizeof(mRotatingId), rotatingId.Value()); + mRotatingIdHasValue = true; + } + else + { + mRotatingIdHasValue = false; } return *this; } - Optional GetRotatingId() const { return mRotatingId; } + Optional GetRotatingId() const + { + return mRotatingIdHasValue ? Optional::Value(mRotatingId) : Optional::Missing(); + } CommissionAdvertisingParameters & SetPairingInstr(Optional pairingInstr) { if (pairingInstr.HasValue()) { - strncpy(sPairingInstr, pairingInstr.Value(), min(strlen(pairingInstr.Value()) + 1, sizeof(sPairingInstr))); - mPairingInstr = Optional::Value(static_cast(sPairingInstr)); + chip::Platform::CopyString(mPairingInstr, sizeof(mPairingInstr), pairingInstr.Value()); + mPairingInstrHasValue = true; + } + else + { + mPairingInstrHasValue = false; } return *this; } - Optional GetPairingInstr() const { return mPairingInstr; } + Optional GetPairingInstr() const + { + return mPairingInstrHasValue ? Optional::Value(mPairingInstr) : Optional::Missing(); + } CommissionAdvertisingParameters & SetPairingHint(Optional pairingHint) { @@ -233,14 +255,14 @@ class CommissionAdvertisingParameters : public BaseAdvertisingParams mDeviceType; chip::Optional mPairingHint; - char sDeviceName[kKeyDeviceNameMaxLength + 1]; - chip::Optional mDeviceName; + char mDeviceName[kKeyDeviceNameMaxLength + 1]; + bool mDeviceNameHasValue = false; - char sRotatingId[kKeyRotatingIdMaxLength + 1]; - chip::Optional mRotatingId; + char mRotatingId[kKeyRotatingIdMaxLength + 1]; + bool mRotatingIdHasValue = false; - char sPairingInstr[kKeyPairingInstructionMaxLength + 1]; - chip::Optional mPairingInstr; + char mPairingInstr[kKeyPairingInstructionMaxLength + 1]; + bool mPairingInstrHasValue = false; }; /// Handles advertising of CHIP nodes @@ -264,6 +286,9 @@ class ServiceAdvertiser /// Provides the system-wide implementation of the service advertiser static ServiceAdvertiser & Instance(); + + /// Returns DNS-SD instance name formatted as hex string + virtual CHIP_ERROR GetCommissionableInstanceName(char * instanceName, size_t maxLength) = 0; }; } // namespace Mdns diff --git a/src/lib/mdns/Advertiser_ImplMinimalMdns.cpp b/src/lib/mdns/Advertiser_ImplMinimalMdns.cpp index 39911ede6fdd39..998d059d6fbe12 100644 --- a/src/lib/mdns/Advertiser_ImplMinimalMdns.cpp +++ b/src/lib/mdns/Advertiser_ImplMinimalMdns.cpp @@ -116,6 +116,7 @@ class AdvertiserMinMdns : public ServiceAdvertiser, CHIP_ERROR Advertise(const OperationalAdvertisingParameters & params) override; CHIP_ERROR Advertise(const CommissionAdvertisingParameters & params) override; CHIP_ERROR StopPublishDevice() override; + CHIP_ERROR GetCommissionableInstanceName(char * instanceName, size_t maxLength) override; // MdnsPacketDelegate void OnMdnsPacketData(const BytesRange & data, const chip::Inet::IPPacketInfo * info) override; @@ -146,6 +147,8 @@ class AdvertiserMinMdns : public ServiceAdvertiser, QueryResponderAllocator mQueryResponderAllocatorCommissioner; ResponseSender mResponseSender; + uint32_t mCommissionInstanceName1; + uint32_t mCommissionInstanceName2; // current request handling const chip::Inet::IPPacketInfo * mCurrentSource = nullptr; @@ -191,6 +194,9 @@ CHIP_ERROR AdvertiserMinMdns::Start(chip::Inet::InetLayer * inetLayer, uint16_t { GlobalMinimalMdnsServer::Server().Shutdown(); + mCommissionInstanceName1 = GetRandU32(); + mCommissionInstanceName2 = GetRandU32(); + ReturnErrorOnFailure(GlobalMinimalMdnsServer::Instance().StartServer(inetLayer, port)); ChipLogProgress(Discovery, "CHIP minimal mDNS started advertising."); @@ -277,8 +283,23 @@ CHIP_ERROR AdvertiserMinMdns::Advertise(const OperationalAdvertisingParameters & return CHIP_NO_ERROR; } +CHIP_ERROR AdvertiserMinMdns::GetCommissionableInstanceName(char * instanceName, size_t maxLength) +{ + if (maxLength < (kMaxInstanceNameSize + 1)) + { + return CHIP_ERROR_NO_MEMORY; + } + size_t len = snprintf(instanceName, maxLength, ChipLogFormatX64, mCommissionInstanceName1, mCommissionInstanceName2); + if (len >= maxLength) + { + return CHIP_ERROR_NO_MEMORY; + } + return CHIP_NO_ERROR; +} + CHIP_ERROR AdvertiserMinMdns::Advertise(const CommissionAdvertisingParameters & params) { + // TODO: When multi-admin is enabled, operational does not need to be cleared here. if (params.GetCommissionAdvertiseMode() == CommssionAdvertiseMode::kCommissionableNode) { @@ -291,11 +312,8 @@ CHIP_ERROR AdvertiserMinMdns::Advertise(const CommissionAdvertisingParameters & // TODO: need to detect colisions here char nameBuffer[64] = ""; - size_t len = snprintf(nameBuffer, sizeof(nameBuffer), ChipLogFormatX64, GetRandU32(), GetRandU32()); - if (len >= sizeof(nameBuffer)) - { - return CHIP_ERROR_NO_MEMORY; - } + ReturnErrorOnFailure(GetCommissionableInstanceName(nameBuffer, sizeof(nameBuffer))); + QueryResponderAllocator * allocator = params.GetCommissionAdvertiseMode() == CommssionAdvertiseMode::kCommissionableNode ? &mQueryResponderAllocatorCommissionable : &mQueryResponderAllocatorCommissioner; @@ -486,26 +504,26 @@ FullQName AdvertiserMinMdns::GetCommisioningTextEntries(const CommissionAdvertis char txtVidPid[chip::Mdns::kKeyVendorProductMaxLength + 4]; if (params.GetProductId().HasValue() && params.GetVendorId().HasValue()) { - sprintf(txtVidPid, "VP=%d+%d", params.GetVendorId().Value(), params.GetProductId().Value()); + snprintf(txtVidPid, sizeof(txtVidPid), "VP=%d+%d", params.GetVendorId().Value(), params.GetProductId().Value()); txtFields[numTxtFields++] = txtVidPid; } else if (params.GetVendorId().HasValue()) { - sprintf(txtVidPid, "VP=%d", params.GetVendorId().Value()); + snprintf(txtVidPid, sizeof(txtVidPid), "VP=%d", params.GetVendorId().Value()); txtFields[numTxtFields++] = txtVidPid; } char txtDeviceType[chip::Mdns::kKeyDeviceTypeMaxLength + 4]; if (params.GetDeviceType().HasValue()) { - sprintf(txtDeviceType, "DT=%d", params.GetDeviceType().Value()); + snprintf(txtDeviceType, sizeof(txtDeviceType), "DT=%d", params.GetDeviceType().Value()); txtFields[numTxtFields++] = txtDeviceType; } char txtDeviceName[chip::Mdns::kKeyDeviceNameMaxLength + 4]; if (params.GetDeviceName().HasValue()) { - sprintf(txtDeviceName, "DN=%s", params.GetDeviceName().Value()); + snprintf(txtDeviceName, sizeof(txtDeviceName), "DN=%s", params.GetDeviceName().Value()); txtFields[numTxtFields++] = txtDeviceName; } @@ -514,7 +532,7 @@ FullQName AdvertiserMinMdns::GetCommisioningTextEntries(const CommissionAdvertis { // a discriminator always exists char txtDiscriminator[chip::Mdns::kKeyDiscriminatorMaxLength + 3]; - sprintf(txtDiscriminator, "D=%d", params.GetLongDiscriminator()); + snprintf(txtDiscriminator, sizeof(txtDiscriminator), "D=%d", params.GetLongDiscriminator()); txtFields[numTxtFields++] = txtDiscriminator; if (!params.GetVendorId().HasValue()) @@ -523,34 +541,34 @@ FullQName AdvertiserMinMdns::GetCommisioningTextEntries(const CommissionAdvertis } char txtCommissioningMode[chip::Mdns::kKeyCommissioningModeMaxLength + 4]; - sprintf(txtCommissioningMode, "CM=%d", params.GetCommissioningMode() ? 1 : 0); + snprintf(txtCommissioningMode, sizeof(txtCommissioningMode), "CM=%d", params.GetCommissioningMode() ? 1 : 0); txtFields[numTxtFields++] = txtCommissioningMode; char txtOpenWindowCommissioningMode[chip::Mdns::kKeyAdditionalPairingMaxLength + 4]; if (params.GetCommissioningMode() && params.GetOpenWindowCommissioningMode()) { - sprintf(txtOpenWindowCommissioningMode, "AP=1"); + snprintf(txtOpenWindowCommissioningMode, sizeof(txtOpenWindowCommissioningMode), "AP=1"); txtFields[numTxtFields++] = txtOpenWindowCommissioningMode; } char txtRotatingDeviceId[chip::Mdns::kKeyRotatingIdMaxLength + 4]; if (params.GetRotatingId().HasValue()) { - sprintf(txtRotatingDeviceId, "RI=%s", params.GetRotatingId().Value()); + snprintf(txtRotatingDeviceId, sizeof(txtRotatingDeviceId), "RI=%s", params.GetRotatingId().Value()); txtFields[numTxtFields++] = txtRotatingDeviceId; } char txtPairingHint[chip::Mdns::kKeyPairingInstructionMaxLength + 4]; if (params.GetPairingHint().HasValue()) { - sprintf(txtPairingHint, "PH=%d", params.GetPairingHint().Value()); + snprintf(txtPairingHint, sizeof(txtPairingHint), "PH=%d", params.GetPairingHint().Value()); txtFields[numTxtFields++] = txtPairingHint; } char txtPairingInstr[chip::Mdns::kKeyPairingInstructionMaxLength + 4]; if (params.GetPairingInstr().HasValue()) { - sprintf(txtPairingInstr, "PI=%s", params.GetPairingInstr().Value()); + snprintf(txtPairingInstr, sizeof(txtPairingInstr), "PI=%s", params.GetPairingInstr().Value()); txtFields[numTxtFields++] = txtPairingInstr; } } diff --git a/src/lib/mdns/Advertiser_ImplNone.cpp b/src/lib/mdns/Advertiser_ImplNone.cpp index 889388abdb0d3a..208fbcf4f2df7d 100644 --- a/src/lib/mdns/Advertiser_ImplNone.cpp +++ b/src/lib/mdns/Advertiser_ImplNone.cpp @@ -50,6 +50,12 @@ class NoneAdvertiser : public ServiceAdvertiser ChipLogError(Discovery, "mDNS advertising not available. mDNS stop not available."); return CHIP_ERROR_NOT_IMPLEMENTED; } + + CHIP_ERROR GetCommissionableInstanceName(char * instanceName, size_t maxLength) override + { + ChipLogError(Discovery, "mDNS advertising not available. mDNS GetCommissionableInstanceName not available."); + return CHIP_ERROR_NOT_IMPLEMENTED; + } }; NoneAdvertiser gAdvertiser; diff --git a/src/lib/mdns/Discovery_ImplPlatform.cpp b/src/lib/mdns/Discovery_ImplPlatform.cpp index dbdbdf4c3796c8..5ea0345fad056f 100644 --- a/src/lib/mdns/Discovery_ImplPlatform.cpp +++ b/src/lib/mdns/Discovery_ImplPlatform.cpp @@ -103,6 +103,21 @@ void DiscoveryImplPlatform::HandleMdnsError(void * context, CHIP_ERROR error) } } +CHIP_ERROR DiscoveryImplPlatform::GetCommissionableInstanceName(char * instanceName, size_t maxLength) +{ + if (maxLength < (chip::Mdns::kMaxInstanceNameSize + 1)) + { + return CHIP_ERROR_NO_MEMORY; + } + size_t len = snprintf(instanceName, maxLength, "%08" PRIX32 "%08" PRIX32, static_cast(mCommissionInstanceName >> 32), + static_cast(mCommissionInstanceName)); + if (len >= maxLength) + { + return CHIP_ERROR_NO_MEMORY; + } + return CHIP_NO_ERROR; +} + CHIP_ERROR DiscoveryImplPlatform::Advertise(const CommissionAdvertisingParameters & params) { CHIP_ERROR error = CHIP_NO_ERROR; @@ -143,8 +158,8 @@ CHIP_ERROR DiscoveryImplPlatform::Advertise(const CommissionAdvertisingParameter return error; } - snprintf(service.mName, sizeof(service.mName), "%08" PRIX32 "%08" PRIX32, static_cast(mCommissionInstanceName >> 32), - static_cast(mCommissionInstanceName)); + ReturnErrorOnFailure(GetCommissionableInstanceName(service.mName, sizeof(service.mName))); + if (params.GetCommissionAdvertiseMode() == CommssionAdvertiseMode::kCommissionableNode) { strncpy(service.mType, kCommissionableServiceName, sizeof(service.mType)); diff --git a/src/lib/mdns/Discovery_ImplPlatform.h b/src/lib/mdns/Discovery_ImplPlatform.h index a9fb603a4921ce..9115dc4c72f904 100644 --- a/src/lib/mdns/Discovery_ImplPlatform.h +++ b/src/lib/mdns/Discovery_ImplPlatform.h @@ -48,6 +48,9 @@ class DiscoveryImplPlatform : public ServiceAdvertiser, public Resolver /// This function stops publishing the device on mDNS. CHIP_ERROR StopPublishDevice() override; + /// Returns DNS-SD instance name formatted as hex string + CHIP_ERROR GetCommissionableInstanceName(char * instanceName, size_t maxLength) override; + /// Registers a resolver delegate if none has been registered before CHIP_ERROR SetResolverDelegate(ResolverDelegate * delegate) override; diff --git a/src/lib/mdns/Resolver.h b/src/lib/mdns/Resolver.h index 3e71ba8beb7feb..fcefadb1b1b24b 100644 --- a/src/lib/mdns/Resolver.h +++ b/src/lib/mdns/Resolver.h @@ -52,13 +52,16 @@ struct ResolvedNodeData constexpr size_t kMaxDeviceNameLen = 32; constexpr size_t kMaxRotatingIdLen = 50; constexpr size_t kMaxPairingInstructionLen = 128; + +// Largest host name is 64-bits in hex. +static constexpr int kMaxHostNameSize = 16; +static constexpr int kMaxInstanceNameSize = 16; struct DiscoveredNodeData { // TODO(cecille): is 4 OK? IPv6 LL, GUA, ULA, IPv4? static constexpr int kMaxIPAddresses = 5; - // Largest host name is 64-bits in hex. - static constexpr int kHostNameSize = 16; - char hostName[kHostNameSize + 1]; + char hostName[kMaxHostNameSize + 1]; + char instanceName[kMaxInstanceNameSize + 1]; uint16_t longDiscriminator; uint16_t vendorId; uint16_t productId; @@ -76,6 +79,7 @@ struct DiscoveredNodeData void Reset() { memset(hostName, 0, sizeof(hostName)); + memset(instanceName, 0, sizeof(instanceName)); longDiscriminator = 0; vendorId = 0; productId = 0; @@ -107,14 +111,17 @@ enum class DiscoveryFilterType : uint8_t kDeviceType, kCommissioningMode, kCommissioningModeFromCommand, + kInstanceName, kCommissioner }; struct DiscoveryFilter { DiscoveryFilterType type; uint16_t code; + char * instanceName; DiscoveryFilter() : type(DiscoveryFilterType::kNone), code(0) {} DiscoveryFilter(DiscoveryFilterType newType, uint16_t newCode) : type(newType), code(newCode) {} + DiscoveryFilter(DiscoveryFilterType newType, char * newInstanceName) : type(newType), instanceName(newInstanceName) {} }; enum class DiscoveryType { diff --git a/src/lib/mdns/Resolver_ImplMinimalMdns.cpp b/src/lib/mdns/Resolver_ImplMinimalMdns.cpp index a3d39f80d3ce02..8d3078c4737e15 100644 --- a/src/lib/mdns/Resolver_ImplMinimalMdns.cpp +++ b/src/lib/mdns/Resolver_ImplMinimalMdns.cpp @@ -153,11 +153,14 @@ void PacketDataReporter::OnCommissionableNodeSrvRecord(SerializedQNameIterator n { // Host name is the first part of the qname mdns::Minimal::SerializedQNameIterator it = srv.GetName(); - if (!it.Next()) + if (it.Next()) { - return; + strncpy(mDiscoveredNodeData.hostName, it.Value(), sizeof(DiscoveredNodeData::hostName)); + } + if (name.Next()) + { + strncpy(mDiscoveredNodeData.instanceName, name.Value(), sizeof(DiscoveredNodeData::instanceName)); } - strncpy(mDiscoveredNodeData.hostName, it.Value(), sizeof(DiscoveredNodeData::hostName)); } void PacketDataReporter::OnOperationalIPAddress(const chip::Inet::IPAddress & addr) @@ -239,6 +242,18 @@ void PacketDataReporter::OnResource(ResourceType type, const ResourceData & data } break; } + case QType::PTR: { + if (mDiscoveryType == DiscoveryType::kCommissionableNode) + { + SerializedQNameIterator qname; + ParsePtrRecord(data.GetData(), mPacketRange, &qname); + if (qname.Next()) + { + strncpy(mDiscoveredNodeData.instanceName, qname.Value(), sizeof(DiscoveredNodeData::instanceName)); + } + } + break; + } case QType::TXT: if (mDiscoveryType == DiscoveryType::kCommissionableNode || mDiscoveryType == DiscoveryType::kCommissionerNode) { @@ -424,6 +439,10 @@ CHIP_ERROR MinMdnsResolver::BrowseNodes(DiscoveryType type, DiscoveryFilter filt { qname = CheckAndAllocateQName(kCommissionableServiceName, kCommissionProtocol, kLocalDomain); } + else if (filter.type == DiscoveryFilterType::kInstanceName) + { + qname = CheckAndAllocateQName(filter.instanceName, kCommissionableServiceName, kCommissionProtocol, kLocalDomain); + } else { char subtypeStr[kMaxSubtypeDescSize]; diff --git a/src/lib/mdns/ServiceNaming.cpp b/src/lib/mdns/ServiceNaming.cpp index b23200dc628713..1f9f7cfa7ae24f 100644 --- a/src/lib/mdns/ServiceNaming.cpp +++ b/src/lib/mdns/ServiceNaming.cpp @@ -172,6 +172,9 @@ CHIP_ERROR MakeServiceSubtype(char * buffer, size_t bufferLen, DiscoveryFilter s } requiredSize = snprintf(buffer, bufferLen, "_A1"); break; + case DiscoveryFilterType::kInstanceName: + requiredSize = snprintf(buffer, bufferLen, "%s", subtype.instanceName); + break; case DiscoveryFilterType::kNone: requiredSize = 0; buffer[0] = '\0'; diff --git a/src/lib/mdns/ServiceNaming.h b/src/lib/mdns/ServiceNaming.h index e6fa40ee2fac15..48692804954f8b 100644 --- a/src/lib/mdns/ServiceNaming.h +++ b/src/lib/mdns/ServiceNaming.h @@ -27,7 +27,7 @@ namespace chip { namespace Mdns { -constexpr size_t kMaxSubtypeDescSize = 8; // max 5 decimal digits + _X prefix. + null character +constexpr size_t kMaxSubtypeDescSize = 16; // max 16 char service name constexpr char kSubtypeServiceNamePart[] = "_sub"; constexpr char kCommissionableServiceName[] = "_matterc"; constexpr char kOperationalServiceName[] = "_matter"; diff --git a/src/lib/mdns/tests/TestServiceNaming.cpp b/src/lib/mdns/tests/TestServiceNaming.cpp index 31efe7d940828d..d2d43f432f4d18 100644 --- a/src/lib/mdns/tests/TestServiceNaming.cpp +++ b/src/lib/mdns/tests/TestServiceNaming.cpp @@ -83,7 +83,7 @@ void TestExtractIdFromInstanceName(nlTestSuite * inSuite, void * inContext) void TestMakeServiceNameSubtype(nlTestSuite * inSuite, void * inContext) { - constexpr size_t kSize = 16; + constexpr size_t kSize = 17; char buffer[kSize]; DiscoveryFilter filter; @@ -152,6 +152,12 @@ void TestMakeServiceNameSubtype(nlTestSuite * inSuite, void * inContext) filter.type = DiscoveryFilterType::kNone; NL_TEST_ASSERT(inSuite, MakeServiceSubtype(buffer, sizeof(buffer), filter) == CHIP_NO_ERROR); NL_TEST_ASSERT(inSuite, strcmp(buffer, "") == 0); + + // instance name - "1234567890123456._matterc" + filter.type = DiscoveryFilterType::kInstanceName; + filter.instanceName = (char *) "1234567890123456"; + NL_TEST_ASSERT(inSuite, MakeServiceSubtype(buffer, sizeof(buffer), filter) == CHIP_NO_ERROR); + NL_TEST_ASSERT(inSuite, strcmp(buffer, "1234567890123456") == 0); } void TestMakeServiceTypeName(nlTestSuite * inSuite, void * inContext)