1*cfb92d14SAndroid Build Coastguard Worker /*
2*cfb92d14SAndroid Build Coastguard Worker * Copyright (c) 2016, The OpenThread Authors.
3*cfb92d14SAndroid Build Coastguard Worker * All rights reserved.
4*cfb92d14SAndroid Build Coastguard Worker *
5*cfb92d14SAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
6*cfb92d14SAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions are met:
7*cfb92d14SAndroid Build Coastguard Worker * 1. Redistributions of source code must retain the above copyright
8*cfb92d14SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
9*cfb92d14SAndroid Build Coastguard Worker * 2. Redistributions in binary form must reproduce the above copyright
10*cfb92d14SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer in the
11*cfb92d14SAndroid Build Coastguard Worker * documentation and/or other materials provided with the distribution.
12*cfb92d14SAndroid Build Coastguard Worker * 3. Neither the name of the copyright holder nor the
13*cfb92d14SAndroid Build Coastguard Worker * names of its contributors may be used to endorse or promote products
14*cfb92d14SAndroid Build Coastguard Worker * derived from this software without specific prior written permission.
15*cfb92d14SAndroid Build Coastguard Worker *
16*cfb92d14SAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17*cfb92d14SAndroid Build Coastguard Worker * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*cfb92d14SAndroid Build Coastguard Worker * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*cfb92d14SAndroid Build Coastguard Worker * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20*cfb92d14SAndroid Build Coastguard Worker * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*cfb92d14SAndroid Build Coastguard Worker * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*cfb92d14SAndroid Build Coastguard Worker * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*cfb92d14SAndroid Build Coastguard Worker * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*cfb92d14SAndroid Build Coastguard Worker * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*cfb92d14SAndroid Build Coastguard Worker * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*cfb92d14SAndroid Build Coastguard Worker * POSSIBILITY OF SUCH DAMAGE.
27*cfb92d14SAndroid Build Coastguard Worker */
28*cfb92d14SAndroid Build Coastguard Worker
29*cfb92d14SAndroid Build Coastguard Worker #include "test_platform.h"
30*cfb92d14SAndroid Build Coastguard Worker #include "test_util.h"
31*cfb92d14SAndroid Build Coastguard Worker
32*cfb92d14SAndroid Build Coastguard Worker #include "common/array.hpp"
33*cfb92d14SAndroid Build Coastguard Worker #include "common/code_utils.hpp"
34*cfb92d14SAndroid Build Coastguard Worker #include "thread/link_metrics.hpp"
35*cfb92d14SAndroid Build Coastguard Worker #include "thread/link_quality.hpp"
36*cfb92d14SAndroid Build Coastguard Worker
37*cfb92d14SAndroid Build Coastguard Worker namespace ot {
38*cfb92d14SAndroid Build Coastguard Worker
39*cfb92d14SAndroid Build Coastguard Worker static Instance *sInstance;
40*cfb92d14SAndroid Build Coastguard Worker
41*cfb92d14SAndroid Build Coastguard Worker enum
42*cfb92d14SAndroid Build Coastguard Worker {
43*cfb92d14SAndroid Build Coastguard Worker kMaxRssValue = 0,
44*cfb92d14SAndroid Build Coastguard Worker kMinRssValue = -128,
45*cfb92d14SAndroid Build Coastguard Worker
46*cfb92d14SAndroid Build Coastguard Worker kStringBuffferSize = 80,
47*cfb92d14SAndroid Build Coastguard Worker
48*cfb92d14SAndroid Build Coastguard Worker kRssAverageMaxDiff = 16,
49*cfb92d14SAndroid Build Coastguard Worker kNumRssAdds = 300,
50*cfb92d14SAndroid Build Coastguard Worker
51*cfb92d14SAndroid Build Coastguard Worker kRawAverageBitShift = 3,
52*cfb92d14SAndroid Build Coastguard Worker kRawAverageMultiple = (1 << kRawAverageBitShift),
53*cfb92d14SAndroid Build Coastguard Worker kRawAverageBitMask = (1 << kRawAverageBitShift) - 1,
54*cfb92d14SAndroid Build Coastguard Worker };
55*cfb92d14SAndroid Build Coastguard Worker
56*cfb92d14SAndroid Build Coastguard Worker #define MIN_RSS(_rss1, _rss2) (((_rss1) < (_rss2)) ? (_rss1) : (_rss2))
57*cfb92d14SAndroid Build Coastguard Worker #define MAX_RSS(_rss1, _rss2) (((_rss1) < (_rss2)) ? (_rss2) : (_rss1))
58*cfb92d14SAndroid Build Coastguard Worker #define ABS(value) (((value) >= 0) ? (value) : -(value))
59*cfb92d14SAndroid Build Coastguard Worker
60*cfb92d14SAndroid Build Coastguard Worker // This struct contains RSS values and test data for checking link quality info class.
61*cfb92d14SAndroid Build Coastguard Worker struct RssTestData
62*cfb92d14SAndroid Build Coastguard Worker {
63*cfb92d14SAndroid Build Coastguard Worker const int8_t *mRssList; // Array of RSS values.
64*cfb92d14SAndroid Build Coastguard Worker size_t mRssListSize; // Size of RSS list.
65*cfb92d14SAndroid Build Coastguard Worker uint8_t mExpectedLinkQuality; // Expected final link quality value.
66*cfb92d14SAndroid Build Coastguard Worker };
67*cfb92d14SAndroid Build Coastguard Worker
68*cfb92d14SAndroid Build Coastguard Worker int8_t sNoiseFloor = -100; // dBm
69*cfb92d14SAndroid Build Coastguard Worker
70*cfb92d14SAndroid Build Coastguard Worker // Check and verify the raw average RSS value to match the value from GetAverage().
VerifyRawRssValue(int8_t aAverage,uint16_t aRawValue)71*cfb92d14SAndroid Build Coastguard Worker void VerifyRawRssValue(int8_t aAverage, uint16_t aRawValue)
72*cfb92d14SAndroid Build Coastguard Worker {
73*cfb92d14SAndroid Build Coastguard Worker if (aAverage != Radio::kInvalidRssi)
74*cfb92d14SAndroid Build Coastguard Worker {
75*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(aAverage == -static_cast<int16_t>((aRawValue + (kRawAverageMultiple / 2)) >> kRawAverageBitShift),
76*cfb92d14SAndroid Build Coastguard Worker "Raw value does not match the average.");
77*cfb92d14SAndroid Build Coastguard Worker }
78*cfb92d14SAndroid Build Coastguard Worker else
79*cfb92d14SAndroid Build Coastguard Worker {
80*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(aRawValue == 0, "Raw value does not match the average.");
81*cfb92d14SAndroid Build Coastguard Worker }
82*cfb92d14SAndroid Build Coastguard Worker }
83*cfb92d14SAndroid Build Coastguard Worker
84*cfb92d14SAndroid Build Coastguard Worker // This function prints the values in the passed in link info instance. It is invoked as the final step in test-case.
PrintOutcome(LinkQualityInfo & aLinkInfo)85*cfb92d14SAndroid Build Coastguard Worker void PrintOutcome(LinkQualityInfo &aLinkInfo) { printf("%s -> PASS \n", aLinkInfo.ToInfoString().AsCString()); }
86*cfb92d14SAndroid Build Coastguard Worker
TestLinkQualityData(RssTestData aRssData)87*cfb92d14SAndroid Build Coastguard Worker void TestLinkQualityData(RssTestData aRssData)
88*cfb92d14SAndroid Build Coastguard Worker {
89*cfb92d14SAndroid Build Coastguard Worker LinkQualityInfo linkInfo;
90*cfb92d14SAndroid Build Coastguard Worker int8_t rss, ave, min, max;
91*cfb92d14SAndroid Build Coastguard Worker size_t i;
92*cfb92d14SAndroid Build Coastguard Worker
93*cfb92d14SAndroid Build Coastguard Worker sInstance = testInitInstance();
94*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(sInstance != nullptr);
95*cfb92d14SAndroid Build Coastguard Worker linkInfo.Init(*sInstance);
96*cfb92d14SAndroid Build Coastguard Worker
97*cfb92d14SAndroid Build Coastguard Worker printf("- - - - - - - - - - - - - - - - - -\n");
98*cfb92d14SAndroid Build Coastguard Worker linkInfo.Clear();
99*cfb92d14SAndroid Build Coastguard Worker min = kMinRssValue;
100*cfb92d14SAndroid Build Coastguard Worker max = kMaxRssValue;
101*cfb92d14SAndroid Build Coastguard Worker
102*cfb92d14SAndroid Build Coastguard Worker for (i = 0; i < aRssData.mRssListSize; i++)
103*cfb92d14SAndroid Build Coastguard Worker {
104*cfb92d14SAndroid Build Coastguard Worker rss = aRssData.mRssList[i];
105*cfb92d14SAndroid Build Coastguard Worker min = MIN_RSS(rss, min);
106*cfb92d14SAndroid Build Coastguard Worker max = MAX_RSS(rss, max);
107*cfb92d14SAndroid Build Coastguard Worker linkInfo.AddRss(rss);
108*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(linkInfo.GetLastRss() == rss);
109*cfb92d14SAndroid Build Coastguard Worker ave = linkInfo.GetAverageRss();
110*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(ave >= min, "GetAverageRss() is smaller than min value.");
111*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(ave <= max, "GetAverageRss() is larger than min value");
112*cfb92d14SAndroid Build Coastguard Worker VerifyRawRssValue(linkInfo.GetAverageRss(), linkInfo.GetAverageRssRaw());
113*cfb92d14SAndroid Build Coastguard Worker printf("%02u) AddRss(%4d): ", static_cast<unsigned int>(i), rss);
114*cfb92d14SAndroid Build Coastguard Worker PrintOutcome(linkInfo);
115*cfb92d14SAndroid Build Coastguard Worker }
116*cfb92d14SAndroid Build Coastguard Worker
117*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(linkInfo.GetLinkQuality() == aRssData.mExpectedLinkQuality);
118*cfb92d14SAndroid Build Coastguard Worker }
119*cfb92d14SAndroid Build Coastguard Worker
120*cfb92d14SAndroid Build Coastguard Worker // Check and verify the raw average RSS value to match the value from GetAverage().
VerifyRawRssValue(RssAverager & aRssAverager)121*cfb92d14SAndroid Build Coastguard Worker void VerifyRawRssValue(RssAverager &aRssAverager)
122*cfb92d14SAndroid Build Coastguard Worker {
123*cfb92d14SAndroid Build Coastguard Worker int8_t average = aRssAverager.GetAverage();
124*cfb92d14SAndroid Build Coastguard Worker uint16_t rawValue = aRssAverager.GetRaw();
125*cfb92d14SAndroid Build Coastguard Worker
126*cfb92d14SAndroid Build Coastguard Worker if (average != Radio::kInvalidRssi)
127*cfb92d14SAndroid Build Coastguard Worker {
128*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(average == -static_cast<int16_t>((rawValue + (kRawAverageMultiple / 2)) >> kRawAverageBitShift),
129*cfb92d14SAndroid Build Coastguard Worker "Raw value does not match the average.");
130*cfb92d14SAndroid Build Coastguard Worker }
131*cfb92d14SAndroid Build Coastguard Worker else
132*cfb92d14SAndroid Build Coastguard Worker {
133*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(rawValue == 0, "Raw value does not match the average.");
134*cfb92d14SAndroid Build Coastguard Worker }
135*cfb92d14SAndroid Build Coastguard Worker }
136*cfb92d14SAndroid Build Coastguard Worker
137*cfb92d14SAndroid Build Coastguard Worker // This function prints the values in the passed link info instance. It is invoked as the final step in test-case.
PrintOutcome(RssAverager & aRssAverager)138*cfb92d14SAndroid Build Coastguard Worker void PrintOutcome(RssAverager &aRssAverager) { printf("%s -> PASS\n", aRssAverager.ToString().AsCString()); }
139*cfb92d14SAndroid Build Coastguard Worker
GetRandomRss(void)140*cfb92d14SAndroid Build Coastguard Worker int8_t GetRandomRss(void)
141*cfb92d14SAndroid Build Coastguard Worker {
142*cfb92d14SAndroid Build Coastguard Worker uint32_t value;
143*cfb92d14SAndroid Build Coastguard Worker
144*cfb92d14SAndroid Build Coastguard Worker value = rand() % 128;
145*cfb92d14SAndroid Build Coastguard Worker return -static_cast<int8_t>(value);
146*cfb92d14SAndroid Build Coastguard Worker }
147*cfb92d14SAndroid Build Coastguard Worker
TestRssAveraging(void)148*cfb92d14SAndroid Build Coastguard Worker void TestRssAveraging(void)
149*cfb92d14SAndroid Build Coastguard Worker {
150*cfb92d14SAndroid Build Coastguard Worker RssAverager rssAverager;
151*cfb92d14SAndroid Build Coastguard Worker int8_t rss, rss2, ave;
152*cfb92d14SAndroid Build Coastguard Worker int16_t diff;
153*cfb92d14SAndroid Build Coastguard Worker size_t i, j, k;
154*cfb92d14SAndroid Build Coastguard Worker const int8_t rssValues[] = {kMinRssValue, -70, -40, -41, -10, kMaxRssValue};
155*cfb92d14SAndroid Build Coastguard Worker int16_t sum;
156*cfb92d14SAndroid Build Coastguard Worker
157*cfb92d14SAndroid Build Coastguard Worker //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
158*cfb92d14SAndroid Build Coastguard Worker // Values after initialization/reset.
159*cfb92d14SAndroid Build Coastguard Worker
160*cfb92d14SAndroid Build Coastguard Worker rssAverager.Clear();
161*cfb92d14SAndroid Build Coastguard Worker
162*cfb92d14SAndroid Build Coastguard Worker printf("\nAfter Clear: ");
163*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(rssAverager.GetAverage() == Radio::kInvalidRssi, "Initial value from GetAverage() is incorrect.");
164*cfb92d14SAndroid Build Coastguard Worker VerifyRawRssValue(rssAverager);
165*cfb92d14SAndroid Build Coastguard Worker PrintOutcome(rssAverager);
166*cfb92d14SAndroid Build Coastguard Worker
167*cfb92d14SAndroid Build Coastguard Worker //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
168*cfb92d14SAndroid Build Coastguard Worker // Adding a single value
169*cfb92d14SAndroid Build Coastguard Worker rss = -70;
170*cfb92d14SAndroid Build Coastguard Worker printf("AddRss(%d): ", rss);
171*cfb92d14SAndroid Build Coastguard Worker IgnoreError(rssAverager.Add(rss));
172*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(rssAverager.GetAverage() == rss, "GetAverage() failed after a single AddRss().");
173*cfb92d14SAndroid Build Coastguard Worker VerifyRawRssValue(rssAverager);
174*cfb92d14SAndroid Build Coastguard Worker PrintOutcome(rssAverager);
175*cfb92d14SAndroid Build Coastguard Worker
176*cfb92d14SAndroid Build Coastguard Worker //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
177*cfb92d14SAndroid Build Coastguard Worker // Clear
178*cfb92d14SAndroid Build Coastguard Worker
179*cfb92d14SAndroid Build Coastguard Worker printf("Clear(): ");
180*cfb92d14SAndroid Build Coastguard Worker rssAverager.Clear();
181*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(rssAverager.GetAverage() == Radio::kInvalidRssi, "GetAverage() after Clear() is incorrect.");
182*cfb92d14SAndroid Build Coastguard Worker VerifyRawRssValue(rssAverager);
183*cfb92d14SAndroid Build Coastguard Worker PrintOutcome(rssAverager);
184*cfb92d14SAndroid Build Coastguard Worker
185*cfb92d14SAndroid Build Coastguard Worker //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
186*cfb92d14SAndroid Build Coastguard Worker // Adding the same value many times.
187*cfb92d14SAndroid Build Coastguard Worker
188*cfb92d14SAndroid Build Coastguard Worker printf("- - - - - - - - - - - - - - - - - -\n");
189*cfb92d14SAndroid Build Coastguard Worker
190*cfb92d14SAndroid Build Coastguard Worker for (j = 0; j < sizeof(rssValues); j++)
191*cfb92d14SAndroid Build Coastguard Worker {
192*cfb92d14SAndroid Build Coastguard Worker rssAverager.Clear();
193*cfb92d14SAndroid Build Coastguard Worker rss = rssValues[j];
194*cfb92d14SAndroid Build Coastguard Worker printf("AddRss(%4d) %d times: ", rss, kNumRssAdds);
195*cfb92d14SAndroid Build Coastguard Worker
196*cfb92d14SAndroid Build Coastguard Worker for (i = 0; i < kNumRssAdds; i++)
197*cfb92d14SAndroid Build Coastguard Worker {
198*cfb92d14SAndroid Build Coastguard Worker IgnoreError(rssAverager.Add(rss));
199*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(rssAverager.GetAverage() == rss, "GetAverage() returned incorrect value.");
200*cfb92d14SAndroid Build Coastguard Worker VerifyRawRssValue(rssAverager);
201*cfb92d14SAndroid Build Coastguard Worker }
202*cfb92d14SAndroid Build Coastguard Worker
203*cfb92d14SAndroid Build Coastguard Worker PrintOutcome(rssAverager);
204*cfb92d14SAndroid Build Coastguard Worker }
205*cfb92d14SAndroid Build Coastguard Worker
206*cfb92d14SAndroid Build Coastguard Worker //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
207*cfb92d14SAndroid Build Coastguard Worker // Adding two RSS values:
208*cfb92d14SAndroid Build Coastguard Worker
209*cfb92d14SAndroid Build Coastguard Worker printf("- - - - - - - - - - - - - - - - - -\n");
210*cfb92d14SAndroid Build Coastguard Worker
211*cfb92d14SAndroid Build Coastguard Worker for (j = 0; j < sizeof(rssValues); j++)
212*cfb92d14SAndroid Build Coastguard Worker {
213*cfb92d14SAndroid Build Coastguard Worker rss = rssValues[j];
214*cfb92d14SAndroid Build Coastguard Worker
215*cfb92d14SAndroid Build Coastguard Worker for (k = 0; k < sizeof(rssValues); k++)
216*cfb92d14SAndroid Build Coastguard Worker {
217*cfb92d14SAndroid Build Coastguard Worker if (k == j)
218*cfb92d14SAndroid Build Coastguard Worker {
219*cfb92d14SAndroid Build Coastguard Worker continue;
220*cfb92d14SAndroid Build Coastguard Worker }
221*cfb92d14SAndroid Build Coastguard Worker
222*cfb92d14SAndroid Build Coastguard Worker rss2 = rssValues[k];
223*cfb92d14SAndroid Build Coastguard Worker rssAverager.Clear();
224*cfb92d14SAndroid Build Coastguard Worker IgnoreError(rssAverager.Add(rss));
225*cfb92d14SAndroid Build Coastguard Worker IgnoreError(rssAverager.Add(rss2));
226*cfb92d14SAndroid Build Coastguard Worker printf("AddRss(%4d), AddRss(%4d): ", rss, rss2);
227*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(rssAverager.GetAverage() == ((rss + rss2) >> 1), "GetAverage() returned incorrect value.");
228*cfb92d14SAndroid Build Coastguard Worker VerifyRawRssValue(rssAverager);
229*cfb92d14SAndroid Build Coastguard Worker PrintOutcome(rssAverager);
230*cfb92d14SAndroid Build Coastguard Worker }
231*cfb92d14SAndroid Build Coastguard Worker }
232*cfb92d14SAndroid Build Coastguard Worker
233*cfb92d14SAndroid Build Coastguard Worker //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
234*cfb92d14SAndroid Build Coastguard Worker // Adding one value many times and a different value once:
235*cfb92d14SAndroid Build Coastguard Worker
236*cfb92d14SAndroid Build Coastguard Worker printf("- - - - - - - - - - - - - - - - - -\n");
237*cfb92d14SAndroid Build Coastguard Worker
238*cfb92d14SAndroid Build Coastguard Worker for (j = 0; j < sizeof(rssValues); j++)
239*cfb92d14SAndroid Build Coastguard Worker {
240*cfb92d14SAndroid Build Coastguard Worker rss = rssValues[j];
241*cfb92d14SAndroid Build Coastguard Worker
242*cfb92d14SAndroid Build Coastguard Worker for (k = 0; k < sizeof(rssValues); k++)
243*cfb92d14SAndroid Build Coastguard Worker {
244*cfb92d14SAndroid Build Coastguard Worker if (k == j)
245*cfb92d14SAndroid Build Coastguard Worker {
246*cfb92d14SAndroid Build Coastguard Worker continue;
247*cfb92d14SAndroid Build Coastguard Worker }
248*cfb92d14SAndroid Build Coastguard Worker
249*cfb92d14SAndroid Build Coastguard Worker rss2 = rssValues[k];
250*cfb92d14SAndroid Build Coastguard Worker rssAverager.Clear();
251*cfb92d14SAndroid Build Coastguard Worker
252*cfb92d14SAndroid Build Coastguard Worker for (i = 0; i < kNumRssAdds; i++)
253*cfb92d14SAndroid Build Coastguard Worker {
254*cfb92d14SAndroid Build Coastguard Worker IgnoreError(rssAverager.Add(rss));
255*cfb92d14SAndroid Build Coastguard Worker }
256*cfb92d14SAndroid Build Coastguard Worker
257*cfb92d14SAndroid Build Coastguard Worker IgnoreError(rssAverager.Add(rss2));
258*cfb92d14SAndroid Build Coastguard Worker printf("AddRss(%4d) %d times, AddRss(%4d): ", rss, kNumRssAdds, rss2);
259*cfb92d14SAndroid Build Coastguard Worker ave = rssAverager.GetAverage();
260*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(ave >= MIN_RSS(rss, rss2), "GetAverage() returned incorrect value.");
261*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(ave <= MAX_RSS(rss, rss2), "GetAverage() returned incorrect value.");
262*cfb92d14SAndroid Build Coastguard Worker VerifyRawRssValue(rssAverager);
263*cfb92d14SAndroid Build Coastguard Worker PrintOutcome(rssAverager);
264*cfb92d14SAndroid Build Coastguard Worker }
265*cfb92d14SAndroid Build Coastguard Worker }
266*cfb92d14SAndroid Build Coastguard Worker
267*cfb92d14SAndroid Build Coastguard Worker //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
268*cfb92d14SAndroid Build Coastguard Worker // Adding two alternating values many times:
269*cfb92d14SAndroid Build Coastguard Worker
270*cfb92d14SAndroid Build Coastguard Worker printf("- - - - - - - - - - - - - - - - - -\n");
271*cfb92d14SAndroid Build Coastguard Worker
272*cfb92d14SAndroid Build Coastguard Worker for (j = 0; j < sizeof(rssValues); j++)
273*cfb92d14SAndroid Build Coastguard Worker {
274*cfb92d14SAndroid Build Coastguard Worker rss = rssValues[j];
275*cfb92d14SAndroid Build Coastguard Worker
276*cfb92d14SAndroid Build Coastguard Worker for (k = 0; k < sizeof(rssValues); k++)
277*cfb92d14SAndroid Build Coastguard Worker {
278*cfb92d14SAndroid Build Coastguard Worker if (k == j)
279*cfb92d14SAndroid Build Coastguard Worker {
280*cfb92d14SAndroid Build Coastguard Worker continue;
281*cfb92d14SAndroid Build Coastguard Worker }
282*cfb92d14SAndroid Build Coastguard Worker
283*cfb92d14SAndroid Build Coastguard Worker rss2 = rssValues[k];
284*cfb92d14SAndroid Build Coastguard Worker rssAverager.Clear();
285*cfb92d14SAndroid Build Coastguard Worker
286*cfb92d14SAndroid Build Coastguard Worker for (i = 0; i < kNumRssAdds; i++)
287*cfb92d14SAndroid Build Coastguard Worker {
288*cfb92d14SAndroid Build Coastguard Worker IgnoreError(rssAverager.Add(rss));
289*cfb92d14SAndroid Build Coastguard Worker IgnoreError(rssAverager.Add(rss2));
290*cfb92d14SAndroid Build Coastguard Worker ave = rssAverager.GetAverage();
291*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(ave >= MIN_RSS(rss, rss2), "GetAverage() is smaller than min value.");
292*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(ave <= MAX_RSS(rss, rss2), "GetAverage() is larger than min value.");
293*cfb92d14SAndroid Build Coastguard Worker diff = ave;
294*cfb92d14SAndroid Build Coastguard Worker diff -= (rss + rss2) >> 1;
295*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(ABS(diff) <= kRssAverageMaxDiff, "GetAverage() is incorrect");
296*cfb92d14SAndroid Build Coastguard Worker VerifyRawRssValue(rssAverager);
297*cfb92d14SAndroid Build Coastguard Worker }
298*cfb92d14SAndroid Build Coastguard Worker
299*cfb92d14SAndroid Build Coastguard Worker printf("[AddRss(%4d), AddRss(%4d)] %d times: ", rss, rss2, kNumRssAdds);
300*cfb92d14SAndroid Build Coastguard Worker PrintOutcome(rssAverager);
301*cfb92d14SAndroid Build Coastguard Worker }
302*cfb92d14SAndroid Build Coastguard Worker }
303*cfb92d14SAndroid Build Coastguard Worker
304*cfb92d14SAndroid Build Coastguard Worker //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
305*cfb92d14SAndroid Build Coastguard Worker // For the first 8 values the average should be the arithmetic mean.
306*cfb92d14SAndroid Build Coastguard Worker
307*cfb92d14SAndroid Build Coastguard Worker printf("- - - - - - - - - - - - - - - - - -\n");
308*cfb92d14SAndroid Build Coastguard Worker
309*cfb92d14SAndroid Build Coastguard Worker for (i = 0; i < 1000; i++)
310*cfb92d14SAndroid Build Coastguard Worker {
311*cfb92d14SAndroid Build Coastguard Worker double mean;
312*cfb92d14SAndroid Build Coastguard Worker
313*cfb92d14SAndroid Build Coastguard Worker rssAverager.Clear();
314*cfb92d14SAndroid Build Coastguard Worker sum = 0;
315*cfb92d14SAndroid Build Coastguard Worker
316*cfb92d14SAndroid Build Coastguard Worker printf("\n");
317*cfb92d14SAndroid Build Coastguard Worker
318*cfb92d14SAndroid Build Coastguard Worker for (j = 1; j <= 8; j++)
319*cfb92d14SAndroid Build Coastguard Worker {
320*cfb92d14SAndroid Build Coastguard Worker rss = GetRandomRss();
321*cfb92d14SAndroid Build Coastguard Worker IgnoreError(rssAverager.Add(rss));
322*cfb92d14SAndroid Build Coastguard Worker sum += rss;
323*cfb92d14SAndroid Build Coastguard Worker mean = static_cast<double>(sum) / static_cast<double>(j);
324*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(ABS(rssAverager.GetAverage() - mean) < 1, "Average does not match the arithmetic mean!");
325*cfb92d14SAndroid Build Coastguard Worker VerifyRawRssValue(rssAverager);
326*cfb92d14SAndroid Build Coastguard Worker printf("AddRss(%4d) sum=%-5d, mean=%-8.2f RssAverager=", rss, sum, mean);
327*cfb92d14SAndroid Build Coastguard Worker PrintOutcome(rssAverager);
328*cfb92d14SAndroid Build Coastguard Worker }
329*cfb92d14SAndroid Build Coastguard Worker }
330*cfb92d14SAndroid Build Coastguard Worker }
331*cfb92d14SAndroid Build Coastguard Worker
TestLinkQualityCalculations(void)332*cfb92d14SAndroid Build Coastguard Worker void TestLinkQualityCalculations(void)
333*cfb92d14SAndroid Build Coastguard Worker {
334*cfb92d14SAndroid Build Coastguard Worker const int8_t rssList1[] = {-81, -80, -79, -78, -76, -80, -77, -75, -77, -76, -77, -74};
335*cfb92d14SAndroid Build Coastguard Worker const RssTestData rssData1 = {
336*cfb92d14SAndroid Build Coastguard Worker rssList1, // mRssList
337*cfb92d14SAndroid Build Coastguard Worker sizeof(rssList1), // mRssListSize
338*cfb92d14SAndroid Build Coastguard Worker 3 // mExpectedLinkQuality
339*cfb92d14SAndroid Build Coastguard Worker };
340*cfb92d14SAndroid Build Coastguard Worker
341*cfb92d14SAndroid Build Coastguard Worker const int8_t rssList2[] = {-90, -80, -85};
342*cfb92d14SAndroid Build Coastguard Worker const RssTestData rssData2 = {
343*cfb92d14SAndroid Build Coastguard Worker rssList2, // mRssList
344*cfb92d14SAndroid Build Coastguard Worker sizeof(rssList2), // mRssListSize
345*cfb92d14SAndroid Build Coastguard Worker 2 // mExpectedLinkQuality
346*cfb92d14SAndroid Build Coastguard Worker };
347*cfb92d14SAndroid Build Coastguard Worker
348*cfb92d14SAndroid Build Coastguard Worker const int8_t rssList3[] = {-95, -96, -98, -99, -100, -100, -98, -99, -100, -100, -100, -100, -100};
349*cfb92d14SAndroid Build Coastguard Worker const RssTestData rssData3 = {
350*cfb92d14SAndroid Build Coastguard Worker rssList3, // mRssList
351*cfb92d14SAndroid Build Coastguard Worker sizeof(rssList3), // mRssListSize
352*cfb92d14SAndroid Build Coastguard Worker 0 // mExpectedLinkQuality
353*cfb92d14SAndroid Build Coastguard Worker };
354*cfb92d14SAndroid Build Coastguard Worker
355*cfb92d14SAndroid Build Coastguard Worker const int8_t rssList4[] = {-75, -100, -100, -100, -100, -100, -95, -92, -93, -94, -93, -93};
356*cfb92d14SAndroid Build Coastguard Worker const RssTestData rssData4 = {
357*cfb92d14SAndroid Build Coastguard Worker rssList4, // mRssList
358*cfb92d14SAndroid Build Coastguard Worker sizeof(rssList4), // mRssListSize
359*cfb92d14SAndroid Build Coastguard Worker 1 // mExpectedLinkQuality
360*cfb92d14SAndroid Build Coastguard Worker };
361*cfb92d14SAndroid Build Coastguard Worker
362*cfb92d14SAndroid Build Coastguard Worker TestLinkQualityData(rssData1);
363*cfb92d14SAndroid Build Coastguard Worker TestLinkQualityData(rssData2);
364*cfb92d14SAndroid Build Coastguard Worker TestLinkQualityData(rssData3);
365*cfb92d14SAndroid Build Coastguard Worker TestLinkQualityData(rssData4);
366*cfb92d14SAndroid Build Coastguard Worker }
367*cfb92d14SAndroid Build Coastguard Worker
TestSuccessRateTracker(void)368*cfb92d14SAndroid Build Coastguard Worker void TestSuccessRateTracker(void)
369*cfb92d14SAndroid Build Coastguard Worker {
370*cfb92d14SAndroid Build Coastguard Worker SuccessRateTracker rateTracker;
371*cfb92d14SAndroid Build Coastguard Worker uint16_t sampleCount;
372*cfb92d14SAndroid Build Coastguard Worker
373*cfb92d14SAndroid Build Coastguard Worker const uint16_t kMaxSamples = 5000;
374*cfb92d14SAndroid Build Coastguard Worker
375*cfb92d14SAndroid Build Coastguard Worker const uint16_t kMaxRate = SuccessRateTracker::kMaxRateValue;
376*cfb92d14SAndroid Build Coastguard Worker const double kMaxError = 1.0; // Max permitted error in percentage
377*cfb92d14SAndroid Build Coastguard Worker const uint16_t kWeightLimit[] = {64, 128, 256, 300, 512, 810, 900};
378*cfb92d14SAndroid Build Coastguard Worker
379*cfb92d14SAndroid Build Coastguard Worker printf("\nTesting SuccessRateTracker\n");
380*cfb92d14SAndroid Build Coastguard Worker
381*cfb92d14SAndroid Build Coastguard Worker rateTracker.Clear();
382*cfb92d14SAndroid Build Coastguard Worker
383*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(rateTracker.GetSuccessRate() == kMaxRate, "SuccessRateTracker: Initial value incorrect");
384*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(rateTracker.GetFailureRate() == 0, "SuccessRateTracker: Initial value incorrect");
385*cfb92d14SAndroid Build Coastguard Worker
386*cfb92d14SAndroid Build Coastguard Worker // Adding all success
387*cfb92d14SAndroid Build Coastguard Worker for (sampleCount = 1; sampleCount < kMaxSamples; sampleCount++)
388*cfb92d14SAndroid Build Coastguard Worker {
389*cfb92d14SAndroid Build Coastguard Worker rateTracker.AddSample(true, sampleCount);
390*cfb92d14SAndroid Build Coastguard Worker
391*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(rateTracker.GetSuccessRate() == kMaxRate, "SuccessRateTracker: incorrect rate all success case");
392*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(rateTracker.GetFailureRate() == 0, "SuccessRateTracker: incorrect rate in all success case");
393*cfb92d14SAndroid Build Coastguard Worker }
394*cfb92d14SAndroid Build Coastguard Worker
395*cfb92d14SAndroid Build Coastguard Worker rateTracker.Clear();
396*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(rateTracker.GetSuccessRate() == kMaxRate, "SuccessRateTracker: Rate incorrect after reset");
397*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(rateTracker.GetFailureRate() == 0, "SuccessRateTracker: Rate incorrect after reset");
398*cfb92d14SAndroid Build Coastguard Worker
399*cfb92d14SAndroid Build Coastguard Worker // Adding all failures
400*cfb92d14SAndroid Build Coastguard Worker for (sampleCount = 1; sampleCount < kMaxRate; sampleCount++)
401*cfb92d14SAndroid Build Coastguard Worker {
402*cfb92d14SAndroid Build Coastguard Worker rateTracker.AddSample(false, sampleCount);
403*cfb92d14SAndroid Build Coastguard Worker
404*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(rateTracker.GetSuccessRate() == 0, "SuccessRateTracker: rate incorrect all failure case");
405*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(rateTracker.GetFailureRate() == kMaxRate,
406*cfb92d14SAndroid Build Coastguard Worker "SuccessRateTracker: rate incorrect in all failure case");
407*cfb92d14SAndroid Build Coastguard Worker }
408*cfb92d14SAndroid Build Coastguard Worker
409*cfb92d14SAndroid Build Coastguard Worker // Adding success/failure at different rates and checking the RateTracker rate for every sample
410*cfb92d14SAndroid Build Coastguard Worker
411*cfb92d14SAndroid Build Coastguard Worker for (uint16_t testRound = 0; testRound < GetArrayLength(kWeightLimit) * 2; testRound++)
412*cfb92d14SAndroid Build Coastguard Worker {
413*cfb92d14SAndroid Build Coastguard Worker uint16_t weightLimit;
414*cfb92d14SAndroid Build Coastguard Worker bool reverseLogic;
415*cfb92d14SAndroid Build Coastguard Worker double maxDiff = 0;
416*cfb92d14SAndroid Build Coastguard Worker
417*cfb92d14SAndroid Build Coastguard Worker // Reverse the logic (add success instead of failure) on even test rounds
418*cfb92d14SAndroid Build Coastguard Worker reverseLogic = ((testRound % 2) == 0);
419*cfb92d14SAndroid Build Coastguard Worker
420*cfb92d14SAndroid Build Coastguard Worker // Select a different weight limit based on the current test round
421*cfb92d14SAndroid Build Coastguard Worker weightLimit = kWeightLimit[testRound / 2];
422*cfb92d14SAndroid Build Coastguard Worker
423*cfb92d14SAndroid Build Coastguard Worker printf("TestRound %02d, weightLimit %3d, reverseLogic %d ", testRound, weightLimit, reverseLogic);
424*cfb92d14SAndroid Build Coastguard Worker
425*cfb92d14SAndroid Build Coastguard Worker for (uint16_t period = 1; period < 101; period++)
426*cfb92d14SAndroid Build Coastguard Worker {
427*cfb92d14SAndroid Build Coastguard Worker uint16_t failureCount = 0;
428*cfb92d14SAndroid Build Coastguard Worker
429*cfb92d14SAndroid Build Coastguard Worker rateTracker.Clear();
430*cfb92d14SAndroid Build Coastguard Worker
431*cfb92d14SAndroid Build Coastguard Worker for (sampleCount = 1; sampleCount < kMaxSamples; sampleCount++)
432*cfb92d14SAndroid Build Coastguard Worker {
433*cfb92d14SAndroid Build Coastguard Worker double expectedRate;
434*cfb92d14SAndroid Build Coastguard Worker double failureRate;
435*cfb92d14SAndroid Build Coastguard Worker double diff;
436*cfb92d14SAndroid Build Coastguard Worker bool isSuccess = ((sampleCount % period) == 0);
437*cfb92d14SAndroid Build Coastguard Worker uint16_t weight;
438*cfb92d14SAndroid Build Coastguard Worker
439*cfb92d14SAndroid Build Coastguard Worker if (reverseLogic)
440*cfb92d14SAndroid Build Coastguard Worker {
441*cfb92d14SAndroid Build Coastguard Worker isSuccess = !isSuccess;
442*cfb92d14SAndroid Build Coastguard Worker }
443*cfb92d14SAndroid Build Coastguard Worker
444*cfb92d14SAndroid Build Coastguard Worker weight = sampleCount;
445*cfb92d14SAndroid Build Coastguard Worker
446*cfb92d14SAndroid Build Coastguard Worker if (weight > weightLimit)
447*cfb92d14SAndroid Build Coastguard Worker {
448*cfb92d14SAndroid Build Coastguard Worker weight = weightLimit;
449*cfb92d14SAndroid Build Coastguard Worker }
450*cfb92d14SAndroid Build Coastguard Worker
451*cfb92d14SAndroid Build Coastguard Worker rateTracker.AddSample(isSuccess, weight);
452*cfb92d14SAndroid Build Coastguard Worker
453*cfb92d14SAndroid Build Coastguard Worker if (!isSuccess)
454*cfb92d14SAndroid Build Coastguard Worker {
455*cfb92d14SAndroid Build Coastguard Worker failureCount++;
456*cfb92d14SAndroid Build Coastguard Worker }
457*cfb92d14SAndroid Build Coastguard Worker
458*cfb92d14SAndroid Build Coastguard Worker // Calculate the failure rate from rateTracker and expected rate.
459*cfb92d14SAndroid Build Coastguard Worker
460*cfb92d14SAndroid Build Coastguard Worker failureRate = static_cast<double>(rateTracker.GetFailureRate()) * 100.0 / kMaxRate; // in percent
461*cfb92d14SAndroid Build Coastguard Worker expectedRate = static_cast<double>(failureCount) * 100.0 / sampleCount; // in percent
462*cfb92d14SAndroid Build Coastguard Worker
463*cfb92d14SAndroid Build Coastguard Worker diff = failureRate - expectedRate;
464*cfb92d14SAndroid Build Coastguard Worker diff = ABS(diff);
465*cfb92d14SAndroid Build Coastguard Worker
466*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(diff <= kMaxError, "SuccessRateTracker: rate does not match expected value");
467*cfb92d14SAndroid Build Coastguard Worker
468*cfb92d14SAndroid Build Coastguard Worker if (diff > maxDiff)
469*cfb92d14SAndroid Build Coastguard Worker {
470*cfb92d14SAndroid Build Coastguard Worker maxDiff = diff;
471*cfb92d14SAndroid Build Coastguard Worker }
472*cfb92d14SAndroid Build Coastguard Worker }
473*cfb92d14SAndroid Build Coastguard Worker }
474*cfb92d14SAndroid Build Coastguard Worker
475*cfb92d14SAndroid Build Coastguard Worker printf(" MaxDiff = %.3f%%-> PASS\n", maxDiff);
476*cfb92d14SAndroid Build Coastguard Worker }
477*cfb92d14SAndroid Build Coastguard Worker }
478*cfb92d14SAndroid Build Coastguard Worker
479*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
480*cfb92d14SAndroid Build Coastguard Worker
481*cfb92d14SAndroid Build Coastguard Worker class UnitTester
482*cfb92d14SAndroid Build Coastguard Worker {
483*cfb92d14SAndroid Build Coastguard Worker public:
TestLinkMetricsScaling(void)484*cfb92d14SAndroid Build Coastguard Worker static void TestLinkMetricsScaling(void)
485*cfb92d14SAndroid Build Coastguard Worker {
486*cfb92d14SAndroid Build Coastguard Worker printf("\nTestLinkMetricsScaling\n");
487*cfb92d14SAndroid Build Coastguard Worker
488*cfb92d14SAndroid Build Coastguard Worker // Test Link Margin scaling from [0,130] -> [0, 255]
489*cfb92d14SAndroid Build Coastguard Worker
490*cfb92d14SAndroid Build Coastguard Worker for (uint8_t linkMargin = 0; linkMargin <= 130; linkMargin++)
491*cfb92d14SAndroid Build Coastguard Worker {
492*cfb92d14SAndroid Build Coastguard Worker double scaled = 255.0 / 130.0 * linkMargin;
493*cfb92d14SAndroid Build Coastguard Worker uint8_t scaledAsU8 = static_cast<uint8_t>(scaled + 0.5);
494*cfb92d14SAndroid Build Coastguard Worker
495*cfb92d14SAndroid Build Coastguard Worker printf("\nLinkMargin : %-3u -> Scaled : %.1f (rounded:%u)", linkMargin, scaled, scaledAsU8);
496*cfb92d14SAndroid Build Coastguard Worker
497*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(LinkMetrics::ScaleLinkMarginToRawValue(linkMargin) == scaledAsU8);
498*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(LinkMetrics::ScaleRawValueToLinkMargin(scaledAsU8) == linkMargin);
499*cfb92d14SAndroid Build Coastguard Worker }
500*cfb92d14SAndroid Build Coastguard Worker
501*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(LinkMetrics::ScaleLinkMarginToRawValue(131) == 255);
502*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(LinkMetrics::ScaleLinkMarginToRawValue(150) == 255);
503*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(LinkMetrics::ScaleLinkMarginToRawValue(255) == 255);
504*cfb92d14SAndroid Build Coastguard Worker
505*cfb92d14SAndroid Build Coastguard Worker // Test RSSI scaling from [-130, 0] -> [0, 255]
506*cfb92d14SAndroid Build Coastguard Worker
507*cfb92d14SAndroid Build Coastguard Worker for (int8_t rssi = -128; rssi <= 0; rssi++)
508*cfb92d14SAndroid Build Coastguard Worker {
509*cfb92d14SAndroid Build Coastguard Worker double scaled = 255.0 / 130.0 * (rssi + 130.0);
510*cfb92d14SAndroid Build Coastguard Worker uint8_t scaledAsU8 = static_cast<uint8_t>(scaled + 0.5);
511*cfb92d14SAndroid Build Coastguard Worker
512*cfb92d14SAndroid Build Coastguard Worker printf("\nRSSI : %-3d -> Scaled :%.1f (rounded:%u)", rssi, scaled, scaledAsU8);
513*cfb92d14SAndroid Build Coastguard Worker
514*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(LinkMetrics::ScaleRssiToRawValue(rssi) == scaledAsU8);
515*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(LinkMetrics::ScaleRawValueToRssi(scaledAsU8) == rssi);
516*cfb92d14SAndroid Build Coastguard Worker }
517*cfb92d14SAndroid Build Coastguard Worker
518*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(LinkMetrics::ScaleRssiToRawValue(1) == 255);
519*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(LinkMetrics::ScaleRssiToRawValue(10) == 255);
520*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(LinkMetrics::ScaleRssiToRawValue(127) == 255);
521*cfb92d14SAndroid Build Coastguard Worker
522*cfb92d14SAndroid Build Coastguard Worker // Test corner case of ScaleRawValueToRssi
523*cfb92d14SAndroid Build Coastguard Worker for (uint8_t rawValue = 0; rawValue < 2; rawValue++)
524*cfb92d14SAndroid Build Coastguard Worker {
525*cfb92d14SAndroid Build Coastguard Worker int8_t rssi = LinkMetrics::ScaleRawValueToRssi(rawValue);
526*cfb92d14SAndroid Build Coastguard Worker printf("\nRaw Value: %u -> RSSI : %-3d", rawValue, rssi);
527*cfb92d14SAndroid Build Coastguard Worker }
528*cfb92d14SAndroid Build Coastguard Worker }
529*cfb92d14SAndroid Build Coastguard Worker };
530*cfb92d14SAndroid Build Coastguard Worker
531*cfb92d14SAndroid Build Coastguard Worker #endif
532*cfb92d14SAndroid Build Coastguard Worker
533*cfb92d14SAndroid Build Coastguard Worker } // namespace ot
534*cfb92d14SAndroid Build Coastguard Worker
main(void)535*cfb92d14SAndroid Build Coastguard Worker int main(void)
536*cfb92d14SAndroid Build Coastguard Worker {
537*cfb92d14SAndroid Build Coastguard Worker ot::TestRssAveraging();
538*cfb92d14SAndroid Build Coastguard Worker ot::TestLinkQualityCalculations();
539*cfb92d14SAndroid Build Coastguard Worker ot::TestSuccessRateTracker();
540*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
541*cfb92d14SAndroid Build Coastguard Worker ot::UnitTester::TestLinkMetricsScaling();
542*cfb92d14SAndroid Build Coastguard Worker #endif
543*cfb92d14SAndroid Build Coastguard Worker
544*cfb92d14SAndroid Build Coastguard Worker printf("\nAll tests passed\n");
545*cfb92d14SAndroid Build Coastguard Worker return 0;
546*cfb92d14SAndroid Build Coastguard Worker }
547