diff --git a/src/app/server/Mdns.cpp b/src/app/server/Mdns.cpp index 2fa796b8af0214..a78c060eae7e41 100644 --- a/src/app/server/Mdns.cpp +++ b/src/app/server/Mdns.cpp @@ -260,6 +260,7 @@ CHIP_ERROR MdnsServer::AdvertiseOperational() .SetPort(GetSecuredPort()) .SetMRPRetryIntervals(Optional(CHIP_CONFIG_MRP_DEFAULT_INITIAL_RETRY_INTERVAL), Optional(CHIP_CONFIG_MRP_DEFAULT_ACTIVE_RETRY_INTERVAL)) + .SetTcpSupported(Optional(INET_CONFIG_ENABLE_TCP_ENDPOINT)) .EnableIpV4(true); auto & mdnsAdvertiser = chip::Mdns::ServiceAdvertiser::Instance(); @@ -335,8 +336,10 @@ CHIP_ERROR MdnsServer::Advertise(bool commissionableNode, chip::Mdns::Commission advertiseParameters.SetRotatingId(chip::Optional::Value(rotatingDeviceIdHexBuffer)); #endif - advertiseParameters.SetMRPRetryIntervals(Optional(CHIP_CONFIG_MRP_DEFAULT_INITIAL_RETRY_INTERVAL), - Optional(CHIP_CONFIG_MRP_DEFAULT_ACTIVE_RETRY_INTERVAL)); + advertiseParameters + .SetMRPRetryIntervals(Optional(CHIP_CONFIG_MRP_DEFAULT_INITIAL_RETRY_INTERVAL), + Optional(CHIP_CONFIG_MRP_DEFAULT_ACTIVE_RETRY_INTERVAL)) + .SetTcpSupported(Optional(INET_CONFIG_ENABLE_TCP_ENDPOINT)); if (mode != chip::Mdns::CommissioningMode::kEnabledEnhanced) { diff --git a/src/lib/mdns/Advertiser.h b/src/lib/mdns/Advertiser.h index 87f66244d3479b..1fabef103694b9 100644 --- a/src/lib/mdns/Advertiser.h +++ b/src/lib/mdns/Advertiser.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -35,22 +36,6 @@ static constexpr uint16_t kMdnsPort = 5353; // Need 8 bytes to fit a thread mac. static constexpr size_t kMaxMacSize = 8; -// Operational node TXT entries -static constexpr size_t kTxtRetryIntervalIdleMaxLength = 7; // [CRI] 0-3600000 -static constexpr size_t kTxtRetryIntervalActiveMaxLength = 7; // [CRA] 0-3600000 -static constexpr size_t kMaxRetryInterval = 3600000; - -// Commissionable/commissioner node TXT entries -static constexpr size_t kKeyDiscriminatorMaxLength = 5; -static constexpr size_t kKeyVendorProductMaxLength = 11; -static constexpr size_t kKeyAdditionalCommissioningMaxLength = 1; -static constexpr size_t kKeyCommissioningModeMaxLength = 1; -static constexpr size_t kKeyDeviceTypeMaxLength = 5; -static constexpr size_t kKeyDeviceNameMaxLength = 32; -static constexpr size_t kKeyRotatingIdMaxLength = 100; -static constexpr size_t kKeyPairingInstructionMaxLength = 128; -static constexpr size_t kKeyPairingHintMaxLength = 10; - // Commissionable/commissioner node subtypes static constexpr size_t kSubTypeShortDiscriminatorMaxLength = 4; // _S
static constexpr size_t kSubTypeLongDiscriminatorMaxLength = 6; // _L @@ -82,11 +67,11 @@ template class BaseAdvertisingParams { public: - static constexpr uint8_t kCommonTxtMaxNumber = 2; - static constexpr size_t kCommonTxtMaxKeySize = MaxStringLength("CRI", "CRA"); // possible keys - static constexpr size_t kCommonTxtMaxValueSize = std::max({ kTxtRetryIntervalIdleMaxLength, kTxtRetryIntervalActiveMaxLength }); - static constexpr size_t kCommonTxtTotalKeySize = TotalStringLength("CRI", "CRA"); // possible keys - static constexpr size_t kCommonTxtTotalValueSize = kTxtRetryIntervalIdleMaxLength + kTxtRetryIntervalActiveMaxLength; + static constexpr uint8_t kCommonTxtMaxNumber = KeyCount(TxtKeyUse::kCommon); + static constexpr size_t kCommonTxtMaxKeySize = MaxKeyLen(TxtKeyUse::kCommon); + static constexpr size_t kCommonTxtMaxValueSize = MaxValueLen(TxtKeyUse::kCommon); + static constexpr size_t kCommonTxtTotalKeySize = TotalKeyLen(TxtKeyUse::kCommon); + static constexpr size_t kCommonTxtTotalValueSize = TotalValueLen(TxtKeyUse::kCommon); Derived & SetPort(uint16_t port) { @@ -121,6 +106,12 @@ class BaseAdvertisingParams intervalIdle = mMrpRetryIntervalIdle; intervalActive = mMrpRetryIntervalActive; } + Derived & SetTcpSupported(Optional tcpSupported) + { + mTcpSupported = tcpSupported; + return *reinterpret_cast(this); + } + Optional GetTcpSupported() const { return mTcpSupported; } private: uint16_t mPort = CHIP_PORT; @@ -129,7 +120,8 @@ class BaseAdvertisingParams size_t mMacLength = 0; Optional mMrpRetryIntervalIdle; Optional mMrpRetryIntervalActive; -}; // namespace Mdns + Optional mTcpSupported; +}; /// Defines parameters required for advertising a CHIP node /// over mDNS as an 'operationally ready' node. @@ -157,19 +149,11 @@ class OperationalAdvertisingParameters : public BaseAdvertisingParams { public: - static constexpr uint8_t kTxtMaxNumber = kCommonTxtMaxNumber + 9; - static constexpr uint8_t kTxtMaxKeySize = - std::max(kCommonTxtMaxKeySize, MaxStringLength("D", "VP", "CM", "AP", "DT", "DN", "RI", "PI", "PH")); // possible keys - static constexpr uint8_t kTxtMaxValueSize = - std::max({ kKeyDiscriminatorMaxLength, kKeyVendorProductMaxLength, kKeyAdditionalCommissioningMaxLength, - kKeyCommissioningModeMaxLength, kKeyDeviceTypeMaxLength, kKeyDeviceNameMaxLength, kKeyRotatingIdMaxLength, - kKeyPairingInstructionMaxLength, kKeyPairingHintMaxLength, kCommonTxtMaxValueSize }); - static constexpr size_t kTxtTotalKeySize = - kCommonTxtTotalKeySize + TotalStringLength("D", "VP", "CM", "AP", "DT", "DN", "RI", "PI", "PH"); // possible keys - static constexpr size_t kTxtTotalValueSize = kCommonTxtTotalValueSize + kKeyDiscriminatorMaxLength + - kKeyVendorProductMaxLength + kKeyAdditionalCommissioningMaxLength + kKeyCommissioningModeMaxLength + - kKeyDeviceTypeMaxLength + kKeyDeviceNameMaxLength + kKeyRotatingIdMaxLength + kKeyPairingInstructionMaxLength + - kKeyPairingHintMaxLength; + static constexpr uint8_t kTxtMaxNumber = kCommonTxtMaxNumber + KeyCount(TxtKeyUse::kCommission); + static constexpr uint8_t kTxtMaxKeySize = std::max(kCommonTxtMaxKeySize, MaxKeyLen(TxtKeyUse::kCommission)); + static constexpr uint8_t kTxtMaxValueSize = std::max(kCommonTxtMaxValueSize, MaxValueLen(TxtKeyUse::kCommission)); + static constexpr size_t kTxtTotalKeySize = kCommonTxtTotalKeySize + TotalKeyLen(TxtKeyUse::kCommission); + static constexpr size_t kTxtTotalValueSize = kCommonTxtTotalValueSize + TotalValueLen(TxtKeyUse::kCommission); CommissionAdvertisingParameters & SetShortDiscriminator(uint8_t discriminator) { diff --git a/src/lib/mdns/Advertiser_ImplMinimalMdns.cpp b/src/lib/mdns/Advertiser_ImplMinimalMdns.cpp index 4a2226dc3c3a99..7193151bacfb6c 100644 --- a/src/lib/mdns/Advertiser_ImplMinimalMdns.cpp +++ b/src/lib/mdns/Advertiser_ImplMinimalMdns.cpp @@ -144,9 +144,11 @@ class AdvertiserMinMdns : public ServiceAdvertiser, struct CommonTxtEntryStorage { - // CRA and CRI are both 3 chars + '=' = 4 + 1 for nullchar - char mrpRetryIntervalIdleBuf[kTxtRetryIntervalIdleMaxLength + 4 + 1]; - char mrpRetryIntervalActiveBuf[kTxtRetryIntervalActiveMaxLength + 4 + 1]; + // +2 for all to account for '=' and terminating nullchar + char mrpRetryIntervalIdleBuf[KeySize(TxtFieldKey::kMrpRetryIntervalIdle) + ValSize(TxtFieldKey::kMrpRetryIntervalIdle) + 2]; + char mrpRetryIntervalActiveBuf[KeySize(TxtFieldKey::kMrpRetryIntervalActive) + + ValSize(TxtFieldKey::kMrpRetryIntervalActive) + 2]; + char tcpSupportedBuf[KeySize(TxtFieldKey::kTcpSupport) + ValSize(TxtFieldKey::kTcpSupport) + 2]; }; template CHIP_ERROR AddCommonTxtEntries(const BaseAdvertisingParams & params, CommonTxtEntryStorage & storage, @@ -203,6 +205,14 @@ class AdvertiserMinMdns : public ServiceAdvertiser, CHIP_ERROR_INVALID_STRING_LENGTH); txtFields[numTxtFields++] = storage.mrpRetryIntervalActiveBuf; } + if (params.GetTcpSupported().HasValue()) + { + size_t writtenCharactersNumber = + snprintf(storage.tcpSupportedBuf, sizeof(storage.tcpSupportedBuf), "T=%d", params.GetTcpSupported().Value()); + VerifyOrReturnError((writtenCharactersNumber > 0) && (writtenCharactersNumber < sizeof(storage.tcpSupportedBuf)), + CHIP_ERROR_INVALID_STRING_LENGTH); + txtFields[numTxtFields++] = storage.tcpSupportedBuf; + } return CHIP_NO_ERROR; } diff --git a/src/lib/mdns/Discovery_ImplPlatform.cpp b/src/lib/mdns/Discovery_ImplPlatform.cpp index fe6daf728ddafd..1ec2470e844e2d 100644 --- a/src/lib/mdns/Discovery_ImplPlatform.cpp +++ b/src/lib/mdns/Discovery_ImplPlatform.cpp @@ -123,9 +123,10 @@ CHIP_ERROR DiscoveryImplPlatform::GetCommissionableInstanceName(char * instanceN return CHIP_NO_ERROR; } -template +template CHIP_ERROR AddCommonTxtElements(const BaseAdvertisingParams & params, char (&mrpRetryIdleStorage)[N_idle], - char (&mrpRetryActiveStorage)[N_active], TextEntry txtEntryStorage[], size_t & txtEntryIdx) + char (&mrpRetryActiveStorage)[N_active], char (&tcpSupportedStorage)[N_tcp], + TextEntry txtEntryStorage[], size_t & txtEntryIdx) { Optional mrpRetryIntervalIdle, mrpRetryIntervalActive; params.GetMRPRetryIntervals(mrpRetryIntervalIdle, mrpRetryIntervalActive); @@ -178,6 +179,15 @@ CHIP_ERROR AddCommonTxtElements(const BaseAdvertisingParams & params, c CHIP_ERROR_INVALID_STRING_LENGTH); txtEntryStorage[txtEntryIdx++] = { "CRA", Uint8::from_const_char(mrpRetryActiveStorage), strlen(mrpRetryActiveStorage) }; } + if (params.GetTcpSupported().HasValue()) + { + size_t writtenCharactersNumber = + snprintf(tcpSupportedStorage, sizeof(tcpSupportedStorage), "%d", params.GetTcpSupported().Value()); + VerifyOrReturnError((writtenCharactersNumber > 0) && (writtenCharactersNumber <= kKeyTcpSupportMaxLength), + CHIP_ERROR_INVALID_STRING_LENGTH); + txtEntryStorage[txtEntryIdx++] = { "T", reinterpret_cast(tcpSupportedStorage), + strlen(tcpSupportedStorage) }; + } return CHIP_NO_ERROR; } @@ -196,6 +206,7 @@ CHIP_ERROR DiscoveryImplPlatform::Advertise(const CommissionAdvertisingParameter char pairingInstrBuf[kKeyPairingInstructionMaxLength + 1]; char mrpRetryIntervalIdleBuf[kTxtRetryIntervalIdleMaxLength + 1]; char mrpRetryIntervalActiveBuf[kTxtRetryIntervalActiveMaxLength + 1]; + char tcpSupportedBuf[kKeyTcpSupportMaxLength + 1]; // size of textEntries array should be count of Bufs above TextEntry textEntries[CommissionAdvertisingParameters::kTxtMaxNumber]; size_t textEntrySize = 0; @@ -261,8 +272,8 @@ CHIP_ERROR DiscoveryImplPlatform::Advertise(const CommissionAdvertisingParameter textEntries[textEntrySize++] = { "DN", reinterpret_cast(deviceNameBuf), strnlen(deviceNameBuf, sizeof(deviceNameBuf)) }; } - AddCommonTxtElements(params, mrpRetryIntervalIdleBuf, mrpRetryIntervalActiveBuf, textEntries, - textEntrySize); + AddCommonTxtElements(params, mrpRetryIntervalIdleBuf, mrpRetryIntervalActiveBuf, + tcpSupportedBuf, textEntries, textEntrySize); // Following fields are for nodes and not for commissioners if (params.GetCommissionAdvertiseMode() == CommssionAdvertiseMode::kCommissionableNode) @@ -391,11 +402,12 @@ CHIP_ERROR DiscoveryImplPlatform::Advertise(const OperationalAdvertisingParamete char mrpRetryIntervalIdleBuf[kTxtRetryIntervalIdleMaxLength + 1]; char mrpRetryIntervalActiveBuf[kTxtRetryIntervalActiveMaxLength + 1]; + char tcpSupportedBuf[kKeyTcpSupportMaxLength + 1]; TextEntry txtEntries[OperationalAdvertisingParameters::kTxtMaxNumber]; size_t textEntrySize = 0; - ReturnLogErrorOnFailure( - AddCommonTxtElements(params, mrpRetryIntervalIdleBuf, mrpRetryIntervalActiveBuf, txtEntries, textEntrySize)); + ReturnLogErrorOnFailure(AddCommonTxtElements(params, mrpRetryIntervalIdleBuf, mrpRetryIntervalActiveBuf, tcpSupportedBuf, + txtEntries, textEntrySize)); if (MakeServiceSubtype(compressedFabricIdSub, sizeof(compressedFabricIdSub), DiscoveryFilter(DiscoveryFilterType::kCompressedFabricId, params.GetPeerId().GetCompressedFabricId())) == diff --git a/src/lib/mdns/TxtFields.cpp b/src/lib/mdns/TxtFields.cpp index 389535d2f27988..02040860e34251 100644 --- a/src/lib/mdns/TxtFields.cpp +++ b/src/lib/mdns/TxtFields.cpp @@ -183,95 +183,55 @@ uint32_t GetRetryInterval(const ByteSpan & value) TxtFieldKey GetTxtFieldKey(const ByteSpan & key) { - if (IsKey(key, "D")) + for (auto & info : txtFieldInfo) { - return TxtFieldKey::kLongDiscriminator; - } - else if (IsKey(key, "VP")) - { - return TxtFieldKey::kVendorProduct; - } - else if (IsKey(key, "CM")) - { - return TxtFieldKey::kCommissioningMode; - } - else if (IsKey(key, "DT")) - { - return TxtFieldKey::kDeviceType; - } - else if (IsKey(key, "DN")) - { - return TxtFieldKey::kDeviceName; - } - else if (IsKey(key, "RI")) - { - return TxtFieldKey::kRotatingDeviceId; - } - else if (IsKey(key, "PI")) - { - return TxtFieldKey::kPairingInstruction; - } - else if (IsKey(key, "PH")) - { - return TxtFieldKey::kPairingHint; - } - else if (IsKey(key, "CRI")) - { - return TxtFieldKey::kMrpRetryIntervalIdle; - } - else if (IsKey(key, "CRA")) - { - return TxtFieldKey::kMrpRetryIntervalActive; - } - else if (IsKey(key, "T")) - { - return TxtFieldKey::kTcpSupport; - } - else - { - return TxtFieldKey::kUnknown; + if (IsKey(key, info.keyStr)) + { + return info.key; + } } + return TxtFieldKey::kUnknown; } } // namespace Internal void FillNodeDataFromTxt(const ByteSpan & key, const ByteSpan & val, DiscoveredNodeData & nodeData) { - Internal::TxtFieldKey keyType = Internal::GetTxtFieldKey(key); + TxtFieldKey keyType = Internal::GetTxtFieldKey(key); switch (keyType) { - case Internal::TxtFieldKey::kLongDiscriminator: + case TxtFieldKey::kLongDiscriminator: nodeData.longDiscriminator = Internal::GetLongDiscriminator(val); break; - case Internal::TxtFieldKey::kVendorProduct: + case TxtFieldKey::kVendorProduct: nodeData.vendorId = Internal::GetVendor(val); nodeData.productId = Internal::GetProduct(val); break; - case Internal::TxtFieldKey::kCommissioningMode: + case TxtFieldKey::kCommissioningMode: nodeData.commissioningMode = Internal::GetCommissioningMode(val); break; - case Internal::TxtFieldKey::kDeviceType: + case TxtFieldKey::kDeviceType: nodeData.deviceType = Internal::GetDeviceType(val); break; - case Internal::TxtFieldKey::kDeviceName: + case TxtFieldKey::kDeviceName: Internal::GetDeviceName(val, nodeData.deviceName); break; - case Internal::TxtFieldKey::kRotatingDeviceId: + case TxtFieldKey::kRotatingDeviceId: Internal::GetRotatingDeviceId(val, nodeData.rotatingId, &nodeData.rotatingIdLen); break; - case Internal::TxtFieldKey::kPairingInstruction: + case TxtFieldKey::kPairingInstruction: Internal::GetPairingInstruction(val, nodeData.pairingInstruction); break; - case Internal::TxtFieldKey::kPairingHint: + case TxtFieldKey::kPairingHint: nodeData.pairingHint = Internal::GetPairingHint(val); break; - case Internal::TxtFieldKey::kMrpRetryIntervalIdle: + case TxtFieldKey::kMrpRetryIntervalIdle: nodeData.mrpRetryIntervalIdle = Internal::GetRetryInterval(val); break; - case Internal::TxtFieldKey::kMrpRetryIntervalActive: + case TxtFieldKey::kMrpRetryIntervalActive: nodeData.mrpRetryIntervalActive = Internal::GetRetryInterval(val); break; - case Internal::TxtFieldKey::kTcpSupport: + case TxtFieldKey::kTcpSupport: nodeData.supportsTcp = Internal::MakeBoolFromAsciiDecimal(val); break; default: @@ -283,13 +243,13 @@ void FillNodeDataFromTxt(const ByteSpan & key, const ByteSpan & value, ResolvedN { switch (Internal::GetTxtFieldKey(key)) { - case Internal::TxtFieldKey::kMrpRetryIntervalIdle: + case TxtFieldKey::kMrpRetryIntervalIdle: nodeData.mMrpRetryIntervalIdle = Internal::GetRetryInterval(value); break; - case Internal::TxtFieldKey::kMrpRetryIntervalActive: + case TxtFieldKey::kMrpRetryIntervalActive: nodeData.mMrpRetryIntervalActive = Internal::GetRetryInterval(value); break; - case Internal::TxtFieldKey::kTcpSupport: + case TxtFieldKey::kTcpSupport: nodeData.mSupportsTcp = Internal::MakeBoolFromAsciiDecimal(value); break; default: diff --git a/src/lib/mdns/TxtFields.h b/src/lib/mdns/TxtFields.h index 2f63009cdda7d2..d8a87533288f9f 100644 --- a/src/lib/mdns/TxtFields.h +++ b/src/lib/mdns/TxtFields.h @@ -27,8 +27,29 @@ namespace chip { namespace Mdns { -#ifdef CHIP_CONFIG_TEST -namespace Internal { +// Operational node TXT entries +static constexpr size_t kTxtRetryIntervalIdleMaxLength = 7; // [CRI] 0-3600000 +static constexpr size_t kTxtRetryIntervalActiveMaxLength = 7; // [CRA] 0-3600000 +static constexpr size_t kMaxRetryInterval = 3600000; +static constexpr size_t kKeyTcpSupportMaxLength = 1; + +// Commissionable/commissioner node TXT entries +static constexpr size_t kKeyDiscriminatorMaxLength = 5; +static constexpr size_t kKeyVendorProductMaxLength = 11; +static constexpr size_t kKeyAdditionalCommissioningMaxLength = 1; +static constexpr size_t kKeyCommissioningModeMaxLength = 1; +static constexpr size_t kKeyDeviceTypeMaxLength = 5; +static constexpr size_t kKeyDeviceNameMaxLength = 32; +static constexpr size_t kKeyRotatingIdMaxLength = 100; +static constexpr size_t kKeyPairingInstructionMaxLength = 128; +static constexpr size_t kKeyPairingHintMaxLength = 10; + +enum class TxtKeyUse : uint8_t +{ + kNone, + kCommon, + kCommission, +}; enum class TxtFieldKey : uint8_t { @@ -45,8 +66,35 @@ enum class TxtFieldKey : uint8_t kMrpRetryIntervalIdle, kMrpRetryIntervalActive, kTcpSupport, + kCount, }; +namespace Internal { +struct TxtFieldInfo +{ + TxtFieldKey key; + size_t valMaxSize; + char keyStr[4]; + TxtKeyUse use; +}; + +constexpr const TxtFieldInfo txtFieldInfo[static_cast(TxtFieldKey::kCount)] = { + { TxtFieldKey::kUnknown, 0, "", TxtKeyUse::kNone }, + { TxtFieldKey::kLongDiscriminator, kKeyDiscriminatorMaxLength, "D", TxtKeyUse::kCommission }, + { TxtFieldKey::kVendorProduct, kKeyVendorProductMaxLength, "VP", TxtKeyUse::kCommission }, + { TxtFieldKey::kAdditionalPairing, kKeyAdditionalCommissioningMaxLength, "AP", TxtKeyUse::kCommission }, + { TxtFieldKey::kCommissioningMode, kKeyCommissioningModeMaxLength, "CM", TxtKeyUse::kCommission }, + { TxtFieldKey::kDeviceType, kKeyDeviceTypeMaxLength, "DT", TxtKeyUse::kCommission }, + { TxtFieldKey::kDeviceName, kKeyDeviceNameMaxLength, "DN", TxtKeyUse::kCommission }, + { TxtFieldKey::kRotatingDeviceId, kKeyRotatingIdMaxLength, "RI", TxtKeyUse::kCommission }, + { TxtFieldKey::kPairingInstruction, kKeyPairingInstructionMaxLength, "PI", TxtKeyUse::kCommission }, + { TxtFieldKey::kPairingHint, kKeyPairingHintMaxLength, "PH", TxtKeyUse::kCommission }, + { TxtFieldKey::kMrpRetryIntervalIdle, kTxtRetryIntervalIdleMaxLength, "CRI", TxtKeyUse::kCommon }, + { TxtFieldKey::kMrpRetryIntervalActive, kTxtRetryIntervalActiveMaxLength, "CRA", TxtKeyUse::kCommon }, + { TxtFieldKey::kTcpSupport, kKeyTcpSupportMaxLength, "T", TxtKeyUse::kCommon }, +}; +#ifdef CHIP_CONFIG_TEST + TxtFieldKey GetTxtFieldKey(const ByteSpan & key); uint16_t GetProduct(const ByteSpan & value); @@ -59,9 +107,80 @@ void GetDeviceName(const ByteSpan & value, char * name); void GetRotatingDeviceId(const ByteSpan & value, uint8_t * rotatingId, size_t * len); uint16_t GetPairingHint(const ByteSpan & value); void GetPairingInstruction(const ByteSpan & value, char * pairingInstruction); - -} // namespace Internal #endif +} // namespace Internal + +constexpr size_t MaxKeyLen(TxtKeyUse use) +{ + size_t max = 0; + for (auto & info : Internal::txtFieldInfo) + { + if (use == info.use) + { + max = sizeof(info.keyStr) > max ? sizeof(info.keyStr) : max; + } + } + // minus 1 becuase sizeof includes the null terminator. + return max - 1; +} +constexpr size_t TotalKeyLen(TxtKeyUse use) +{ + size_t total = 0; + for (auto & info : Internal::txtFieldInfo) + { + if (use == info.use) + { + total += sizeof(info.keyStr) - 1; + } + } + return total; +} + +constexpr size_t MaxValueLen(TxtKeyUse use) +{ + size_t max = 0; + for (auto & info : Internal::txtFieldInfo) + { + if (use == info.use) + { + max = info.valMaxSize > max ? info.valMaxSize : max; + } + } + // minus 1 becuase sizeof includes the null terminator. + return max - 1; +} +constexpr size_t TotalValueLen(TxtKeyUse use) +{ + size_t total = 0; + for (auto & info : Internal::txtFieldInfo) + { + if (use == info.use) + { + total += info.valMaxSize - 1; + } + } + return total; +} +constexpr uint8_t KeyCount(TxtKeyUse use) +{ + uint8_t count = 0; + for (auto & info : Internal::txtFieldInfo) + { + if (use == info.use) + { + count++; + } + } + return count; +} +constexpr size_t KeySize(TxtFieldKey key) +{ + return sizeof(Internal::txtFieldInfo[static_cast(key)].keyStr) - 1; +} +constexpr size_t ValSize(TxtFieldKey key) +{ + return Internal::txtFieldInfo[static_cast(key)].valMaxSize; +} void FillNodeDataFromTxt(const ByteSpan & key, const ByteSpan & value, DiscoveredNodeData & nodeData); void FillNodeDataFromTxt(const ByteSpan & key, const ByteSpan & value, ResolvedNodeData & nodeData); diff --git a/src/lib/mdns/minimal/tests/CheckOnlyServer.h b/src/lib/mdns/minimal/tests/CheckOnlyServer.h index 011e37d0072bba..e5d836e262a90a 100644 --- a/src/lib/mdns/minimal/tests/CheckOnlyServer.h +++ b/src/lib/mdns/minimal/tests/CheckOnlyServer.h @@ -303,7 +303,7 @@ class CheckOnlyServer : public ServerBase, public ParserDelegate, public TxtReco found = false; } }; - static constexpr size_t kMaxExpectedTxt = 10; + static constexpr size_t kMaxExpectedTxt = 11; KV mExpectedTxt[kMaxExpectedTxt]; size_t mNumExpectedTxtRecords = 0; size_t mNumReceivedTxtRecords = 0; diff --git a/src/lib/mdns/minimal/tests/TestAdvertiser.cpp b/src/lib/mdns/minimal/tests/TestAdvertiser.cpp index bf5fa68a7d66c9..25953cbcd266bc 100644 --- a/src/lib/mdns/minimal/tests/TestAdvertiser.cpp +++ b/src/lib/mdns/minimal/tests/TestAdvertiser.cpp @@ -77,6 +77,7 @@ OperationalAdvertisingParameters operationalParams1 = .SetMac(ByteSpan(kMac)) .SetPort(CHIP_PORT) .EnableIpV4(true) + .SetTcpSupported(chip::Optional(false)) .SetMRPRetryIntervals(chip::Optional(32), chip::Optional(33)); OperationalAdvertisingParameters operationalParams2 = OperationalAdvertisingParameters().SetPeerId(kPeerId2).SetMac(ByteSpan(kMac)).SetPort(CHIP_PORT).EnableIpV4(true); @@ -88,7 +89,7 @@ OperationalAdvertisingParameters operationalParams5 = OperationalAdvertisingParameters().SetPeerId(kPeerId5).SetMac(ByteSpan(kMac)).SetPort(CHIP_PORT).EnableIpV4(true); OperationalAdvertisingParameters operationalParams6 = OperationalAdvertisingParameters().SetPeerId(kPeerId6).SetMac(ByteSpan(kMac)).SetPort(CHIP_PORT).EnableIpV4(true); -const QNamePart txtOperational1Parts[] = { "CRI=32", "CRA=33" }; +const QNamePart txtOperational1Parts[] = { "CRI=32", "CRA=33", "T=0" }; PtrResourceRecord ptrOperationalService = PtrResourceRecord(kDnsSdQueryName, kMatterOperationalQueryName); PtrResourceRecord ptrOperational1 = PtrResourceRecord(kMatterOperationalQueryName, kInstanceName1); SrvResourceRecord srvOperational1 = SrvResourceRecord(kInstanceName1, kHostnameName, CHIP_PORT); @@ -176,11 +177,12 @@ CommissionAdvertisingParameters commissionableNodeParamsLargeEnhanced = .SetPairingInstr(chip::Optional("Pair me")) .SetProductId(chip::Optional(897)) .SetRotatingId(chip::Optional("id_that_spins")) + .SetTcpSupported(chip::Optional(true)) .SetMRPRetryIntervals(chip::Optional(3600000), chip::Optional(3600005)); // 3600005 is more than the max so should be adjusted down QNamePart txtCommissionableNodeParamsLargeEnhancedParts[] = { "D=22", "VP=555+897", "CM=2", "DT=25", "DN=testy-test", "RI=id_that_spins", "PI=Pair me", "PH=3", - "CRA=3600000", "CRI=3600000" }; + "CRA=3600000", "CRI=3600000", "T=1" }; FullQName txtCommissionableNodeParamsLargeEnhancedName = FullQName(txtCommissionableNodeParamsLargeEnhancedParts); TxtResourceRecord txtCommissionableNodeParamsLargeEnhanced = TxtResourceRecord(instanceName, txtCommissionableNodeParamsLargeEnhancedName); diff --git a/src/lib/mdns/platform/tests/TestPlatform.cpp b/src/lib/mdns/platform/tests/TestPlatform.cpp index b8c40515a32188..58b585f0dd01fd 100644 --- a/src/lib/mdns/platform/tests/TestPlatform.cpp +++ b/src/lib/mdns/platform/tests/TestPlatform.cpp @@ -50,7 +50,8 @@ OperationalAdvertisingParameters operationalParams2 = OperationalAdvertisingPara .SetMac(ByteSpan(kMac)) .SetPort(CHIP_PORT) .EnableIpV4(true) - .SetMRPRetryIntervals(Optional(32), Optional(33)); + .SetMRPRetryIntervals(Optional(32), Optional(33)) + .SetTcpSupported(Optional(true)); test::ExpectedCall operationalCall2 = test::ExpectedCall() .SetProtocol(MdnsServiceProtocol::kMdnsProtocolTcp) .SetServiceName("_matter") @@ -58,7 +59,8 @@ test::ExpectedCall operationalCall2 = test::ExpectedCall() .SetHostName(host) .AddSubtype("_I5555666677778888") .AddTxt("CRI", "32") - .AddTxt("CRA", "33"); + .AddTxt("CRA", "33") + .AddTxt("T", "1"); CommissionAdvertisingParameters commissionableNodeParamsSmall = CommissionAdvertisingParameters() @@ -90,6 +92,7 @@ CommissionAdvertisingParameters commissionableNodeParamsLargeBasic = .SetPairingInstr(chip::Optional("Pair me")) .SetProductId(chip::Optional(897)) .SetRotatingId(chip::Optional("id_that_spins")) + .SetTcpSupported(chip::Optional(true)) .SetMRPRetryIntervals( chip::Optional(3600000), chip::Optional(3600005)); // 3600005 is over the max, so this should be adjusted by the platform @@ -106,6 +109,7 @@ test::ExpectedCall commissionableLargeBasic = test::ExpectedCall() .AddTxt("RI", "id_that_spins") .AddTxt("PI", "Pair me") .AddTxt("PH", "3") + .AddTxt("T", "1") .AddTxt("CRI", "3600000") .AddTxt("CRA", "3600000") .AddSubtype("_S2") diff --git a/src/platform/fake/MdnsImpl.h b/src/platform/fake/MdnsImpl.h index 5c08735d79344c..e2d176ad67a3fb 100644 --- a/src/platform/fake/MdnsImpl.h +++ b/src/platform/fake/MdnsImpl.h @@ -166,7 +166,7 @@ struct ExpectedCall } } - static constexpr size_t kMaxTxtRecords = 10; + static constexpr size_t kMaxTxtRecords = 11; static constexpr size_t kMaxSubtypes = 10; CallType callType = CallType::kUnknown; MdnsServiceProtocol protocol = MdnsServiceProtocol::kMdnsProtocolUnknown;