/* * * Copyright (c) 2021 Project CHIP Authors * All rights reserved. * * 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. */ #include #include #include #include #include #include #include using namespace chip; using namespace chip::Dnssd; using namespace chip::Dnssd::Internal; namespace { ByteSpan GetSpan(char * key) { size_t len = strlen(key); // Stop the string from being null terminated to ensure the code makes no assumptions. key[len] = '1'; return ByteSpan(reinterpret_cast(key), len); } TEST(TestTxtFields, TestGetTxtFieldKey) { char key[4]; strcpy(key, "D"); EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kLongDiscriminator); strcpy(key, "VP"); EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kVendorProduct); strcpy(key, "CM"); EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kCommissioningMode); strcpy(key, "DT"); EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kDeviceType); strcpy(key, "DN"); EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kDeviceName); strcpy(key, "RI"); EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kRotatingDeviceId); strcpy(key, "PI"); EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kPairingInstruction); strcpy(key, "PH"); EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kPairingHint); strcpy(key, "SII"); EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kSessionIdleInterval); strcpy(key, "SAI"); EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kSessionActiveInterval); strcpy(key, "SAT"); EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kSessionActiveThreshold); strcpy(key, "T"); EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kTcpSupported); strcpy(key, "ICD"); EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kLongIdleTimeICD); strcpy(key, "XX"); EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kUnknown); strcpy(key, "CP"); EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kCommissionerPasscode); } TEST(TestTxtFields, TestGetTxtFieldKeyCaseInsensitive) { char key[3]; strcpy(key, "d"); EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kLongDiscriminator); strcpy(key, "vp"); EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kVendorProduct); strcpy(key, "Vp"); EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kVendorProduct); strcpy(key, "vP"); EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kVendorProduct); strcpy(key, "Xx"); EXPECT_EQ(GetTxtFieldKey(GetSpan(key)), TxtFieldKey::kUnknown); } TEST(TestTxtFields, TestGetProduct) { // Product and vendor are given as part of the same key, on either side of a + sign. Product is after the + char vp[64]; strcpy(vp, "123+456"); EXPECT_EQ(GetProduct(GetSpan(vp)), 456); strcpy(vp, "123+"); EXPECT_EQ(GetProduct(GetSpan(vp)), 0); strcpy(vp, "+456"); EXPECT_EQ(GetProduct(GetSpan(vp)), 456); strcpy(vp, "123"); EXPECT_EQ(GetProduct(GetSpan(vp)), 0); // overflow a uint16 sprintf(vp, "123+%" PRIu32, static_cast(std::numeric_limits::max()) + 1); EXPECT_EQ(GetProduct(GetSpan(vp)), 0); } TEST(TestTxtFields, TestGetVendor) { // Product and vendor are given as part of the same key, on either side of a + sign. Vendor is first char vp[64]; strcpy(vp, "123+456"); EXPECT_EQ(GetVendor(GetSpan(vp)), 123); strcpy(vp, "123+"); EXPECT_EQ(GetVendor(GetSpan(vp)), 123); strcpy(vp, "+456"); EXPECT_EQ(GetVendor(GetSpan(vp)), 0); strcpy(vp, "123"); EXPECT_EQ(GetVendor(GetSpan(vp)), 123); // overflow a uint16 sprintf(vp, "%" PRIu32 "+456", static_cast(std::numeric_limits::max()) + 1); EXPECT_EQ(GetVendor(GetSpan(vp)), 0); } TEST(TestTxtFields, TestGetLongDiscriminator) { char ld[64]; strcpy(ld, "1234"); EXPECT_EQ(GetLongDiscriminator(GetSpan(ld)), 1234); // overflow a uint16 sprintf(ld, "%" PRIu32, static_cast(std::numeric_limits::max()) + 1); printf("ld = %s\n", ld); EXPECT_EQ(GetLongDiscriminator(GetSpan(ld)), 0); } TEST(TestTxtFields, TestGetCommissioningMode) { char cm[64]; strcpy(cm, "0"); EXPECT_EQ(GetCommissioningMode(GetSpan(cm)), 0); strcpy(cm, "1"); EXPECT_EQ(GetCommissioningMode(GetSpan(cm)), 1); strcpy(cm, "2"); EXPECT_EQ(GetCommissioningMode(GetSpan(cm)), 2); // overflow a uint8 sprintf(cm, "%u", static_cast(std::numeric_limits::max()) + 1); EXPECT_EQ(GetCommissioningMode(GetSpan(cm)), 0); } TEST(TestTxtFields, TestGetDeviceType) { char dt[64]; strcpy(dt, "1234"); EXPECT_EQ(GetDeviceType(GetSpan(dt)), 1234u); // overflow a uint32 sprintf(dt, "%" PRIu64, static_cast(std::numeric_limits::max()) + 1); EXPECT_EQ(GetDeviceType(GetSpan(dt)), 0u); } TEST(TestTxtFields, TestGetDeviceName) { char name[kMaxDeviceNameLen + 1] = ""; char val[kMaxDeviceNameLen + 2]; strcpy(val, "testname"); GetDeviceName(GetSpan(val), name); EXPECT_STREQ(name, "testname"); // If the data passed in is too long, it should truncate the end. memset(val, 'a', kMaxDeviceNameLen); val[kMaxDeviceNameLen] = 'b'; val[kMaxDeviceNameLen + 1] = '\0'; GetDeviceName(GetSpan(val), name); val[kMaxDeviceNameLen] = '\0'; EXPECT_STREQ(name, val); } TEST(TestTxtFields, TestGetRotatingDeviceId) { // Rotating device ID is given as up to 50 hex bytes char ri[kMaxRotatingIdLen * 2 + 1]; uint8_t id[kMaxRotatingIdLen]; size_t len; strcpy(ri, "0A1B"); GetRotatingDeviceId(GetSpan(ri), id, &len); printf("id[0] = %x\n", id[0]); EXPECT_EQ(id[0], 0x0A); EXPECT_EQ(id[1], 0x1B); EXPECT_EQ(len, 2u); // odd number of characters can't be parsed. strcpy(ri, "0A1BC"); GetRotatingDeviceId(GetSpan(ri), id, &len); EXPECT_EQ(len, 0u); // non-hex characters can't be parsed strcpy(ri, "0ATT"); GetRotatingDeviceId(GetSpan(ri), id, &len); EXPECT_EQ(len, 0u); // Lower case should work on SDK even though devices shouldn't be sending that. strcpy(ri, "0a1b"); GetRotatingDeviceId(GetSpan(ri), id, &len); EXPECT_EQ(id[0], 0x0A); EXPECT_EQ(id[1], 0x1B); EXPECT_EQ(len, 2u); strcpy(ri, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F3031"); GetRotatingDeviceId(GetSpan(ri), id, &len); EXPECT_EQ(len, sizeof(id)); for (size_t i = 0; i < sizeof(id); ++i) { EXPECT_EQ(id[i], i); } } TEST(TestTxtFields, TestGetPairingHint) { char ph[64]; strcpy(ph, "0"); EXPECT_EQ(GetPairingHint(GetSpan(ph)), 0); strcpy(ph, "9"); EXPECT_EQ(GetPairingHint(GetSpan(ph)), 9); // overflow a uint16 sprintf(ph, "%" PRIu32, static_cast(std::numeric_limits::max()) + 1); EXPECT_EQ(GetPairingHint(GetSpan(ph)), 0); } TEST(TestTxtFields, TestGetPairingInstruction) { char data[kMaxPairingInstructionLen + 2]; char ret[kMaxPairingInstructionLen + 1] = ""; strcpy(data, "something"); GetPairingInstruction(GetSpan(data), ret); EXPECT_STREQ(ret, "something"); // Exactly the max len. memset(data, 'a', kMaxPairingInstructionLen); data[kMaxPairingInstructionLen] = '\0'; GetPairingInstruction(GetSpan(data), ret); // Add back the null terminator removed by GetSpan. data[kMaxPairingInstructionLen] = '\0'; EXPECT_STREQ(data, ret); // Too long - should truncate end. memset(data, 'a', kMaxPairingInstructionLen); data[kMaxPairingInstructionLen] = 'b'; data[kMaxPairingInstructionLen + 1] = '\0'; GetPairingInstruction(GetSpan(data), ret); data[kMaxPairingInstructionLen] = '\0'; EXPECT_STREQ(ret, data); } TEST(TestTxtFields, TestGetCommissionerPasscode) { char cm[64]; strcpy(cm, "0"); EXPECT_EQ(GetCommissionerPasscode(GetSpan(cm)), 0); strcpy(cm, "1"); EXPECT_EQ(GetCommissionerPasscode(GetSpan(cm)), 1); // overflow a uint8 sprintf(cm, "%u", static_cast(std::numeric_limits::max()) + 1); EXPECT_EQ(GetCommissionerPasscode(GetSpan(cm)), 0); } bool NodeDataIsEmpty(const CommissionNodeData & node) { if (node.longDiscriminator != 0 || node.vendorId != 0 || node.productId != 0 || node.commissioningMode != 0 || node.deviceType != 0 || node.rotatingIdLen != 0 || node.pairingHint != 0 || node.mrpRetryIntervalIdle.has_value() || node.mrpRetryIntervalActive.has_value() || node.mrpRetryActiveThreshold.has_value() || node.isICDOperatingAsLIT.has_value() || node.supportsTcpServer || node.supportsTcpClient || node.supportsCommissionerGeneratedPasscode != 0) { return false; } if (strcmp(node.deviceName, "") != 0 || strcmp(node.pairingInstruction, "") != 0) { return false; } for (uint8_t id : node.rotatingId) { if (id != 0) { return false; } } return true; } // The individual fill tests test the error cases for each key type, this test is used to ensure the proper record is filled. TEST(TestTxtFields, TestFillDiscoveredNodeDataFromTxt) { char key[3]; char val[16]; CommissionNodeData filled; // Long discriminator strcpy(key, "D"); strcpy(val, "840"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), filled); EXPECT_EQ(filled.longDiscriminator, 840); filled.longDiscriminator = 0; EXPECT_TRUE(NodeDataIsEmpty(filled)); // vendor and product strcpy(key, "VP"); strcpy(val, "123+456"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), filled); EXPECT_EQ(filled.vendorId, 123); EXPECT_EQ(filled.productId, 456); filled.vendorId = 0; filled.productId = 0; EXPECT_TRUE(NodeDataIsEmpty(filled)); // Commissioning mode strcpy(key, "CM"); strcpy(val, "1"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), filled); EXPECT_EQ(filled.commissioningMode, 1); filled.commissioningMode = 0; EXPECT_TRUE(NodeDataIsEmpty(filled)); // Supports Commissioner Generated Passcode strcpy(key, "CP"); strcpy(val, "1"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), filled); EXPECT_TRUE(filled.supportsCommissionerGeneratedPasscode); filled.supportsCommissionerGeneratedPasscode = false; EXPECT_TRUE(NodeDataIsEmpty(filled)); // Device type strcpy(key, "DT"); strcpy(val, "1"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), filled); EXPECT_EQ(filled.deviceType, 1u); filled.deviceType = 0; EXPECT_TRUE(NodeDataIsEmpty(filled)); // Device name strcpy(key, "DN"); strcpy(val, "abc"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), filled); EXPECT_STREQ(filled.deviceName, "abc"); memset(filled.deviceName, 0, sizeof(filled.deviceName)); EXPECT_TRUE(NodeDataIsEmpty(filled)); // Rotating device id strcpy(key, "RI"); strcpy(val, "1A2B"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), filled); EXPECT_EQ(filled.rotatingId[0], 0x1A); EXPECT_EQ(filled.rotatingId[1], 0x2B); EXPECT_EQ(filled.rotatingIdLen, 2u); filled.rotatingIdLen = 0; memset(filled.rotatingId, 0, sizeof(filled.rotatingId)); EXPECT_TRUE(NodeDataIsEmpty(filled)); // Pairing instruction strcpy(key, "PI"); strcpy(val, "hint"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), filled); EXPECT_STREQ(filled.pairingInstruction, "hint"); memset(filled.pairingInstruction, 0, sizeof(filled.pairingInstruction)); EXPECT_TRUE(NodeDataIsEmpty(filled)); // Pairing hint strcpy(key, "PH"); strcpy(val, "1"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), filled); EXPECT_EQ(filled.pairingHint, 1); filled.pairingHint = 0; EXPECT_TRUE(NodeDataIsEmpty(filled)); } bool NodeDataIsEmpty(const ResolvedNodeData & nodeData) { return nodeData.operationalData.peerId == PeerId{} && nodeData.resolutionData.numIPs == 0 && nodeData.resolutionData.port == 0 && !nodeData.resolutionData.mrpRetryIntervalIdle.has_value() && !nodeData.resolutionData.mrpRetryIntervalActive.has_value() && !nodeData.resolutionData.supportsTcpClient && !nodeData.resolutionData.supportsTcpServer && !nodeData.resolutionData.isICDOperatingAsLIT.has_value(); } void ResetRetryIntervalIdle(DiscoveredNodeData & nodeData) { nodeData.Get().mrpRetryIntervalIdle.reset(); } void ResetRetryIntervalIdle(ResolvedNodeData & nodeData) { nodeData.resolutionData.mrpRetryIntervalIdle.reset(); } void ResetRetryIntervalActive(DiscoveredNodeData & nodeData) { nodeData.Get().mrpRetryIntervalActive.reset(); } void ResetRetryIntervalActive(ResolvedNodeData & nodeData) { nodeData.resolutionData.mrpRetryIntervalActive.reset(); } void ResetRetryActiveThreshold(DiscoveredNodeData & nodeData) { nodeData.Get().mrpRetryActiveThreshold.reset(); } void ResetRetryActiveThreshold(ResolvedNodeData & nodeData) { nodeData.resolutionData.mrpRetryActiveThreshold.reset(); } template void DiscoveredTxtFieldSessionIdleInterval() { char key[4]; char val[16]; DiscoveredNodeData nodeData; nodeData.Set(); CommonResolutionData & resolutionData = nodeData.Get(); // Minimum strcpy(key, "SII"); strcpy(val, "1"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_EQ(nodeData.Get().GetMrpRetryIntervalIdle(), std::make_optional(1_ms32)); // Maximum strcpy(key, "SII"); strcpy(val, "3600000"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_EQ(nodeData.Get().GetMrpRetryIntervalIdle(), std::make_optional(3600000_ms32)); // Test no other fields were populated ResetRetryIntervalIdle(nodeData); EXPECT_TRUE(NodeDataIsEmpty(nodeData.Get())); // Invalid SII - negative value strcpy(key, "SII"); strcpy(val, "-1"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_FALSE(nodeData.Get().GetMrpRetryIntervalIdle().has_value()); // Invalid SII - greater than maximum strcpy(key, "SII"); strcpy(val, "3600001"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_FALSE(nodeData.Get().GetMrpRetryIntervalIdle().has_value()); // Invalid SII - much greater than maximum strcpy(key, "SII"); strcpy(val, "1095216660481"); // 0xFF00000001 == 1 (mod 2^32) FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_FALSE(nodeData.Get().GetMrpRetryIntervalIdle().has_value()); // Invalid SII - hexadecimal value strcpy(key, "SII"); strcpy(val, "0x20"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_FALSE(nodeData.Get().GetMrpRetryIntervalIdle().has_value()); // Invalid SII - leading zeros strcpy(key, "SII"); strcpy(val, "0700"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_FALSE(nodeData.Get().GetMrpRetryIntervalIdle().has_value()); // Invalid SII - text at the end strcpy(key, "SII"); strcpy(val, "123abc"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_FALSE(nodeData.Get().GetMrpRetryIntervalIdle().has_value()); } // Test SAI (formerly CRA) template void DiscoveredTxtFieldSessionActiveInterval() { char key[4]; char val[16]; DiscoveredNodeData nodeData; nodeData.Set(); CommonResolutionData & resolutionData = nodeData.Get(); // Minimum strcpy(key, "SAI"); strcpy(val, "1"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_EQ(nodeData.Get().GetMrpRetryIntervalActive(), std::make_optional(1_ms32)); // Maximum strcpy(key, "SAI"); strcpy(val, "3600000"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_EQ(nodeData.Get().GetMrpRetryIntervalActive(), std::make_optional(3600000_ms32)); // Test no other fields were populated ResetRetryIntervalActive(nodeData); EXPECT_TRUE(NodeDataIsEmpty(nodeData.Get())); // Invalid SAI - negative value strcpy(key, "SAI"); strcpy(val, "-1"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_FALSE(nodeData.Get().GetMrpRetryIntervalActive().has_value()); // Invalid SAI - greater than maximum strcpy(key, "SAI"); strcpy(val, "3600001"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_FALSE(nodeData.Get().GetMrpRetryIntervalActive().has_value()); // Invalid SAI - much greater than maximum strcpy(key, "SAI"); strcpy(val, "1095216660481"); // 0xFF00000001 == 1 (mod 2^32) FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_FALSE(nodeData.Get().GetMrpRetryIntervalActive().has_value()); // Invalid SAI - hexadecimal value strcpy(key, "SAI"); strcpy(val, "0x20"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_FALSE(nodeData.Get().GetMrpRetryIntervalActive().has_value()); // Invalid SAI - leading zeros strcpy(key, "SAI"); strcpy(val, "0700"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_FALSE(nodeData.Get().GetMrpRetryIntervalActive().has_value()); // Invalid SAI - text at the end strcpy(key, "SAI"); strcpy(val, "123abc"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_FALSE(nodeData.Get().GetMrpRetryIntervalActive().has_value()); } // Test SAT (Session Active Threshold) template void DiscoveredTxtFieldSessionActiveThreshold() { char key[4]; char val[16]; DiscoveredNodeData nodeData; nodeData.Set(); CommonResolutionData & resolutionData = nodeData.Get(); // Minimum strcpy(key, "SAT"); strcpy(val, "1"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_EQ(nodeData.Get().GetMrpRetryActiveThreshold(), std::make_optional(1_ms16)); // Maximum strcpy(key, "SAT"); strcpy(val, "65535"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_EQ(nodeData.Get().GetMrpRetryActiveThreshold(), std::make_optional(65535_ms16)); // Test no other fields were populated ResetRetryActiveThreshold(nodeData); EXPECT_TRUE(NodeDataIsEmpty(nodeData.Get())); // Invalid SAI - negative value strcpy(key, "SAT"); strcpy(val, "-1"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_FALSE(nodeData.Get().GetMrpRetryActiveThreshold().has_value()); // Invalid SAI - greater than maximum strcpy(key, "SAT"); strcpy(val, "65536"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_FALSE(nodeData.Get().GetMrpRetryActiveThreshold().has_value()); // Invalid SAT - much greater than maximum strcpy(key, "SAT"); strcpy(val, "1095216660481"); // 0xFF00000001 == 1 (mod 2^32) FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_FALSE(nodeData.Get().GetMrpRetryActiveThreshold().has_value()); // Invalid SAT - hexadecimal value strcpy(key, "SAT"); strcpy(val, "0x20"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_FALSE(nodeData.Get().GetMrpRetryActiveThreshold().has_value()); // Invalid SAT - leading zeros strcpy(key, "SAT"); strcpy(val, "0700"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_FALSE(nodeData.Get().GetMrpRetryActiveThreshold().has_value()); // Invalid SAT - text at the end strcpy(key, "SAT"); strcpy(val, "123abc"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_FALSE(nodeData.Get().GetMrpRetryActiveThreshold().has_value()); } // Test T (TCP support) template void DiscoveredTxtFieldTcpSupport() { char key[4]; char val[8]; DiscoveredNodeData nodeData; nodeData.Set(); CommonResolutionData & resolutionData = nodeData.Get(); // Neither TCP Client nor TCP Server are enabled strcpy(key, "T"); strcpy(val, "0"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_FALSE(nodeData.Get().supportsTcpServer); EXPECT_FALSE(nodeData.Get().supportsTcpClient); // Neither TCP Client nor TCP Server are enabled - ignoring first bit strcpy(key, "T"); strcpy(val, "1"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_FALSE(nodeData.Get().supportsTcpServer); EXPECT_FALSE(nodeData.Get().supportsTcpClient); // Supporting TCP Client only strcpy(key, "T"); strcpy(val, "2"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_TRUE(nodeData.Get().supportsTcpClient); EXPECT_FALSE(nodeData.Get().supportsTcpServer); // Supporting TCP Client only - ignoring first bit strcpy(key, "T"); strcpy(val, "3"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_TRUE(nodeData.Get().supportsTcpClient); EXPECT_FALSE(nodeData.Get().supportsTcpServer); // Supporting TCP Server only strcpy(key, "T"); strcpy(val, "4"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_FALSE(nodeData.Get().supportsTcpClient); EXPECT_TRUE(nodeData.Get().supportsTcpServer); // Supporting TCP Server only - ignoring first bit strcpy(key, "T"); strcpy(val, "5"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_FALSE(nodeData.Get().supportsTcpClient); EXPECT_TRUE(nodeData.Get().supportsTcpServer); // Supporting TCP Server and Client strcpy(key, "T"); strcpy(val, "6"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_TRUE(nodeData.Get().supportsTcpClient); EXPECT_TRUE(nodeData.Get().supportsTcpServer); // Supporting TCP Server and Client - ignoring first bit strcpy(key, "T"); strcpy(val, "7"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_TRUE(nodeData.Get().supportsTcpClient); EXPECT_TRUE(nodeData.Get().supportsTcpServer); // Invalid value, means neither TCP Client or Server are enabled strcpy(key, "T"); strcpy(val, "8"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_FALSE(nodeData.Get().supportsTcpClient); EXPECT_FALSE(nodeData.Get().supportsTcpServer); // Invalid value, means neither TCP Client or Server are enabled strcpy(key, "T"); strcpy(val, "asdf"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_FALSE(nodeData.Get().supportsTcpClient); EXPECT_FALSE(nodeData.Get().supportsTcpServer); // Test no other fields were populated nodeData.Get().supportsTcpClient = false; nodeData.Get().supportsTcpServer = false; EXPECT_TRUE(NodeDataIsEmpty(nodeData.Get())); } // Test ICD (ICD operation Mode) template void DiscoveredTxtFieldICDoperatesAsLIT() { char key[4]; char val[16]; DiscoveredNodeData nodeData; nodeData.Set(); CommonResolutionData & resolutionData = nodeData.Get(); // ICD is operating as a LIT device strcpy(key, "ICD"); strcpy(val, "1"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_EQ(nodeData.Get().isICDOperatingAsLIT, std::make_optional(true)); // Test no other fields were populated nodeData.Get().isICDOperatingAsLIT.reset(); EXPECT_TRUE(NodeDataIsEmpty(nodeData.Get())); // ICD is operating as a SIT device strcpy(key, "ICD"); strcpy(val, "0"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_EQ(nodeData.Get().isICDOperatingAsLIT, std::make_optional(false)); nodeData.Get().isICDOperatingAsLIT.reset(); EXPECT_TRUE(NodeDataIsEmpty(nodeData.Get())); // Invalid value, No key set strcpy(key, "ICD"); strcpy(val, "asdf"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_FALSE(nodeData.Get().isICDOperatingAsLIT.has_value()); } // Test IsDeviceTreatedAsSleepy() with CRI template void DiscoveredTestIsDeviceSessionIdle() { char key[4]; char val[32]; DiscoveredNodeData nodeData; nodeData.Set(); const ReliableMessageProtocolConfig defaultMRPConfig(CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL, CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL); CommonResolutionData & resolutionData = nodeData.Get(); // No key/val set, so the device can't be sleepy EXPECT_FALSE(nodeData.Get().IsDeviceTreatedAsSleepy(&defaultMRPConfig)); // If the interval is the default value, the device is not sleepy strcpy(key, "SII"); sprintf(val, "%d", static_cast(CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL.count())); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_FALSE(nodeData.Get().IsDeviceTreatedAsSleepy(&defaultMRPConfig)); // If the interval is greater than the default value, the device is sleepy sprintf(key, "SII"); sprintf(val, "%d", static_cast(CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL.count() + 1)); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_TRUE(nodeData.Get().IsDeviceTreatedAsSleepy(&defaultMRPConfig)); } // Test IsDeviceTreatedAsSleepy() with CRA template void DiscoveredTestIsDeviceSessionActive() { char key[4]; char val[32]; DiscoveredNodeData nodeData; nodeData.Set(); const ReliableMessageProtocolConfig defaultMRPConfig(CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL, CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL); CommonResolutionData & resolutionData = nodeData.Get(); // No key/val set, so the device can't be sleepy EXPECT_FALSE(nodeData.Get().IsDeviceTreatedAsSleepy(&defaultMRPConfig)); // If the interval is the default value, the device is not sleepy sprintf(key, "SAI"); sprintf(val, "%d", static_cast(CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL.count())); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_FALSE(nodeData.Get().IsDeviceTreatedAsSleepy(&defaultMRPConfig)); // If the interval is greater than the default value, the device is sleepy strcpy(key, "SAI"); sprintf(val, "%d", static_cast(CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL.count() + 1)); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), resolutionData); EXPECT_TRUE(nodeData.Get().IsDeviceTreatedAsSleepy(&defaultMRPConfig)); } // Test SAI (formally CRI) template void TxtFieldSessionIdleInterval() { char key[4]; char val[16]; NodeData nodeData; // Minimum strcpy(key, "SII"); strcpy(val, "1"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_EQ(nodeData.resolutionData.GetMrpRetryIntervalIdle(), std::make_optional(1_ms32)); // Maximum strcpy(key, "SII"); strcpy(val, "3600000"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_EQ(nodeData.resolutionData.GetMrpRetryIntervalIdle(), std::make_optional(3600000_ms32)); // Test no other fields were populated ResetRetryIntervalIdle(nodeData); EXPECT_TRUE(NodeDataIsEmpty(nodeData)); // Invalid SII - negative value strcpy(key, "SII"); strcpy(val, "-1"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryIntervalIdle().has_value()); // Invalid SII - greater than maximum strcpy(key, "SII"); strcpy(val, "3600001"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryIntervalIdle().has_value()); // Invalid SII - much greater than maximum strcpy(key, "SII"); strcpy(val, "1095216660481"); // 0xFF00000001 == 1 (mod 2^32) FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryIntervalIdle().has_value()); // Invalid SII - hexadecimal value strcpy(key, "SII"); strcpy(val, "0x20"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryIntervalIdle().has_value()); // Invalid SII - leading zeros strcpy(key, "SII"); strcpy(val, "0700"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryIntervalIdle().has_value()); // Invalid SII - text at the end strcpy(key, "SII"); strcpy(val, "123abc"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryIntervalIdle().has_value()); } TEST(TestTxtFields, TxtDiscoveredFieldMrpRetryIntervalIdle) { DiscoveredTxtFieldSessionIdleInterval(); } TEST(TestTxtFields, TxtResolvedFieldMrpRetryIntervalIdle) { TxtFieldSessionIdleInterval(); } // Test SAI (formerly CRA) template void TxtFieldSessionActiveInterval() { char key[4]; char val[16]; NodeData nodeData; // Minimum strcpy(key, "SAI"); strcpy(val, "1"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_EQ(nodeData.resolutionData.GetMrpRetryIntervalActive(), std::make_optional(1_ms32)); // Maximum strcpy(key, "SAI"); strcpy(val, "3600000"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_EQ(nodeData.resolutionData.GetMrpRetryIntervalActive(), std::make_optional(3600000_ms32)); // Test no other fields were populated ResetRetryIntervalActive(nodeData); EXPECT_TRUE(NodeDataIsEmpty(nodeData)); // Invalid SAI - negative value strcpy(key, "SAI"); strcpy(val, "-1"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryIntervalActive().has_value()); // Invalid SAI - greater than maximum strcpy(key, "SAI"); strcpy(val, "3600001"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryIntervalActive().has_value()); // Invalid SAI - much greater than maximum strcpy(key, "SAI"); strcpy(val, "1095216660481"); // 0xFF00000001 == 1 (mod 2^32) FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryIntervalActive().has_value()); // Invalid SAI - hexadecimal value strcpy(key, "SAI"); strcpy(val, "0x20"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryIntervalActive().has_value()); // Invalid SAI - leading zeros strcpy(key, "SAI"); strcpy(val, "0700"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryIntervalActive().has_value()); // Invalid SAI - text at the end strcpy(key, "SAI"); strcpy(val, "123abc"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryIntervalActive().has_value()); } TEST(TestTxtFields, TxtDiscoveredFieldMrpRetryIntervalActive) { DiscoveredTxtFieldSessionActiveInterval(); } TEST(TestTxtFields, TxtResolvedFieldMrpRetryIntervalActive) { TxtFieldSessionActiveInterval(); } // Test SAT (Session Active Threshold) template void TxtFieldSessionActiveThreshold() { char key[4]; char val[16]; NodeData nodeData; // Minimum strcpy(key, "SAT"); strcpy(val, "1"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_EQ(nodeData.resolutionData.GetMrpRetryActiveThreshold(), std::make_optional(1_ms16)); // Maximum strcpy(key, "SAT"); strcpy(val, "65535"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_EQ(nodeData.resolutionData.GetMrpRetryActiveThreshold(), std::make_optional(65535_ms16)); // Test no other fields were populated ResetRetryActiveThreshold(nodeData); EXPECT_TRUE(NodeDataIsEmpty(nodeData)); // Invalid SAI - negative value strcpy(key, "SAT"); strcpy(val, "-1"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryActiveThreshold().has_value()); // Invalid SAI - greater than maximum strcpy(key, "SAT"); strcpy(val, "65536"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryActiveThreshold().has_value()); // Invalid SAT - much greater than maximum strcpy(key, "SAT"); strcpy(val, "1095216660481"); // 0xFF00000001 == 1 (mod 2^32) FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryActiveThreshold().has_value()); // Invalid SAT - hexadecimal value strcpy(key, "SAT"); strcpy(val, "0x20"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryActiveThreshold().has_value()); // Invalid SAT - leading zeros strcpy(key, "SAT"); strcpy(val, "0700"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryActiveThreshold().has_value()); // Invalid SAT - text at the end strcpy(key, "SAT"); strcpy(val, "123abc"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_FALSE(nodeData.resolutionData.GetMrpRetryActiveThreshold().has_value()); } TEST(TestTxtFields, TxtDiscoveredFieldMrpRetryActiveThreshold) { DiscoveredTxtFieldSessionActiveThreshold(); } TEST(TestTxtFields, TxtResolvedFieldMrpRetryActiveThreshold) { TxtFieldSessionActiveThreshold(); } // Test T (TCP support) template void TxtFieldTcpSupport() { char key[4]; char val[8]; NodeData nodeData; // Neither TCP Client nor TCP Server are enabled strcpy(key, "T"); strcpy(val, "0"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_FALSE(nodeData.resolutionData.supportsTcpServer); EXPECT_FALSE(nodeData.resolutionData.supportsTcpClient); // Neither TCP Client nor TCP Server are enabled - ignoring first bit strcpy(key, "T"); strcpy(val, "1"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_FALSE(nodeData.resolutionData.supportsTcpServer); EXPECT_FALSE(nodeData.resolutionData.supportsTcpClient); // Supporting TCP Client only strcpy(key, "T"); strcpy(val, "2"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_FALSE(nodeData.resolutionData.supportsTcpServer); EXPECT_TRUE(nodeData.resolutionData.supportsTcpClient); // Supporting TCP Client only - ignoring first bit strcpy(key, "T"); strcpy(val, "3"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_FALSE(nodeData.resolutionData.supportsTcpServer); EXPECT_TRUE(nodeData.resolutionData.supportsTcpClient); // Supporting TCP Server only strcpy(key, "T"); strcpy(val, "4"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_TRUE(nodeData.resolutionData.supportsTcpServer); EXPECT_FALSE(nodeData.resolutionData.supportsTcpClient); // Supporting TCP Server only - ignoring first bit strcpy(key, "T"); strcpy(val, "5"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_TRUE(nodeData.resolutionData.supportsTcpServer); EXPECT_FALSE(nodeData.resolutionData.supportsTcpClient); // Supporting TCP Server and Client strcpy(key, "T"); strcpy(val, "6"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_TRUE(nodeData.resolutionData.supportsTcpServer); EXPECT_TRUE(nodeData.resolutionData.supportsTcpClient); // Supporting TCP Server and Client - ignoring first bit strcpy(key, "T"); strcpy(val, "7"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_TRUE(nodeData.resolutionData.supportsTcpServer); EXPECT_TRUE(nodeData.resolutionData.supportsTcpClient); // Invalid value, means neither TCP Client or Server are enabled strcpy(key, "T"); strcpy(val, "8"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_FALSE(nodeData.resolutionData.supportsTcpClient); EXPECT_FALSE(nodeData.resolutionData.supportsTcpServer); // Invalid value, means neither TCP Client or Server are enabled strcpy(key, "T"); strcpy(val, "asdf"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_FALSE(nodeData.resolutionData.supportsTcpClient); EXPECT_FALSE(nodeData.resolutionData.supportsTcpServer); // Test no other fields were populated nodeData.resolutionData.supportsTcpServer = false; nodeData.resolutionData.supportsTcpClient = false; EXPECT_TRUE(NodeDataIsEmpty(nodeData)); } TEST(TestTxtFields, TxtDiscoveredFieldTcpSupport) { DiscoveredTxtFieldTcpSupport(); } TEST(TestTxtFields, TxtResolvedFieldTcpSupport) { TxtFieldTcpSupport(); } // Test ICD (ICD operation Mode) template void TxtFieldICDoperatesAsLIT() { char key[4]; char val[16]; NodeData nodeData; // ICD is operating as a LIT device strcpy(key, "ICD"); strcpy(val, "1"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_TRUE(nodeData.resolutionData.isICDOperatingAsLIT.has_value()); EXPECT_TRUE(nodeData.resolutionData.isICDOperatingAsLIT.value_or(false)); // Test no other fields were populated nodeData.resolutionData.isICDOperatingAsLIT.reset(); EXPECT_TRUE(NodeDataIsEmpty(nodeData)); // ICD is operating as a SIT device strcpy(key, "ICD"); strcpy(val, "0"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_TRUE(nodeData.resolutionData.isICDOperatingAsLIT.has_value()); EXPECT_EQ(nodeData.resolutionData.isICDOperatingAsLIT.value_or(true), false); nodeData.resolutionData.isICDOperatingAsLIT.reset(); EXPECT_TRUE(NodeDataIsEmpty(nodeData)); // Invalid value, No key set strcpy(key, "ICD"); strcpy(val, "asdf"); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_EQ(nodeData.resolutionData.isICDOperatingAsLIT.has_value(), false); } TEST(TestTxtFields, TxtDiscoveredIsICDoperatingAsLIT) { DiscoveredTxtFieldICDoperatesAsLIT(); } TEST(TestTxtFields, TxtResolvedFieldICDoperatingAsLIT) { TxtFieldICDoperatesAsLIT(); } // Test IsDeviceTreatedAsSleepy() with CRI template void TestIsDeviceSessionIdle() { char key[4]; char val[32]; NodeData nodeData; const ReliableMessageProtocolConfig defaultMRPConfig(CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL, CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL); // No key/val set, so the device can't be sleepy EXPECT_FALSE(nodeData.resolutionData.IsDeviceTreatedAsSleepy(&defaultMRPConfig)); // If the interval is the default value, the device is not sleepy strcpy(key, "SII"); sprintf(val, "%d", static_cast(CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL.count())); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_FALSE(nodeData.resolutionData.IsDeviceTreatedAsSleepy(&defaultMRPConfig)); // If the interval is greater than the default value, the device is sleepy sprintf(key, "SII"); sprintf(val, "%d", static_cast(CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL.count() + 1)); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_TRUE(nodeData.resolutionData.IsDeviceTreatedAsSleepy(&defaultMRPConfig)); } TEST(TestTxtFields, TxtDiscoveredIsDeviceSessionIdle) { DiscoveredTestIsDeviceSessionIdle(); } TEST(TestTxtFields, TxtResolvedIsDeviceSessionIdle) { TestIsDeviceSessionIdle(); } // Test IsDeviceTreatedAsSleepy() with CRA template void TestIsDeviceSessionActive() { char key[4]; char val[32]; NodeData nodeData; const ReliableMessageProtocolConfig defaultMRPConfig(CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL, CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL); // No key/val set, so the device can't be sleepy EXPECT_FALSE(nodeData.resolutionData.IsDeviceTreatedAsSleepy(&defaultMRPConfig)); // If the interval is the default value, the device is not sleepy sprintf(key, "SAI"); sprintf(val, "%d", static_cast(CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL.count())); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_FALSE(nodeData.resolutionData.IsDeviceTreatedAsSleepy(&defaultMRPConfig)); // If the interval is greater than the default value, the device is sleepy strcpy(key, "SAI"); sprintf(val, "%d", static_cast(CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL.count() + 1)); FillNodeDataFromTxt(GetSpan(key), GetSpan(val), nodeData.resolutionData); EXPECT_TRUE(nodeData.resolutionData.IsDeviceTreatedAsSleepy(&defaultMRPConfig)); } TEST(TestTxtFields, TxtDiscoveredIsDeviceSessionActive) { DiscoveredTestIsDeviceSessionActive(); } TEST(TestTxtFields, TxtResolvedIsDeviceSessionActive) { TestIsDeviceSessionActive(); } } // namespace