[spinel] clear source match tables before recovery (#12222)

Radio recovery that does not fully reset the firmware leads to tables
filling up with duplicate entries. After a few resets, future resets no
longer work. Clearing the tables before inserting entries allows for
their state to be consistent during recovery.
This commit is contained in:
puddly
2026-01-15 23:21:54 -05:00
committed by GitHub
parent 5c9eeb1ce8
commit 5fd62a9acf
2 changed files with 32 additions and 0 deletions
+4
View File
@@ -2188,12 +2188,16 @@ void RadioSpinel::RestoreProperties(void)
otLinkGetFrameCounter(mInstance) + kFrameCounterGuard));
}
SuccessOrDie(Set(SPINEL_PROP_MAC_SRC_MATCH_SHORT_ADDRESSES, nullptr));
for (int i = 0; i < mSrcMatchShortEntryCount; ++i)
{
SuccessOrDie(
Insert(SPINEL_PROP_MAC_SRC_MATCH_SHORT_ADDRESSES, SPINEL_DATATYPE_UINT16_S, mSrcMatchShortEntries[i]));
}
SuccessOrDie(Set(SPINEL_PROP_MAC_SRC_MATCH_EXTENDED_ADDRESSES, nullptr));
for (int i = 0; i < mSrcMatchExtEntryCount; ++i)
{
SuccessOrDie(
+28
View File
@@ -490,3 +490,31 @@ TEST(RadioSpinelSrcMatch, shouldBeAbleToClearAllRadioSrcMatchExtEntres)
ASSERT_EQ(platform.SrcMatchCountExtEntries(), 0);
}
TEST(RadioSpinelSrcMatch, shouldNotDuplicateSrcMatchEntriesOnRestoreProperties)
{
constexpr uint16_t kTestShortAddr = 0x1234;
constexpr otExtAddress kTestExtAddr{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};
constexpr otExtAddress kTestExtAddrReversed{0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
FakeCoprocessorPlatform platform;
ASSERT_EQ(platform.mRadioSpinel.Enable(FakePlatform::CurrentInstance()), kErrorNone);
ASSERT_EQ(platform.mRadioSpinel.AddSrcMatchShortEntry(kTestShortAddr), kErrorNone);
ASSERT_EQ(platform.mRadioSpinel.AddSrcMatchExtEntry(kTestExtAddr), kErrorNone);
ASSERT_EQ(platform.SrcMatchCountShortEntries(), 1);
ASSERT_EQ(platform.SrcMatchCountExtEntries(), 1);
ASSERT_EQ(platform.SrcMatchHasShortEntry(kTestShortAddr), 1);
ASSERT_EQ(platform.SrcMatchHasExtEntry(kTestExtAddrReversed), 1);
// Simulate RCP recovery by calling RestoreProperties multiple times.
// Without clearing entries first, this would create duplicates.
platform.mRadioSpinel.RestoreProperties();
platform.mRadioSpinel.RestoreProperties();
ASSERT_EQ(platform.SrcMatchCountShortEntries(), 1);
ASSERT_EQ(platform.SrcMatchCountExtEntries(), 1);
ASSERT_EQ(platform.SrcMatchHasShortEntry(kTestShortAddr), 1);
ASSERT_EQ(platform.SrcMatchHasExtEntry(kTestExtAddrReversed), 1);
}