xref: /aosp_15_r20/external/openthread/tests/unit/test_mle.cpp (revision cfb92d1480a9e65faed56933e9c12405f45898b4)
1 /*
2  *  Copyright (c) 2023, 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 <openthread/config.h>
30 
31 #include "test_platform.h"
32 #include "test_util.hpp"
33 
34 #include "common/num_utils.hpp"
35 #include "thread/mle_types.hpp"
36 
37 namespace ot {
38 
39 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MLE_DEVICE_PROPERTY_LEADER_WEIGHT_ENABLE
40 
TestDefaultDeviceProperties(void)41 void TestDefaultDeviceProperties(void)
42 {
43     Instance                 *instance;
44     const otDeviceProperties *props;
45     uint8_t                   weight;
46 
47     instance = static_cast<Instance *>(testInitInstance());
48     VerifyOrQuit(instance != nullptr);
49 
50     props = otThreadGetDeviceProperties(instance);
51 
52     VerifyOrQuit(props->mPowerSupply == OPENTHREAD_CONFIG_DEVICE_POWER_SUPPLY);
53     VerifyOrQuit(!props->mSupportsCcm);
54     VerifyOrQuit(!props->mIsUnstable);
55     VerifyOrQuit(props->mLeaderWeightAdjustment == OPENTHREAD_CONFIG_MLE_DEFAULT_LEADER_WEIGHT_ADJUSTMENT);
56 #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
57     VerifyOrQuit(props->mIsBorderRouter);
58 #else
59     VerifyOrQuit(!props->mIsBorderRouter);
60 #endif
61 
62     weight = 64;
63 
64     switch (props->mPowerSupply)
65     {
66     case OT_POWER_SUPPLY_BATTERY:
67         weight -= 8;
68         break;
69     case OT_POWER_SUPPLY_EXTERNAL:
70         break;
71     case OT_POWER_SUPPLY_EXTERNAL_STABLE:
72         weight += 4;
73         break;
74     case OT_POWER_SUPPLY_EXTERNAL_UNSTABLE:
75         weight -= 4;
76         break;
77     }
78 
79     weight += props->mIsBorderRouter ? 1 : 0;
80 
81     VerifyOrQuit(otThreadGetLocalLeaderWeight(instance) == weight);
82 
83     printf("TestDefaultDeviceProperties passed\n");
84 }
85 
CompareDevicePropertiess(const otDeviceProperties & aFirst,const otDeviceProperties & aSecond)86 void CompareDevicePropertiess(const otDeviceProperties &aFirst, const otDeviceProperties &aSecond)
87 {
88     static constexpr int8_t kMinAdjustment = -16;
89     static constexpr int8_t kMaxAdjustment = +16;
90 
91     VerifyOrQuit(aFirst.mPowerSupply == aSecond.mPowerSupply);
92     VerifyOrQuit(aFirst.mIsBorderRouter == aSecond.mIsBorderRouter);
93     VerifyOrQuit(aFirst.mSupportsCcm == aSecond.mSupportsCcm);
94     VerifyOrQuit(aFirst.mIsUnstable == aSecond.mIsUnstable);
95     VerifyOrQuit(Clamp(aFirst.mLeaderWeightAdjustment, kMinAdjustment, kMaxAdjustment) ==
96                  Clamp(aSecond.mLeaderWeightAdjustment, kMinAdjustment, kMaxAdjustment));
97 }
98 
TestLeaderWeightCalculation(void)99 void TestLeaderWeightCalculation(void)
100 {
101     struct TestCase
102     {
103         otDeviceProperties mDeviceProperties;
104         uint8_t            mExpectedLeaderWeight;
105     };
106 
107     static const TestCase kTestCases[] = {
108         {{OT_POWER_SUPPLY_BATTERY, false, false, false, 0}, 56},
109         {{OT_POWER_SUPPLY_EXTERNAL, false, false, false, 0}, 64},
110         {{OT_POWER_SUPPLY_EXTERNAL_STABLE, false, false, false, 0}, 68},
111         {{OT_POWER_SUPPLY_EXTERNAL_UNSTABLE, false, false, false, 0}, 60},
112 
113         {{OT_POWER_SUPPLY_BATTERY, true, false, false, 0}, 57},
114         {{OT_POWER_SUPPLY_EXTERNAL, true, false, false, 0}, 65},
115         {{OT_POWER_SUPPLY_EXTERNAL_STABLE, true, false, false, 0}, 69},
116         {{OT_POWER_SUPPLY_EXTERNAL_UNSTABLE, true, false, false, 0}, 61},
117 
118         {{OT_POWER_SUPPLY_BATTERY, true, true, false, 0}, 64},
119         {{OT_POWER_SUPPLY_EXTERNAL, true, true, false, 0}, 72},
120         {{OT_POWER_SUPPLY_EXTERNAL_STABLE, true, true, false, 0}, 76},
121         {{OT_POWER_SUPPLY_EXTERNAL_UNSTABLE, true, true, false, 0}, 68},
122 
123         // Check when `mIsUnstable` is set.
124         {{OT_POWER_SUPPLY_BATTERY, false, false, true, 0}, 56},
125         {{OT_POWER_SUPPLY_EXTERNAL, false, false, true, 0}, 60},
126         {{OT_POWER_SUPPLY_EXTERNAL_STABLE, false, false, true, 0}, 64},
127         {{OT_POWER_SUPPLY_EXTERNAL_UNSTABLE, false, false, true, 0}, 60},
128 
129         {{OT_POWER_SUPPLY_BATTERY, true, false, true, 0}, 57},
130         {{OT_POWER_SUPPLY_EXTERNAL, true, false, true, 0}, 61},
131         {{OT_POWER_SUPPLY_EXTERNAL_STABLE, true, false, true, 0}, 65},
132         {{OT_POWER_SUPPLY_EXTERNAL_UNSTABLE, true, false, true, 0}, 61},
133 
134         // Include non-zero `mLeaderWeightAdjustment`.
135         {{OT_POWER_SUPPLY_BATTERY, true, false, false, 10}, 67},
136         {{OT_POWER_SUPPLY_EXTERNAL, true, false, false, 10}, 75},
137         {{OT_POWER_SUPPLY_EXTERNAL_STABLE, true, false, false, 10}, 79},
138         {{OT_POWER_SUPPLY_EXTERNAL_UNSTABLE, true, false, false, 10}, 71},
139 
140         {{OT_POWER_SUPPLY_BATTERY, false, false, false, -10}, 46},
141         {{OT_POWER_SUPPLY_EXTERNAL, false, false, false, -10}, 54},
142         {{OT_POWER_SUPPLY_EXTERNAL_STABLE, false, false, false, -10}, 58},
143         {{OT_POWER_SUPPLY_EXTERNAL_UNSTABLE, false, false, false, -10}, 50},
144 
145         // Use `mLeaderWeightAdjustment` larger than valid range
146         // Make sure it clamps to -16 and +16.
147         {{OT_POWER_SUPPLY_BATTERY, false, false, false, 20}, 72},
148         {{OT_POWER_SUPPLY_EXTERNAL, false, false, false, 20}, 80},
149         {{OT_POWER_SUPPLY_EXTERNAL_STABLE, false, false, false, 20}, 84},
150         {{OT_POWER_SUPPLY_EXTERNAL_UNSTABLE, false, false, false, 20}, 76},
151 
152         {{OT_POWER_SUPPLY_BATTERY, true, false, false, -20}, 41},
153         {{OT_POWER_SUPPLY_EXTERNAL, true, false, false, -20}, 49},
154         {{OT_POWER_SUPPLY_EXTERNAL_STABLE, true, false, false, -20}, 53},
155         {{OT_POWER_SUPPLY_EXTERNAL_UNSTABLE, true, false, false, -20}, 45},
156     };
157 
158     Instance *instance;
159 
160     instance = static_cast<Instance *>(testInitInstance());
161     VerifyOrQuit(instance != nullptr);
162 
163     for (const TestCase &testCase : kTestCases)
164     {
165         otThreadSetDeviceProperties(instance, &testCase.mDeviceProperties);
166         CompareDevicePropertiess(testCase.mDeviceProperties, *otThreadGetDeviceProperties(instance));
167         VerifyOrQuit(otThreadGetLocalLeaderWeight(instance) == testCase.mExpectedLeaderWeight);
168     }
169 
170     printf("TestLeaderWeightCalculation passed\n");
171 }
172 
173 #endif // #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MLE_DEVICE_PROPERTY_LEADER_WEIGHT_ENABLE
174 
175 } // namespace ot
176 
main(void)177 int main(void)
178 {
179 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MLE_DEVICE_PROPERTY_LEADER_WEIGHT_ENABLE
180     ot::TestDefaultDeviceProperties();
181     ot::TestLeaderWeightCalculation();
182 #endif
183 
184     printf("All tests passed\n");
185     return 0;
186 }
187