1*cfb92d14SAndroid Build Coastguard Worker /*
2*cfb92d14SAndroid Build Coastguard Worker * Copyright (c) 2018, 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
31*cfb92d14SAndroid Build Coastguard Worker #include <openthread/config.h>
32*cfb92d14SAndroid Build Coastguard Worker
33*cfb92d14SAndroid Build Coastguard Worker #include "test_util.h"
34*cfb92d14SAndroid Build Coastguard Worker #include "common/array.hpp"
35*cfb92d14SAndroid Build Coastguard Worker #include "common/code_utils.hpp"
36*cfb92d14SAndroid Build Coastguard Worker #include "instance/instance.hpp"
37*cfb92d14SAndroid Build Coastguard Worker #include "thread/child_table.hpp"
38*cfb92d14SAndroid Build Coastguard Worker
39*cfb92d14SAndroid Build Coastguard Worker namespace ot {
40*cfb92d14SAndroid Build Coastguard Worker
41*cfb92d14SAndroid Build Coastguard Worker static Instance *sInstance;
42*cfb92d14SAndroid Build Coastguard Worker
43*cfb92d14SAndroid Build Coastguard Worker enum
44*cfb92d14SAndroid Build Coastguard Worker {
45*cfb92d14SAndroid Build Coastguard Worker kMaxChildren = OPENTHREAD_CONFIG_MLE_MAX_CHILDREN,
46*cfb92d14SAndroid Build Coastguard Worker };
47*cfb92d14SAndroid Build Coastguard Worker
48*cfb92d14SAndroid Build Coastguard Worker struct TestChild
49*cfb92d14SAndroid Build Coastguard Worker {
50*cfb92d14SAndroid Build Coastguard Worker Child::State mState;
51*cfb92d14SAndroid Build Coastguard Worker uint16_t mRloc16;
52*cfb92d14SAndroid Build Coastguard Worker otExtAddress mExtAddress;
53*cfb92d14SAndroid Build Coastguard Worker };
54*cfb92d14SAndroid Build Coastguard Worker
55*cfb92d14SAndroid Build Coastguard Worker const Child::StateFilter kAllFilters[] = {
56*cfb92d14SAndroid Build Coastguard Worker Child::kInStateValid,
57*cfb92d14SAndroid Build Coastguard Worker Child::kInStateValidOrRestoring,
58*cfb92d14SAndroid Build Coastguard Worker Child::kInStateChildIdRequest,
59*cfb92d14SAndroid Build Coastguard Worker Child::kInStateValidOrAttaching,
60*cfb92d14SAndroid Build Coastguard Worker Child::kInStateAnyExceptInvalid,
61*cfb92d14SAndroid Build Coastguard Worker };
62*cfb92d14SAndroid Build Coastguard Worker
63*cfb92d14SAndroid Build Coastguard Worker // Checks whether a `Child` matches the `TestChild` struct.
ChildMatches(const Child & aChild,const TestChild & aTestChild)64*cfb92d14SAndroid Build Coastguard Worker static bool ChildMatches(const Child &aChild, const TestChild &aTestChild)
65*cfb92d14SAndroid Build Coastguard Worker {
66*cfb92d14SAndroid Build Coastguard Worker return (aChild.GetState() == aTestChild.mState) && (aChild.GetRloc16() == aTestChild.mRloc16) &&
67*cfb92d14SAndroid Build Coastguard Worker (aChild.GetExtAddress() == static_cast<const Mac::ExtAddress &>(aTestChild.mExtAddress));
68*cfb92d14SAndroid Build Coastguard Worker }
69*cfb92d14SAndroid Build Coastguard Worker
70*cfb92d14SAndroid Build Coastguard Worker // Checks whether a `Child::State` matches a `Child::StateFilter`.
StateMatchesFilter(Child::State aState,Child::StateFilter aFilter)71*cfb92d14SAndroid Build Coastguard Worker static bool StateMatchesFilter(Child::State aState, Child::StateFilter aFilter)
72*cfb92d14SAndroid Build Coastguard Worker {
73*cfb92d14SAndroid Build Coastguard Worker bool rval = false;
74*cfb92d14SAndroid Build Coastguard Worker Child child;
75*cfb92d14SAndroid Build Coastguard Worker
76*cfb92d14SAndroid Build Coastguard Worker child.SetState(aState);
77*cfb92d14SAndroid Build Coastguard Worker
78*cfb92d14SAndroid Build Coastguard Worker switch (aFilter)
79*cfb92d14SAndroid Build Coastguard Worker {
80*cfb92d14SAndroid Build Coastguard Worker case Child::kInStateAnyExceptInvalid:
81*cfb92d14SAndroid Build Coastguard Worker rval = (aState != Child::kStateInvalid);
82*cfb92d14SAndroid Build Coastguard Worker break;
83*cfb92d14SAndroid Build Coastguard Worker
84*cfb92d14SAndroid Build Coastguard Worker case Child::kInStateValid:
85*cfb92d14SAndroid Build Coastguard Worker rval = (aState == Child::kStateValid);
86*cfb92d14SAndroid Build Coastguard Worker break;
87*cfb92d14SAndroid Build Coastguard Worker
88*cfb92d14SAndroid Build Coastguard Worker case Child::kInStateValidOrRestoring:
89*cfb92d14SAndroid Build Coastguard Worker rval = child.IsStateValidOrRestoring();
90*cfb92d14SAndroid Build Coastguard Worker break;
91*cfb92d14SAndroid Build Coastguard Worker
92*cfb92d14SAndroid Build Coastguard Worker case Child::kInStateChildIdRequest:
93*cfb92d14SAndroid Build Coastguard Worker rval = (aState == Child::kStateChildIdRequest);
94*cfb92d14SAndroid Build Coastguard Worker break;
95*cfb92d14SAndroid Build Coastguard Worker
96*cfb92d14SAndroid Build Coastguard Worker case Child::kInStateValidOrAttaching:
97*cfb92d14SAndroid Build Coastguard Worker rval = child.IsStateValidOrAttaching();
98*cfb92d14SAndroid Build Coastguard Worker break;
99*cfb92d14SAndroid Build Coastguard Worker
100*cfb92d14SAndroid Build Coastguard Worker case Child::kInStateInvalid:
101*cfb92d14SAndroid Build Coastguard Worker rval = child.IsStateInvalid();
102*cfb92d14SAndroid Build Coastguard Worker break;
103*cfb92d14SAndroid Build Coastguard Worker
104*cfb92d14SAndroid Build Coastguard Worker case Child::kInStateAnyExceptValidOrRestoring:
105*cfb92d14SAndroid Build Coastguard Worker rval = !child.IsStateValidOrRestoring();
106*cfb92d14SAndroid Build Coastguard Worker break;
107*cfb92d14SAndroid Build Coastguard Worker
108*cfb92d14SAndroid Build Coastguard Worker case Child::kInStateAny:
109*cfb92d14SAndroid Build Coastguard Worker rval = true;
110*cfb92d14SAndroid Build Coastguard Worker break;
111*cfb92d14SAndroid Build Coastguard Worker }
112*cfb92d14SAndroid Build Coastguard Worker
113*cfb92d14SAndroid Build Coastguard Worker return rval;
114*cfb92d14SAndroid Build Coastguard Worker }
115*cfb92d14SAndroid Build Coastguard Worker
116*cfb92d14SAndroid Build Coastguard Worker // Verifies that `ChildTable` contains a given list of `TestChild` entries.
VerifyChildTableContent(ChildTable & aTable,uint16_t aChildListLength,const TestChild * aChildList)117*cfb92d14SAndroid Build Coastguard Worker void VerifyChildTableContent(ChildTable &aTable, uint16_t aChildListLength, const TestChild *aChildList)
118*cfb92d14SAndroid Build Coastguard Worker {
119*cfb92d14SAndroid Build Coastguard Worker printf("Test ChildTable with %d entries", aChildListLength);
120*cfb92d14SAndroid Build Coastguard Worker
121*cfb92d14SAndroid Build Coastguard Worker for (Child::StateFilter filter : kAllFilters)
122*cfb92d14SAndroid Build Coastguard Worker {
123*cfb92d14SAndroid Build Coastguard Worker // Verify that we can find all children from given list by rloc or extended address.
124*cfb92d14SAndroid Build Coastguard Worker
125*cfb92d14SAndroid Build Coastguard Worker for (uint16_t listIndex = 0; listIndex < aChildListLength; listIndex++)
126*cfb92d14SAndroid Build Coastguard Worker {
127*cfb92d14SAndroid Build Coastguard Worker Child *child;
128*cfb92d14SAndroid Build Coastguard Worker Mac::Address address;
129*cfb92d14SAndroid Build Coastguard Worker
130*cfb92d14SAndroid Build Coastguard Worker if (!StateMatchesFilter(aChildList[listIndex].mState, filter))
131*cfb92d14SAndroid Build Coastguard Worker {
132*cfb92d14SAndroid Build Coastguard Worker continue;
133*cfb92d14SAndroid Build Coastguard Worker }
134*cfb92d14SAndroid Build Coastguard Worker
135*cfb92d14SAndroid Build Coastguard Worker child = aTable.FindChild(aChildList[listIndex].mRloc16, filter);
136*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(child != nullptr, "FindChild(rloc) failed");
137*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(ChildMatches(*child, aChildList[listIndex]), "FindChild(rloc) returned incorrect child");
138*cfb92d14SAndroid Build Coastguard Worker
139*cfb92d14SAndroid Build Coastguard Worker child = aTable.FindChild(static_cast<const Mac::ExtAddress &>(aChildList[listIndex].mExtAddress), filter);
140*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(child != nullptr, "FindChild(ExtAddress) failed");
141*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(ChildMatches(*child, aChildList[listIndex]), "FindChild(ExtAddress) returned incorrect child");
142*cfb92d14SAndroid Build Coastguard Worker
143*cfb92d14SAndroid Build Coastguard Worker address.SetShort(aChildList[listIndex].mRloc16);
144*cfb92d14SAndroid Build Coastguard Worker child = aTable.FindChild(address, filter);
145*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(child != nullptr, "FindChild(address) failed");
146*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(ChildMatches(*child, aChildList[listIndex]), "FindChild(address) returned incorrect child");
147*cfb92d14SAndroid Build Coastguard Worker
148*cfb92d14SAndroid Build Coastguard Worker address.SetExtended(static_cast<const Mac::ExtAddress &>(aChildList[listIndex].mExtAddress));
149*cfb92d14SAndroid Build Coastguard Worker child = aTable.FindChild(address, filter);
150*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(child != nullptr, "FindChild(address) failed");
151*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(ChildMatches(*child, aChildList[listIndex]), "FindChild(address) returned incorrect child");
152*cfb92d14SAndroid Build Coastguard Worker }
153*cfb92d14SAndroid Build Coastguard Worker
154*cfb92d14SAndroid Build Coastguard Worker // Verify `ChildTable::Iterator` behavior.
155*cfb92d14SAndroid Build Coastguard Worker
156*cfb92d14SAndroid Build Coastguard Worker {
157*cfb92d14SAndroid Build Coastguard Worker ChildTable::Iterator iter(*sInstance, filter);
158*cfb92d14SAndroid Build Coastguard Worker bool childObserved[kMaxChildren];
159*cfb92d14SAndroid Build Coastguard Worker uint16_t numChildren = 0;
160*cfb92d14SAndroid Build Coastguard Worker
161*cfb92d14SAndroid Build Coastguard Worker memset(childObserved, 0, sizeof(childObserved));
162*cfb92d14SAndroid Build Coastguard Worker
163*cfb92d14SAndroid Build Coastguard Worker // Use the iterator and verify that each returned `Child` entry is in the expected list.
164*cfb92d14SAndroid Build Coastguard Worker
165*cfb92d14SAndroid Build Coastguard Worker for (; !iter.IsDone(); iter++)
166*cfb92d14SAndroid Build Coastguard Worker {
167*cfb92d14SAndroid Build Coastguard Worker Child *child = iter.GetChild();
168*cfb92d14SAndroid Build Coastguard Worker Child &childRef = *iter;
169*cfb92d14SAndroid Build Coastguard Worker bool didFind = false;
170*cfb92d14SAndroid Build Coastguard Worker uint16_t childIndex;
171*cfb92d14SAndroid Build Coastguard Worker
172*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(child != nullptr, "iter.GetChild() failed");
173*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(&childRef == child, "iter.operator*() failed");
174*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(iter->GetRloc16() == child->GetRloc16(), "iter.operator->() failed");
175*cfb92d14SAndroid Build Coastguard Worker
176*cfb92d14SAndroid Build Coastguard Worker childIndex = aTable.GetChildIndex(*child);
177*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(childIndex < aTable.GetMaxChildrenAllowed(), "Child Index is out of bound");
178*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(aTable.GetChildAtIndex(childIndex) == child, "GetChildAtIndex() failed");
179*cfb92d14SAndroid Build Coastguard Worker
180*cfb92d14SAndroid Build Coastguard Worker for (uint16_t index = 0; index < aChildListLength; index++)
181*cfb92d14SAndroid Build Coastguard Worker {
182*cfb92d14SAndroid Build Coastguard Worker if (ChildMatches(*iter.GetChild(), aChildList[index]))
183*cfb92d14SAndroid Build Coastguard Worker {
184*cfb92d14SAndroid Build Coastguard Worker childObserved[index] = true;
185*cfb92d14SAndroid Build Coastguard Worker numChildren++;
186*cfb92d14SAndroid Build Coastguard Worker didFind = true;
187*cfb92d14SAndroid Build Coastguard Worker break;
188*cfb92d14SAndroid Build Coastguard Worker }
189*cfb92d14SAndroid Build Coastguard Worker }
190*cfb92d14SAndroid Build Coastguard Worker
191*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(didFind, "ChildTable::Iterator returned an entry not in the expected list");
192*cfb92d14SAndroid Build Coastguard Worker }
193*cfb92d14SAndroid Build Coastguard Worker
194*cfb92d14SAndroid Build Coastguard Worker // Verify that when iterator is done, it points to `nullptr`.
195*cfb92d14SAndroid Build Coastguard Worker
196*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(iter.GetChild() == nullptr);
197*cfb92d14SAndroid Build Coastguard Worker
198*cfb92d14SAndroid Build Coastguard Worker iter++;
199*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(iter.IsDone(), "iterator Advance() (after iterator is done) failed");
200*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(iter.GetChild() == nullptr);
201*cfb92d14SAndroid Build Coastguard Worker
202*cfb92d14SAndroid Build Coastguard Worker // Verify that the number of children matches the number of entries we get from iterator.
203*cfb92d14SAndroid Build Coastguard Worker
204*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(aTable.GetNumChildren(filter) == numChildren);
205*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(aTable.HasChildren(filter) == (numChildren != 0));
206*cfb92d14SAndroid Build Coastguard Worker
207*cfb92d14SAndroid Build Coastguard Worker // Verify that there is no missing or extra entry between the expected list
208*cfb92d14SAndroid Build Coastguard Worker // and what was observed/returned by the iterator.
209*cfb92d14SAndroid Build Coastguard Worker
210*cfb92d14SAndroid Build Coastguard Worker for (uint16_t index = 0; index < aChildListLength; index++)
211*cfb92d14SAndroid Build Coastguard Worker {
212*cfb92d14SAndroid Build Coastguard Worker if (StateMatchesFilter(aChildList[index].mState, filter))
213*cfb92d14SAndroid Build Coastguard Worker {
214*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(childObserved[index], "iterator failed to return an expected entry");
215*cfb92d14SAndroid Build Coastguard Worker }
216*cfb92d14SAndroid Build Coastguard Worker else
217*cfb92d14SAndroid Build Coastguard Worker {
218*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(!childObserved[index], "iterator returned an extra unexpected entry");
219*cfb92d14SAndroid Build Coastguard Worker }
220*cfb92d14SAndroid Build Coastguard Worker }
221*cfb92d14SAndroid Build Coastguard Worker
222*cfb92d14SAndroid Build Coastguard Worker // Verify the behavior of range-based `for` iteration.
223*cfb92d14SAndroid Build Coastguard Worker
224*cfb92d14SAndroid Build Coastguard Worker iter.Reset();
225*cfb92d14SAndroid Build Coastguard Worker
226*cfb92d14SAndroid Build Coastguard Worker for (Child &child : aTable.Iterate(filter))
227*cfb92d14SAndroid Build Coastguard Worker {
228*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(&child == iter.GetChild(), "range-based for loop Iterate() failed");
229*cfb92d14SAndroid Build Coastguard Worker iter++;
230*cfb92d14SAndroid Build Coastguard Worker }
231*cfb92d14SAndroid Build Coastguard Worker
232*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(iter.IsDone(), "range-based for loop Iterate() did not return all entries");
233*cfb92d14SAndroid Build Coastguard Worker }
234*cfb92d14SAndroid Build Coastguard Worker }
235*cfb92d14SAndroid Build Coastguard Worker
236*cfb92d14SAndroid Build Coastguard Worker printf(" -- PASS\n");
237*cfb92d14SAndroid Build Coastguard Worker }
238*cfb92d14SAndroid Build Coastguard Worker
TestChildTable(void)239*cfb92d14SAndroid Build Coastguard Worker void TestChildTable(void)
240*cfb92d14SAndroid Build Coastguard Worker {
241*cfb92d14SAndroid Build Coastguard Worker const TestChild testChildList[] = {
242*cfb92d14SAndroid Build Coastguard Worker {
243*cfb92d14SAndroid Build Coastguard Worker Child::kStateValid,
244*cfb92d14SAndroid Build Coastguard Worker 0x8001,
245*cfb92d14SAndroid Build Coastguard Worker {{0x10, 0x20, 0x03, 0x15, 0x10, 0x00, 0x60, 0x16}},
246*cfb92d14SAndroid Build Coastguard Worker },
247*cfb92d14SAndroid Build Coastguard Worker {
248*cfb92d14SAndroid Build Coastguard Worker Child::kStateParentRequest,
249*cfb92d14SAndroid Build Coastguard Worker 0x8002,
250*cfb92d14SAndroid Build Coastguard Worker {{0x10, 0x20, 0x03, 0x15, 0x10, 0x00, 0x60, 0x17}},
251*cfb92d14SAndroid Build Coastguard Worker },
252*cfb92d14SAndroid Build Coastguard Worker {
253*cfb92d14SAndroid Build Coastguard Worker Child::kStateValid,
254*cfb92d14SAndroid Build Coastguard Worker 0x8003,
255*cfb92d14SAndroid Build Coastguard Worker {{0x10, 0x20, 0x03, 0x15, 0x10, 0x00, 0x60, 0x18}},
256*cfb92d14SAndroid Build Coastguard Worker },
257*cfb92d14SAndroid Build Coastguard Worker {
258*cfb92d14SAndroid Build Coastguard Worker Child::kStateValid,
259*cfb92d14SAndroid Build Coastguard Worker 0x8004,
260*cfb92d14SAndroid Build Coastguard Worker {{0x10, 0x20, 0x03, 0x15, 0x10, 0x00, 0x60, 0x19}},
261*cfb92d14SAndroid Build Coastguard Worker },
262*cfb92d14SAndroid Build Coastguard Worker {
263*cfb92d14SAndroid Build Coastguard Worker Child::kStateRestored,
264*cfb92d14SAndroid Build Coastguard Worker 0x8005,
265*cfb92d14SAndroid Build Coastguard Worker {{0x10, 0x20, 0x03, 0x15, 0x10, 0x00, 0x60, 0x20}},
266*cfb92d14SAndroid Build Coastguard Worker },
267*cfb92d14SAndroid Build Coastguard Worker {
268*cfb92d14SAndroid Build Coastguard Worker Child::kStateValid,
269*cfb92d14SAndroid Build Coastguard Worker 0x8006,
270*cfb92d14SAndroid Build Coastguard Worker {{0x10, 0x20, 0x03, 0x15, 0x10, 0x00, 0x60, 0x21}},
271*cfb92d14SAndroid Build Coastguard Worker },
272*cfb92d14SAndroid Build Coastguard Worker {
273*cfb92d14SAndroid Build Coastguard Worker Child::kStateChildIdRequest,
274*cfb92d14SAndroid Build Coastguard Worker 0x8007,
275*cfb92d14SAndroid Build Coastguard Worker {{0x10, 0x20, 0x03, 0x15, 0x10, 0x00, 0x60, 0x22}},
276*cfb92d14SAndroid Build Coastguard Worker },
277*cfb92d14SAndroid Build Coastguard Worker {
278*cfb92d14SAndroid Build Coastguard Worker Child::kStateChildUpdateRequest,
279*cfb92d14SAndroid Build Coastguard Worker 0x8008,
280*cfb92d14SAndroid Build Coastguard Worker {{0x10, 0x20, 0x03, 0x15, 0x10, 0x00, 0x60, 0x23}},
281*cfb92d14SAndroid Build Coastguard Worker },
282*cfb92d14SAndroid Build Coastguard Worker {
283*cfb92d14SAndroid Build Coastguard Worker Child::kStateParentResponse,
284*cfb92d14SAndroid Build Coastguard Worker 0x8009,
285*cfb92d14SAndroid Build Coastguard Worker {{0x10, 0x20, 0x03, 0x15, 0x10, 0x00, 0x60, 0x24}},
286*cfb92d14SAndroid Build Coastguard Worker },
287*cfb92d14SAndroid Build Coastguard Worker {
288*cfb92d14SAndroid Build Coastguard Worker Child::kStateRestored,
289*cfb92d14SAndroid Build Coastguard Worker 0x800a,
290*cfb92d14SAndroid Build Coastguard Worker {{0x10, 0x20, 0x03, 0x15, 0x10, 0x00, 0x60, 0x25}},
291*cfb92d14SAndroid Build Coastguard Worker },
292*cfb92d14SAndroid Build Coastguard Worker };
293*cfb92d14SAndroid Build Coastguard Worker
294*cfb92d14SAndroid Build Coastguard Worker const uint16_t testListLength = GetArrayLength(testChildList);
295*cfb92d14SAndroid Build Coastguard Worker
296*cfb92d14SAndroid Build Coastguard Worker uint16_t testNumAllowedChildren = 2;
297*cfb92d14SAndroid Build Coastguard Worker
298*cfb92d14SAndroid Build Coastguard Worker ChildTable *table;
299*cfb92d14SAndroid Build Coastguard Worker Error error;
300*cfb92d14SAndroid Build Coastguard Worker
301*cfb92d14SAndroid Build Coastguard Worker sInstance = testInitInstance();
302*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(sInstance != nullptr);
303*cfb92d14SAndroid Build Coastguard Worker
304*cfb92d14SAndroid Build Coastguard Worker table = &sInstance->Get<ChildTable>();
305*cfb92d14SAndroid Build Coastguard Worker
306*cfb92d14SAndroid Build Coastguard Worker //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
307*cfb92d14SAndroid Build Coastguard Worker printf("Checking initial state after child table is constructed");
308*cfb92d14SAndroid Build Coastguard Worker
309*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(table->GetMaxChildrenAllowed() == table->GetMaxChildren(),
310*cfb92d14SAndroid Build Coastguard Worker "GetMaxChildrenAllowed() initial value is incorrect ");
311*cfb92d14SAndroid Build Coastguard Worker
312*cfb92d14SAndroid Build Coastguard Worker for (Child::StateFilter filter : kAllFilters)
313*cfb92d14SAndroid Build Coastguard Worker {
314*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(table->HasChildren(filter) == false);
315*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(table->GetNumChildren(filter) == 0);
316*cfb92d14SAndroid Build Coastguard Worker }
317*cfb92d14SAndroid Build Coastguard Worker
318*cfb92d14SAndroid Build Coastguard Worker printf(" -- PASS\n");
319*cfb92d14SAndroid Build Coastguard Worker
320*cfb92d14SAndroid Build Coastguard Worker //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
321*cfb92d14SAndroid Build Coastguard Worker
322*cfb92d14SAndroid Build Coastguard Worker VerifyChildTableContent(*table, 0, testChildList);
323*cfb92d14SAndroid Build Coastguard Worker
324*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(table->GetMaxChildrenAllowed() >= testListLength,
325*cfb92d14SAndroid Build Coastguard Worker "Default child table size is too small for the unit test");
326*cfb92d14SAndroid Build Coastguard Worker
327*cfb92d14SAndroid Build Coastguard Worker // Add the child entries from test list one by one and verify the table content
328*cfb92d14SAndroid Build Coastguard Worker for (uint16_t i = 0; i < testListLength; i++)
329*cfb92d14SAndroid Build Coastguard Worker {
330*cfb92d14SAndroid Build Coastguard Worker Child *child;
331*cfb92d14SAndroid Build Coastguard Worker
332*cfb92d14SAndroid Build Coastguard Worker child = table->GetNewChild();
333*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(child != nullptr, "GetNewChild() failed");
334*cfb92d14SAndroid Build Coastguard Worker
335*cfb92d14SAndroid Build Coastguard Worker child->SetState(testChildList[i].mState);
336*cfb92d14SAndroid Build Coastguard Worker child->SetRloc16(testChildList[i].mRloc16);
337*cfb92d14SAndroid Build Coastguard Worker child->SetExtAddress((static_cast<const Mac::ExtAddress &>(testChildList[i].mExtAddress)));
338*cfb92d14SAndroid Build Coastguard Worker
339*cfb92d14SAndroid Build Coastguard Worker VerifyChildTableContent(*table, i + 1, testChildList);
340*cfb92d14SAndroid Build Coastguard Worker }
341*cfb92d14SAndroid Build Coastguard Worker
342*cfb92d14SAndroid Build Coastguard Worker //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
343*cfb92d14SAndroid Build Coastguard Worker // Verify Child Table clear
344*cfb92d14SAndroid Build Coastguard Worker
345*cfb92d14SAndroid Build Coastguard Worker table->Clear();
346*cfb92d14SAndroid Build Coastguard Worker
347*cfb92d14SAndroid Build Coastguard Worker VerifyChildTableContent(*table, 0, testChildList);
348*cfb92d14SAndroid Build Coastguard Worker
349*cfb92d14SAndroid Build Coastguard Worker // Add the child entries from test list in reverse order and verify the table content
350*cfb92d14SAndroid Build Coastguard Worker for (uint16_t i = testListLength; i > 0; i--)
351*cfb92d14SAndroid Build Coastguard Worker {
352*cfb92d14SAndroid Build Coastguard Worker Child *child;
353*cfb92d14SAndroid Build Coastguard Worker
354*cfb92d14SAndroid Build Coastguard Worker child = table->GetNewChild();
355*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(child != nullptr, "GetNewChild() failed");
356*cfb92d14SAndroid Build Coastguard Worker
357*cfb92d14SAndroid Build Coastguard Worker child->SetState(testChildList[i - 1].mState);
358*cfb92d14SAndroid Build Coastguard Worker child->SetRloc16(testChildList[i - 1].mRloc16);
359*cfb92d14SAndroid Build Coastguard Worker child->SetExtAddress((static_cast<const Mac::ExtAddress &>(testChildList[i - 1].mExtAddress)));
360*cfb92d14SAndroid Build Coastguard Worker
361*cfb92d14SAndroid Build Coastguard Worker VerifyChildTableContent(*table, testListLength - i + 1, &testChildList[i - 1]);
362*cfb92d14SAndroid Build Coastguard Worker }
363*cfb92d14SAndroid Build Coastguard Worker
364*cfb92d14SAndroid Build Coastguard Worker //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
365*cfb92d14SAndroid Build Coastguard Worker printf("Test Get/SetMaxChildrenAllowed");
366*cfb92d14SAndroid Build Coastguard Worker
367*cfb92d14SAndroid Build Coastguard Worker error = table->SetMaxChildrenAllowed(kMaxChildren - 1);
368*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(error == kErrorInvalidState, "SetMaxChildrenAllowed() should fail when table is not empty");
369*cfb92d14SAndroid Build Coastguard Worker
370*cfb92d14SAndroid Build Coastguard Worker table->Clear();
371*cfb92d14SAndroid Build Coastguard Worker error = table->SetMaxChildrenAllowed(kMaxChildren + 1);
372*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(error == kErrorInvalidArgs, "SetMaxChildrenAllowed() did not fail with an invalid arg");
373*cfb92d14SAndroid Build Coastguard Worker
374*cfb92d14SAndroid Build Coastguard Worker error = table->SetMaxChildrenAllowed(0);
375*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(error == kErrorInvalidArgs, "SetMaxChildrenAllowed() did not fail with an invalid arg");
376*cfb92d14SAndroid Build Coastguard Worker
377*cfb92d14SAndroid Build Coastguard Worker error = table->SetMaxChildrenAllowed(testNumAllowedChildren);
378*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(error == kErrorNone, "SetMaxChildrenAllowed() failed");
379*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(table->GetMaxChildrenAllowed() == testNumAllowedChildren);
380*cfb92d14SAndroid Build Coastguard Worker
381*cfb92d14SAndroid Build Coastguard Worker for (uint16_t num = 0; num < testNumAllowedChildren; num++)
382*cfb92d14SAndroid Build Coastguard Worker {
383*cfb92d14SAndroid Build Coastguard Worker Child *child = table->GetNewChild();
384*cfb92d14SAndroid Build Coastguard Worker
385*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(child != nullptr, "GetNewChild() failed");
386*cfb92d14SAndroid Build Coastguard Worker child->SetState(Child::kStateValid);
387*cfb92d14SAndroid Build Coastguard Worker }
388*cfb92d14SAndroid Build Coastguard Worker
389*cfb92d14SAndroid Build Coastguard Worker VerifyOrQuit(table->GetNewChild() == nullptr, "GetNewChild() did not fail when table was full");
390*cfb92d14SAndroid Build Coastguard Worker
391*cfb92d14SAndroid Build Coastguard Worker printf(" -- PASS\n");
392*cfb92d14SAndroid Build Coastguard Worker
393*cfb92d14SAndroid Build Coastguard Worker testFreeInstance(sInstance);
394*cfb92d14SAndroid Build Coastguard Worker }
395*cfb92d14SAndroid Build Coastguard Worker
396*cfb92d14SAndroid Build Coastguard Worker } // namespace ot
397*cfb92d14SAndroid Build Coastguard Worker
main(void)398*cfb92d14SAndroid Build Coastguard Worker int main(void)
399*cfb92d14SAndroid Build Coastguard Worker {
400*cfb92d14SAndroid Build Coastguard Worker ot::TestChildTable();
401*cfb92d14SAndroid Build Coastguard Worker printf("\nAll tests passed.\n");
402*cfb92d14SAndroid Build Coastguard Worker return 0;
403*cfb92d14SAndroid Build Coastguard Worker }
404