/* * * Copyright (c) 2021 Project CHIP Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include #include #include #include #include #include namespace chip { namespace Dnssd { using namespace System::Clock::Literals; // Operational node TXT entries static constexpr size_t kKeySessionIdleIntervalMaxLength = 7; // [SII] 0-3600000 static constexpr size_t kKeySessionActiveIntervalMaxLength = 7; // [SAI] 0-3600000 static constexpr size_t kKeySessionActiveThresholdMaxLength = 5; // [SAT] 0-65535 static constexpr System::Clock::Milliseconds32 kMaxRetryInterval = 3600000_ms32; static constexpr size_t kKeyTcpSupportedMaxLength = 1; static constexpr size_t kKeyLongIdleTimeICDMaxLength = 1; // Commissionable/commissioner node TXT entries static constexpr size_t kKeyLongDiscriminatorMaxLength = 5; static constexpr size_t kKeyVendorProductMaxLength = 11; static constexpr size_t kKeyCommissioningModeMaxLength = 1; static constexpr size_t kKeyDeviceTypeMaxLength = 10; static constexpr size_t kKeyDeviceNameMaxLength = 32; static constexpr size_t kKeyRotatingDeviceIdMaxLength = 100; static constexpr size_t kKeyPairingInstructionMaxLength = 128; static constexpr size_t kKeyPairingHintMaxLength = 10; static constexpr size_t kKeyCommissionerPasscodeMaxLength = 1; enum class TxtKeyUse : uint8_t { kNone, kCommon, kCommission, }; enum class TxtFieldKey : uint8_t { kUnknown, kLongDiscriminator, kVendorProduct, kCommissioningMode, kDeviceType, kDeviceName, kRotatingDeviceId, kPairingInstruction, kPairingHint, kCommissionerPasscode, kSessionIdleInterval, kSessionActiveInterval, kSessionActiveThreshold, kTcpSupported, kLongIdleTimeICD, kCount, }; namespace Internal { struct TxtFieldInfo { size_t valMaxSize; TxtFieldKey key; TxtKeyUse use; char keyStr[4]; }; constexpr const TxtFieldInfo txtFieldInfo[static_cast(TxtFieldKey::kCount)] = { { 0, TxtFieldKey::kUnknown, TxtKeyUse::kNone, "" }, { kKeyLongDiscriminatorMaxLength, TxtFieldKey::kLongDiscriminator, TxtKeyUse::kCommission, "D" }, { kKeyVendorProductMaxLength, TxtFieldKey::kVendorProduct, TxtKeyUse::kCommission, "VP" }, { kKeyCommissioningModeMaxLength, TxtFieldKey::kCommissioningMode, TxtKeyUse::kCommission, "CM" }, { kKeyDeviceTypeMaxLength, TxtFieldKey::kDeviceType, TxtKeyUse::kCommission, "DT" }, { kKeyDeviceNameMaxLength, TxtFieldKey::kDeviceName, TxtKeyUse::kCommission, "DN" }, { kKeyRotatingDeviceIdMaxLength, TxtFieldKey::kRotatingDeviceId, TxtKeyUse::kCommission, "RI" }, { kKeyPairingInstructionMaxLength, TxtFieldKey::kPairingInstruction, TxtKeyUse::kCommission, "PI" }, { kKeyPairingHintMaxLength, TxtFieldKey::kPairingHint, TxtKeyUse::kCommission, "PH" }, { kKeyCommissionerPasscodeMaxLength, TxtFieldKey::kCommissionerPasscode, TxtKeyUse::kCommission, "CP" }, { kKeySessionIdleIntervalMaxLength, TxtFieldKey::kSessionIdleInterval, TxtKeyUse::kCommon, "SII" }, { kKeySessionActiveIntervalMaxLength, TxtFieldKey::kSessionActiveInterval, TxtKeyUse::kCommon, "SAI" }, { kKeySessionActiveThresholdMaxLength, TxtFieldKey::kSessionActiveThreshold, TxtKeyUse::kCommon, "SAT" }, { kKeyTcpSupportedMaxLength, TxtFieldKey::kTcpSupported, TxtKeyUse::kCommon, "T" }, { kKeyLongIdleTimeICDMaxLength, TxtFieldKey::kLongIdleTimeICD, TxtKeyUse::kCommon, "ICD" }, }; #ifdef CHIP_CONFIG_TEST TxtFieldKey GetTxtFieldKey(const ByteSpan & key); uint16_t GetProduct(const ByteSpan & value); uint16_t GetVendor(const ByteSpan & value); uint16_t GetLongDiscriminator(const ByteSpan & value); uint8_t GetCommissioningMode(const ByteSpan & value); uint32_t GetDeviceType(const ByteSpan & value); 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); uint8_t GetCommissionerPasscode(const ByteSpan & value); #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 because 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 because 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, CommonResolutionData & nodeData); void FillNodeDataFromTxt(const ByteSpan & key, const ByteSpan & value, CommissionNodeData & nodeData); } // namespace Dnssd } // namespace chip