• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2024, The OpenThread Authors.
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions are met:
7  *  1. Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  *  2. Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *  3. Neither the name of the copyright holder nor the
13  *     names of its contributors may be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  *  POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <gmock/gmock.h>
30 #include <gtest/gtest.h>
31 
32 #include <openthread/platform/radio.h>
33 
34 #include "common/error.hpp"
35 #include "gmock/gmock.h"
36 #include "mac/mac_frame.hpp"
37 #include "mac/mac_types.hpp"
38 
39 #include "fake_coprocessor_platform.hpp"
40 #include "fake_platform.hpp"
41 
42 using namespace ot;
43 
44 using ::testing::AnyNumber;
45 using ::testing::Truly;
46 
TEST(RadioSpinelTransmit,shouldPassDesiredTxPowerToRadioPlatform)47 TEST(RadioSpinelTransmit, shouldPassDesiredTxPowerToRadioPlatform)
48 {
49     class MockPlatform : public FakeCoprocessorPlatform
50     {
51     public:
52         MOCK_METHOD(otError, Transmit, (otRadioFrame * aFrame), (override));
53     };
54 
55     MockPlatform platform;
56 
57     constexpr Mac::PanId kSrcPanId  = 0x1234;
58     constexpr Mac::PanId kDstPanId  = 0x4321;
59     constexpr uint8_t    kDstAddr[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};
60     constexpr uint16_t   kSrcAddr   = 0xac00;
61     constexpr int8_t     kTxPower   = 100;
62 
63     uint8_t      frameBuffer[OT_RADIO_FRAME_MAX_SIZE];
64     Mac::TxFrame txFrame{};
65 
66     txFrame.mPsdu = frameBuffer;
67 
68     {
69         Mac::TxFrame::Info frameInfo;
70 
71         frameInfo.mType    = Mac::Frame::kTypeData;
72         frameInfo.mVersion = Mac::Frame::kVersion2006;
73         frameInfo.mAddrs.mSource.SetShort(kSrcAddr);
74         frameInfo.mAddrs.mDestination.SetExtended(kDstAddr);
75         frameInfo.mPanIds.SetSource(kSrcPanId);
76         frameInfo.mPanIds.SetDestination(kDstPanId);
77         frameInfo.mSecurityLevel = Mac::Frame::kSecurityEncMic32;
78 
79         frameInfo.PrepareHeadersIn(txFrame);
80     }
81 
82     txFrame.mInfo.mTxInfo.mTxPower = kTxPower;
83     txFrame.mChannel               = 11;
84 
85     EXPECT_CALL(platform, Transmit(Truly([](otRadioFrame *aFrame) -> bool {
86                     Mac::Frame &frame = *static_cast<Mac::Frame *>(aFrame);
87                     return frame.mInfo.mTxInfo.mTxPower == kTxPower;
88                 })))
89         .Times(1);
90 
91     ASSERT_EQ(platform.mRadioSpinel.Enable(FakePlatform::CurrentInstance()), kErrorNone);
92     ASSERT_EQ(platform.mRadioSpinel.Transmit(txFrame), kErrorNone);
93 
94     platform.GoInMs(1000);
95 }
96 
TEST(RadioSpinelTransmit,shouldCauseSwitchingToRxChannelAfterTxDone)97 TEST(RadioSpinelTransmit, shouldCauseSwitchingToRxChannelAfterTxDone)
98 {
99     FakeCoprocessorPlatform platform;
100 
101     constexpr Mac::PanId kSrcPanId  = 0x1234;
102     constexpr Mac::PanId kDstPanId  = 0x4321;
103     constexpr uint8_t    kDstAddr[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};
104     constexpr uint16_t   kSrcAddr   = 0xac00;
105     constexpr int8_t     kTxPower   = 100;
106 
107     uint8_t      frameBuffer[OT_RADIO_FRAME_MAX_SIZE];
108     Mac::TxFrame txFrame;
109 
110     txFrame.mPsdu = frameBuffer;
111 
112     {
113         Mac::TxFrame::Info frameInfo;
114 
115         frameInfo.mType    = Mac::Frame::kTypeData;
116         frameInfo.mVersion = Mac::Frame::kVersion2006;
117         frameInfo.mAddrs.mSource.SetShort(kSrcAddr);
118         frameInfo.mAddrs.mDestination.SetExtended(kDstAddr);
119         frameInfo.mPanIds.SetSource(kSrcPanId);
120         frameInfo.mPanIds.SetDestination(kDstPanId);
121         frameInfo.mSecurityLevel = Mac::Frame::kSecurityEncMic32;
122 
123         frameInfo.PrepareHeadersIn(txFrame);
124     }
125 
126     txFrame.mInfo.mTxInfo.mTxPower              = kTxPower;
127     txFrame.mChannel                            = 11;
128     txFrame.mInfo.mTxInfo.mRxChannelAfterTxDone = 25;
129 
130     ASSERT_EQ(platform.mRadioSpinel.Enable(FakePlatform::CurrentInstance()), kErrorNone);
131     ASSERT_EQ(platform.mRadioSpinel.Transmit(txFrame), kErrorNone);
132     platform.GoInMs(1000);
133     EXPECT_EQ(platform.GetReceiveChannel(), 25);
134 }
135 
TEST(RadioSpinelTransmit,shouldSkipCsmaCaWhenDisabled)136 TEST(RadioSpinelTransmit, shouldSkipCsmaCaWhenDisabled)
137 {
138     class MockPlatform : public FakeCoprocessorPlatform
139     {
140     public:
141         MOCK_METHOD(otError, Transmit, (otRadioFrame * aFrame), (override));
142         MOCK_METHOD(otError, Receive, (uint8_t aChannel), (override));
143     };
144 
145     MockPlatform platform;
146 
147     constexpr Mac::PanId kSrcPanId  = 0x1234;
148     constexpr Mac::PanId kDstPanId  = 0x4321;
149     constexpr uint8_t    kDstAddr[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};
150     constexpr uint16_t   kSrcAddr   = 0xac00;
151     constexpr int8_t     kTxPower   = 100;
152 
153     uint8_t      frameBuffer[OT_RADIO_FRAME_MAX_SIZE];
154     Mac::TxFrame txFrame{};
155 
156     txFrame.mPsdu = frameBuffer;
157 
158     {
159         Mac::TxFrame::Info frameInfo;
160 
161         frameInfo.mType    = Mac::Frame::kTypeData;
162         frameInfo.mVersion = Mac::Frame::kVersion2006;
163         frameInfo.mAddrs.mSource.SetShort(kSrcAddr);
164         frameInfo.mAddrs.mDestination.SetExtended(kDstAddr);
165         frameInfo.mPanIds.SetSource(kSrcPanId);
166         frameInfo.mPanIds.SetDestination(kDstPanId);
167         frameInfo.mSecurityLevel = Mac::Frame::kSecurityEncMic32;
168 
169         frameInfo.PrepareHeadersIn(txFrame);
170     }
171 
172     txFrame.mInfo.mTxInfo.mCsmaCaEnabled = false;
173     txFrame.mChannel                     = 11;
174 
175     EXPECT_CALL(platform, Transmit(Truly([](otRadioFrame *aFrame) -> bool {
176                     Mac::Frame &frame = *static_cast<Mac::Frame *>(aFrame);
177                     return frame.mInfo.mTxInfo.mCsmaCaEnabled == false;
178                 })))
179         .Times(1);
180 
181     EXPECT_CALL(platform, Receive).Times(AnyNumber());
182     // Receive(11) will be called exactly once to prepare for TX because the fake platform doesn't support sleep-to-tx
183     // capability.
184     EXPECT_CALL(platform, Receive(11)).Times(1);
185 
186     ASSERT_EQ(platform.mRadioSpinel.Enable(FakePlatform::CurrentInstance()), kErrorNone);
187     ASSERT_EQ(platform.mRadioSpinel.Transmit(txFrame), kErrorNone);
188 
189     platform.GoInMs(1000);
190 }
191 
TEST(RadioSpinelTransmit,shouldPerformCsmaCaWhenEnabled)192 TEST(RadioSpinelTransmit, shouldPerformCsmaCaWhenEnabled)
193 {
194     class MockPlatform : public FakeCoprocessorPlatform
195     {
196     public:
197         MOCK_METHOD(otError, Transmit, (otRadioFrame * aFrame), (override));
198         MOCK_METHOD(otError, Receive, (uint8_t aChannel), (override));
199     };
200 
201     MockPlatform platform;
202 
203     constexpr Mac::PanId kSrcPanId  = 0x1234;
204     constexpr Mac::PanId kDstPanId  = 0x4321;
205     constexpr uint8_t    kDstAddr[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};
206     constexpr uint16_t   kSrcAddr   = 0xac00;
207     constexpr int8_t     kTxPower   = 100;
208 
209     uint8_t      frameBuffer[OT_RADIO_FRAME_MAX_SIZE];
210     Mac::TxFrame txFrame{};
211 
212     txFrame.mPsdu = frameBuffer;
213 
214     {
215         Mac::TxFrame::Info frameInfo;
216 
217         frameInfo.mType    = Mac::Frame::kTypeData;
218         frameInfo.mVersion = Mac::Frame::kVersion2006;
219         frameInfo.mAddrs.mSource.SetShort(kSrcAddr);
220         frameInfo.mAddrs.mDestination.SetExtended(kDstAddr);
221         frameInfo.mPanIds.SetSource(kSrcPanId);
222         frameInfo.mPanIds.SetDestination(kDstPanId);
223         frameInfo.mSecurityLevel = Mac::Frame::kSecurityEncMic32;
224 
225         frameInfo.PrepareHeadersIn(txFrame);
226     }
227 
228     txFrame.mInfo.mTxInfo.mCsmaCaEnabled   = true;
229     txFrame.mInfo.mTxInfo.mMaxCsmaBackoffs = 1;
230     txFrame.mChannel                       = 11;
231 
232     EXPECT_CALL(platform, Transmit(Truly([](otRadioFrame *aFrame) -> bool {
233                     Mac::Frame &frame = *static_cast<Mac::Frame *>(aFrame);
234                     return frame.mInfo.mTxInfo.mCsmaCaEnabled == true;
235                 })))
236         .Times(1);
237 
238     // Receive(11) will be called exactly twice:
239     // 1. one time to prepare for TX because the fake platform doesn't support sleep-to-tx capability.
240     // 2. one time in CSMA backoff because rx-on-when-idle is true.
241     EXPECT_CALL(platform, Receive(11)).Times(2);
242 
243     ASSERT_EQ(platform.mRadioSpinel.Enable(FakePlatform::CurrentInstance()), kErrorNone);
244     ASSERT_EQ(platform.mRadioSpinel.Transmit(txFrame), kErrorNone);
245 
246     platform.GoInMs(1000);
247 }
248 
TEST(RadioSpinelTransmit,shouldNotCauseSwitchingToRxAfterTxDoneIfNotRxOnWhenIdle)249 TEST(RadioSpinelTransmit, shouldNotCauseSwitchingToRxAfterTxDoneIfNotRxOnWhenIdle)
250 {
251     FakeCoprocessorPlatform platform;
252 
253     constexpr Mac::PanId kSrcPanId  = 0x1234;
254     constexpr Mac::PanId kDstPanId  = 0x4321;
255     constexpr uint8_t    kDstAddr[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};
256     constexpr uint16_t   kSrcAddr   = 0xac00;
257     constexpr int8_t     kTxPower   = 100;
258 
259     uint8_t      frameBuffer[OT_RADIO_FRAME_MAX_SIZE];
260     Mac::TxFrame txFrame;
261 
262     txFrame.mPsdu = frameBuffer;
263 
264     {
265         Mac::TxFrame::Info frameInfo;
266 
267         frameInfo.mType    = Mac::Frame::kTypeData;
268         frameInfo.mVersion = Mac::Frame::kVersion2006;
269         frameInfo.mAddrs.mSource.SetShort(kSrcAddr);
270         frameInfo.mAddrs.mDestination.SetExtended(kDstAddr);
271         frameInfo.mPanIds.SetSource(kSrcPanId);
272         frameInfo.mPanIds.SetDestination(kDstPanId);
273         frameInfo.mSecurityLevel = Mac::Frame::kSecurityEncMic32;
274 
275         frameInfo.PrepareHeadersIn(txFrame);
276     }
277 
278     txFrame.mInfo.mTxInfo.mTxPower              = kTxPower;
279     txFrame.mChannel                            = 11;
280     txFrame.mInfo.mTxInfo.mRxChannelAfterTxDone = 25;
281 
282     ASSERT_EQ(platform.mRadioSpinel.Enable(FakePlatform::CurrentInstance()), kErrorNone);
283     ASSERT_EQ(platform.mRadioSpinel.Receive(11), kErrorNone);
284     ASSERT_EQ(platform.mRadioSpinel.SetRxOnWhenIdle(false), kErrorNone);
285     ASSERT_EQ(platform.mRadioSpinel.Transmit(txFrame), kErrorNone);
286     platform.GoInMs(1000);
287     EXPECT_EQ(platform.GetReceiveChannel(), 11);
288 }
289 
TEST(RadioSpinelReceiveAt,shouldReceiveAtGiveRadioTime)290 TEST(RadioSpinelReceiveAt, shouldReceiveAtGiveRadioTime)
291 {
292     class MockPlatform : public FakeCoprocessorPlatform
293     {
294     public:
295         MOCK_METHOD(otError, ReceiveAt, (uint8_t aChannel, uint32_t aStart, uint32_t aDuration), (override));
296     };
297 
298     MockPlatform platform;
299 
300     ON_CALL(platform, ReceiveAt)
301         .WillByDefault([&platform](uint8_t aChannel, uint32_t aStart, uint32_t aDuration) -> otError {
302             return platform.FakePlatform::ReceiveAt(aChannel, aStart, aDuration);
303         });
304 
305     EXPECT_CALL(platform, ReceiveAt).Times(1);
306 
307     ASSERT_EQ(platform.mRadioSpinel.Enable(FakePlatform::CurrentInstance()), kErrorNone);
308     ASSERT_EQ(platform.mRadioSpinel.SetRxOnWhenIdle(false), kErrorNone);
309     ASSERT_EQ(platform.mRadioSpinel.ReceiveAt(100000, 10000, 11), kErrorNone);
310     platform.GoInUs(100000);
311     EXPECT_EQ(platform.GetReceiveChannel(), 0);
312     platform.GoInUs(1);
313     EXPECT_EQ(platform.GetReceiveChannel(), 11);
314     platform.GoInUs(10000);
315     EXPECT_EQ(platform.GetReceiveChannel(), 0);
316 }
317 
TEST(RadioSpinelTransmit,shouldSkipCsmaBackoffWhenCsmaCaIsEnabledAndMaxBackoffsIsZero)318 TEST(RadioSpinelTransmit, shouldSkipCsmaBackoffWhenCsmaCaIsEnabledAndMaxBackoffsIsZero)
319 {
320     class MockPlatform : public FakeCoprocessorPlatform
321     {
322     public:
323         MOCK_METHOD(otError, Transmit, (otRadioFrame * aFrame), (override));
324         MOCK_METHOD(otError, Receive, (uint8_t aChannel), (override));
325     };
326 
327     MockPlatform platform;
328 
329     constexpr Mac::PanId kSrcPanId  = 0x1234;
330     constexpr Mac::PanId kDstPanId  = 0x4321;
331     constexpr uint8_t    kDstAddr[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};
332     constexpr uint16_t   kSrcAddr   = 0xac00;
333     constexpr int8_t     kTxPower   = 100;
334 
335     uint8_t      frameBuffer[OT_RADIO_FRAME_MAX_SIZE];
336     Mac::TxFrame txFrame{};
337 
338     txFrame.mPsdu = frameBuffer;
339 
340     {
341         Mac::TxFrame::Info frameInfo;
342 
343         frameInfo.mType    = Mac::Frame::kTypeData;
344         frameInfo.mVersion = Mac::Frame::kVersion2006;
345         frameInfo.mAddrs.mSource.SetShort(kSrcAddr);
346         frameInfo.mAddrs.mDestination.SetExtended(kDstAddr);
347         frameInfo.mPanIds.SetSource(kSrcPanId);
348         frameInfo.mPanIds.SetDestination(kDstPanId);
349         frameInfo.mSecurityLevel = Mac::Frame::kSecurityEncMic32;
350 
351         frameInfo.PrepareHeadersIn(txFrame);
352     }
353 
354     txFrame.mInfo.mTxInfo.mCsmaCaEnabled   = true;
355     txFrame.mInfo.mTxInfo.mMaxCsmaBackoffs = 0;
356     txFrame.mChannel                       = 11;
357 
358     EXPECT_CALL(platform, Transmit(Truly([](otRadioFrame *aFrame) -> bool {
359                     Mac::Frame &frame = *static_cast<Mac::Frame *>(aFrame);
360                     return frame.mInfo.mTxInfo.mCsmaCaEnabled == true && frame.mInfo.mTxInfo.mMaxCsmaBackoffs == 0;
361                 })))
362         .Times(1);
363 
364     EXPECT_CALL(platform, Receive).Times(AnyNumber());
365     // Receive(11) will be called exactly once to prepare for TX because the fake platform doesn't support sleep-to-tx
366     // capability.
367     EXPECT_CALL(platform, Receive(11)).Times(1);
368 
369     ASSERT_EQ(platform.mRadioSpinel.Enable(FakePlatform::CurrentInstance()), kErrorNone);
370     ASSERT_EQ(platform.mRadioSpinel.Transmit(txFrame), kErrorNone);
371 
372     platform.GoInMs(1000);
373 }
374 
TEST(RadioSpinelSrcMatch,shouldBeAbleToEnableRadioSrcMatch)375 TEST(RadioSpinelSrcMatch, shouldBeAbleToEnableRadioSrcMatch)
376 {
377     FakeCoprocessorPlatform platform;
378 
379     platform.SrcMatchEnable(false);
380     ASSERT_EQ(platform.mRadioSpinel.Enable(FakePlatform::CurrentInstance()), kErrorNone);
381     ASSERT_EQ(platform.mRadioSpinel.EnableSrcMatch(true), kErrorNone);
382     ASSERT_EQ(platform.SrcMatchIsEnabled(), true);
383 }
384 
TEST(RadioSpinelSrcMatch,shouldBeAbleToDisableRadioSrcMatch)385 TEST(RadioSpinelSrcMatch, shouldBeAbleToDisableRadioSrcMatch)
386 {
387     FakeCoprocessorPlatform platform;
388 
389     platform.SrcMatchEnable(true);
390     ASSERT_EQ(platform.mRadioSpinel.Enable(FakePlatform::CurrentInstance()), kErrorNone);
391     ASSERT_EQ(platform.mRadioSpinel.EnableSrcMatch(false), kErrorNone);
392     ASSERT_EQ(platform.SrcMatchIsEnabled(), false);
393 }
394 
TEST(RadioSpinelSrcMatch,shouldBeAbleToAddRadioSrcMatchShortEntry)395 TEST(RadioSpinelSrcMatch, shouldBeAbleToAddRadioSrcMatchShortEntry)
396 {
397     constexpr uint16_t      kTestShortAddr = 0x1234;
398     FakeCoprocessorPlatform platform;
399 
400     platform.SrcMatchEnable(true);
401 
402     ASSERT_EQ(platform.SrcMatchHasShortEntry(kTestShortAddr), 0);
403 
404     ASSERT_EQ(platform.mRadioSpinel.Enable(FakePlatform::CurrentInstance()), kErrorNone);
405     ASSERT_EQ(platform.mRadioSpinel.AddSrcMatchShortEntry(kTestShortAddr), kErrorNone);
406 
407     ASSERT_EQ(platform.SrcMatchHasShortEntry(kTestShortAddr), 1);
408 }
409 
TEST(RadioSpinelSrcMatch,shouldBeAbleToClearRadioSrcMatchShortEntry)410 TEST(RadioSpinelSrcMatch, shouldBeAbleToClearRadioSrcMatchShortEntry)
411 {
412     constexpr uint16_t      kTestShortAddr = 0x1234;
413     FakeCoprocessorPlatform platform;
414 
415     platform.SrcMatchEnable(true);
416     platform.SrcMatchAddShortEntry(kTestShortAddr);
417 
418     ASSERT_EQ(platform.SrcMatchHasShortEntry(kTestShortAddr), 1);
419 
420     ASSERT_EQ(platform.mRadioSpinel.Enable(FakePlatform::CurrentInstance()), kErrorNone);
421     ASSERT_EQ(platform.mRadioSpinel.ClearSrcMatchShortEntry(kTestShortAddr), kErrorNone);
422 
423     ASSERT_EQ(platform.SrcMatchHasShortEntry(kTestShortAddr), 0);
424 }
425 
TEST(RadioSpinelSrcMatch,shouldBeAbleToAddRadioSrcMatchExtEntry)426 TEST(RadioSpinelSrcMatch, shouldBeAbleToAddRadioSrcMatchExtEntry)
427 {
428     constexpr otExtAddress  kTestExtAddr{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};
429     constexpr otExtAddress  kTestExtAddrReversed{0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
430     FakeCoprocessorPlatform platform;
431 
432     platform.SrcMatchEnable(true);
433     platform.SrcMatchClearExtEntries();
434 
435     ASSERT_EQ(platform.SrcMatchHasExtEntry(kTestExtAddr), 0);
436     ASSERT_EQ(platform.SrcMatchHasExtEntry(kTestExtAddrReversed), 0);
437 
438     ASSERT_EQ(platform.mRadioSpinel.Enable(FakePlatform::CurrentInstance()), kErrorNone);
439     ASSERT_EQ(platform.mRadioSpinel.AddSrcMatchExtEntry(kTestExtAddr), kErrorNone);
440 
441     ASSERT_EQ(platform.SrcMatchHasExtEntry(kTestExtAddr), 0);
442     ASSERT_EQ(platform.SrcMatchHasExtEntry(kTestExtAddrReversed), 1);
443 }
444 
TEST(RadioSpinelSrcMatch,shouldBeAbleToClearRadioSrcMatchExtEntry)445 TEST(RadioSpinelSrcMatch, shouldBeAbleToClearRadioSrcMatchExtEntry)
446 {
447     constexpr otExtAddress  kTestExtAddr{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};
448     constexpr otExtAddress  kTestExtAddrReversed{0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
449     FakeCoprocessorPlatform platform;
450 
451     platform.SrcMatchEnable(true);
452     platform.SrcMatchAddExtEntry(kTestExtAddrReversed);
453 
454     ASSERT_EQ(platform.SrcMatchHasExtEntry(kTestExtAddrReversed), 1);
455 
456     ASSERT_EQ(platform.mRadioSpinel.Enable(FakePlatform::CurrentInstance()), kErrorNone);
457     ASSERT_EQ(platform.mRadioSpinel.ClearSrcMatchExtEntry(kTestExtAddr), kErrorNone);
458 
459     ASSERT_EQ(platform.SrcMatchHasExtEntry(kTestExtAddrReversed), 0);
460 }
461 
TEST(RadioSpinelSrcMatch,shouldBeAbleToClearAllRadioSrcMatchShortEntres)462 TEST(RadioSpinelSrcMatch, shouldBeAbleToClearAllRadioSrcMatchShortEntres)
463 {
464     constexpr uint16_t      kTestShortAddr = 0x1234;
465     FakeCoprocessorPlatform platform;
466 
467     platform.SrcMatchEnable(true);
468     platform.SrcMatchAddShortEntry(kTestShortAddr);
469 
470     ASSERT_EQ(platform.SrcMatchHasShortEntry(kTestShortAddr), 1);
471 
472     ASSERT_EQ(platform.mRadioSpinel.Enable(FakePlatform::CurrentInstance()), kErrorNone);
473     ASSERT_EQ(platform.mRadioSpinel.ClearSrcMatchShortEntries(), kErrorNone);
474 
475     ASSERT_EQ(platform.SrcMatchCountShortEntries(), 0);
476 }
477 
TEST(RadioSpinelSrcMatch,shouldBeAbleToClearAllRadioSrcMatchExtEntres)478 TEST(RadioSpinelSrcMatch, shouldBeAbleToClearAllRadioSrcMatchExtEntres)
479 {
480     constexpr otExtAddress  kTestExtAddrReversed{0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11};
481     FakeCoprocessorPlatform platform;
482 
483     platform.SrcMatchEnable(true);
484     platform.SrcMatchAddExtEntry(kTestExtAddrReversed);
485 
486     ASSERT_EQ(platform.SrcMatchHasExtEntry(kTestExtAddrReversed), 1);
487 
488     ASSERT_EQ(platform.mRadioSpinel.Enable(FakePlatform::CurrentInstance()), kErrorNone);
489     ASSERT_EQ(platform.mRadioSpinel.ClearSrcMatchExtEntries(), kErrorNone);
490 
491     ASSERT_EQ(platform.SrcMatchCountExtEntries(), 0);
492 }
493