mirror of
https://github.com/espressif/openthread.git
synced 2026-06-05 21:14:49 +00:00
7f8e04a352
This commit updates `tests/unit/test_seeker.cpp` to use `ot::Array` instead of C-style arrays with initializer lists for passing expected selection orders in `CheckSelection()`. The previous approach of passing initializer lists to a function expecting a reference to a constant array caused compilation issues on certain toolchains due to template deduction rules or temporary object handling. By explicitly populating an `ot::Array` and passing it, the test code becomes more portable and robust across different compilers.
534 lines
20 KiB
C++
534 lines
20 KiB
C++
/*
|
|
* Copyright (c) 2026, The OpenThread Authors.
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* 3. Neither the name of the copyright holder nor the
|
|
* names of its contributors may be used to endorse or promote products
|
|
* derived from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#include "instance/instance.hpp"
|
|
|
|
#include "test_platform.h"
|
|
#include "test_util.hpp"
|
|
|
|
namespace ot {
|
|
|
|
#if OPENTHREAD_CONFIG_SEEKER_ENABLE || OPENTHREAD_CONFIG_JOINER_ENABLE
|
|
|
|
class UnitTester
|
|
{
|
|
public:
|
|
using Seeker = MeshCoP::Seeker;
|
|
using CandidateEntry = MeshCoP::Seeker::CandidateEntry;
|
|
|
|
static void CreateScanResult(ScanResult &aResult, uint64_t aExtPanId, uint64_t aExtAddr, int8_t aRssi)
|
|
{
|
|
ClearAllBytes(aResult);
|
|
LittleEndian::WriteUint64(aExtPanId, aResult.mExtendedPanId.m8);
|
|
LittleEndian::WriteUint64(aExtAddr, aResult.mExtAddress.m8);
|
|
aResult.mRssi = aRssi;
|
|
aResult.mPanId = static_cast<uint16_t>(aExtPanId & 0xffff);
|
|
aResult.mChannel = 11;
|
|
aResult.mJoinerUdpPort = 1000;
|
|
}
|
|
|
|
static void LogCandidate(const CandidateEntry &aEntry)
|
|
{
|
|
if (aEntry.IsEmpty())
|
|
{
|
|
printf(" empty\n");
|
|
}
|
|
else
|
|
{
|
|
printf(" ext-addr:%2.2s, ext-panid:%4.4s, rssi:%d, prf:%u, conn-attempted:%u\n",
|
|
aEntry.mExtAddr.ToString().AsCString(), aEntry.mExtPanId.ToString().AsCString(), aEntry.mRssi,
|
|
aEntry.mPreferred, aEntry.mConnAttempted);
|
|
}
|
|
}
|
|
|
|
static void LogCandidates(const Seeker &aSeeker)
|
|
{
|
|
CandidateEntry entry;
|
|
|
|
printf("\nCandidates:\n");
|
|
|
|
for (entry.InitForIteration(); aSeeker.mCandidates.ReadNext(entry) == kErrorNone;)
|
|
{
|
|
LogCandidate(entry);
|
|
}
|
|
|
|
printf("\n");
|
|
}
|
|
|
|
static void SaveCandidate(Seeker &aSeeker, uint64_t aExtPanId, uint64_t aExtAddr, int8_t aRssi, bool aPreferred)
|
|
{
|
|
ScanResult result;
|
|
|
|
CreateScanResult(result, aExtPanId, aExtAddr, aRssi);
|
|
aSeeker.SaveCandidate(result, aPreferred);
|
|
}
|
|
|
|
static bool Contains(const Seeker &aSeeker, uint64_t aExtPanId, uint64_t aExtAddr)
|
|
{
|
|
MeshCoP::ExtendedPanId extPanId;
|
|
Mac::ExtAddress extAddr;
|
|
CandidateEntry entry;
|
|
|
|
LittleEndian::WriteUint64(aExtPanId, extPanId.m8);
|
|
LittleEndian::WriteUint64(aExtAddr, extAddr.m8);
|
|
|
|
return (aSeeker.mCandidates.FindMatching(entry, extPanId, extAddr) == kErrorNone);
|
|
}
|
|
|
|
static void StartCandidateSelection(Seeker &aSeeker)
|
|
{
|
|
// Manually set the state so we can call and validate the
|
|
// `SelectNextCandidate()`.
|
|
|
|
aSeeker.SetState(Seeker::kStateConnectingNetworks);
|
|
}
|
|
|
|
static void SelectNextCandidate(Seeker &aSeeker, CandidateEntry &aEntry)
|
|
{
|
|
Error error = aSeeker.SelectNextCandidate(aEntry);
|
|
|
|
if (error == kErrorNone)
|
|
{
|
|
aEntry.mConnAttempted = true;
|
|
SuccessOrQuit(aSeeker.mCandidates.Write(aEntry));
|
|
}
|
|
else
|
|
{
|
|
aEntry.MarkAsEmpty();
|
|
}
|
|
}
|
|
|
|
static constexpr uint16_t kSelectionArraySize = 32;
|
|
|
|
using ExtAddrArray = Array<uint64_t, kSelectionArraySize>;
|
|
|
|
static void CheckSelection(Seeker &aSeeker, const ExtAddrArray &aExtAddrs)
|
|
{
|
|
CandidateEntry entry;
|
|
Mac::ExtAddress extAddr;
|
|
|
|
printf("\nSelection order:\n");
|
|
|
|
StartCandidateSelection(aSeeker);
|
|
|
|
for (uint64_t addr : aExtAddrs)
|
|
{
|
|
SelectNextCandidate(aSeeker, entry);
|
|
LogCandidate(entry);
|
|
|
|
VerifyOrQuit(!entry.IsEmpty());
|
|
|
|
LittleEndian::WriteUint64(addr, extAddr.m8);
|
|
VerifyOrQuit(entry.mExtAddr == extAddr);
|
|
VerifyOrQuit(entry.mConnAttempted);
|
|
}
|
|
|
|
SelectNextCandidate(aSeeker, entry);
|
|
VerifyOrQuit(entry.IsEmpty());
|
|
}
|
|
|
|
static void TestSeekerCandidates(void)
|
|
{
|
|
Instance *instance;
|
|
|
|
printf("TestSeekerCandidates()\n");
|
|
|
|
instance = static_cast<Instance *>(testInitInstance());
|
|
VerifyOrQuit(instance != nullptr);
|
|
|
|
Seeker &seeker = instance->Get<Seeker>();
|
|
CandidateEntry entry;
|
|
ExtAddrArray selectionOrder;
|
|
|
|
printf("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n");
|
|
printf("Basic addition & replacement\n\n");
|
|
|
|
seeker.Stop();
|
|
|
|
printf("Save a single candidate");
|
|
SaveCandidate(seeker, 0xaaaa, 0xa1, -50, false);
|
|
LogCandidates(seeker);
|
|
|
|
VerifyOrQuit(seeker.mCandidates.GetLength() == 1);
|
|
VerifyOrQuit(Contains(seeker, 0xaaaa, 0xa1));
|
|
|
|
printf("Save same candidate with better RSSI");
|
|
SaveCandidate(seeker, 0xaaaa, 0xa1, -40, false);
|
|
LogCandidates(seeker);
|
|
|
|
VerifyOrQuit(seeker.mCandidates.GetLength() == 1);
|
|
VerifyOrQuit(seeker.mCandidates.ReadAt(0, entry) == kErrorNone);
|
|
VerifyOrQuit(entry.mRssi == -40);
|
|
|
|
printf("Save same candidate with worse RSSI, still should replace as it is same extAddr\n");
|
|
SaveCandidate(seeker, 0xaaaa, 0xa1, -60, false);
|
|
LogCandidates(seeker);
|
|
|
|
VerifyOrQuit(seeker.mCandidates.GetLength() == 1);
|
|
VerifyOrQuit(seeker.mCandidates.ReadAt(0, entry) == kErrorNone);
|
|
VerifyOrQuit(entry.mRssi == -60);
|
|
|
|
printf("Validate candidate selection with single entry in array\n\n");
|
|
|
|
selectionOrder.Clear();
|
|
SuccessOrQuit(selectionOrder.PushBack(0xa1));
|
|
|
|
CheckSelection(seeker, selectionOrder);
|
|
|
|
printf("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n");
|
|
printf("Max candidates per network (limit = 3)\n\n");
|
|
|
|
seeker.Stop();
|
|
|
|
printf("Save 3 candidates for network 0xaaaa along with some extra entries\n");
|
|
|
|
SaveCandidate(seeker, 0xaaaa, 0xa1, -50, false);
|
|
SaveCandidate(seeker, 0xbbbb, 0xb1, -70, true);
|
|
SaveCandidate(seeker, 0xaaaa, 0xa2, -52, false);
|
|
SaveCandidate(seeker, 0xcccc, 0xc1, -80, true);
|
|
SaveCandidate(seeker, 0xaaaa, 0xa3, -51, false);
|
|
SaveCandidate(seeker, 0xdddd, 0xd1, -40, false);
|
|
LogCandidates(seeker);
|
|
|
|
VerifyOrQuit(seeker.mCandidates.GetLength() == 6);
|
|
VerifyOrQuit(Contains(seeker, 0xaaaa, 0xa1));
|
|
VerifyOrQuit(Contains(seeker, 0xaaaa, 0xa2));
|
|
VerifyOrQuit(Contains(seeker, 0xaaaa, 0xa3));
|
|
|
|
printf("Try adding 4th for 0xaaaa (worse RSSI) -> should be dropped\n");
|
|
|
|
SaveCandidate(seeker, 0xaaaa, 0xa4, -90, false);
|
|
LogCandidates(seeker);
|
|
|
|
VerifyOrQuit(seeker.mCandidates.GetLength() == 6);
|
|
VerifyOrQuit(!Contains(seeker, 0xaaaa, 0xa4));
|
|
VerifyOrQuit(Contains(seeker, 0xaaaa, 0xa1));
|
|
VerifyOrQuit(Contains(seeker, 0xaaaa, 0xa2));
|
|
VerifyOrQuit(Contains(seeker, 0xaaaa, 0xa3));
|
|
|
|
printf("Try adding 4th for 0xaaaa (better RSSI) -> should replace a2 (lowest RSSI)\n");
|
|
|
|
SaveCandidate(seeker, 0xaaaa, 0xa5, -40, false);
|
|
LogCandidates(seeker);
|
|
|
|
VerifyOrQuit(seeker.mCandidates.GetLength() == 6);
|
|
VerifyOrQuit(Contains(seeker, 0xaaaa, 0xa5));
|
|
VerifyOrQuit(Contains(seeker, 0xaaaa, 0xa1));
|
|
VerifyOrQuit(!Contains(seeker, 0xaaaa, 0xa2));
|
|
VerifyOrQuit(Contains(seeker, 0xaaaa, 0xa3));
|
|
|
|
printf("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n");
|
|
printf("Behavior under full candidates array and eviction\n\n");
|
|
|
|
SaveCandidate(seeker, 0xbbbb, 0xb2, -75, true);
|
|
SaveCandidate(seeker, 0xeeee, 0xe1, -30, false);
|
|
LogCandidates(seeker);
|
|
|
|
VerifyOrQuit(seeker.mCandidates.GetLength() == 8);
|
|
VerifyOrQuit(seeker.mCandidates.IsFull());
|
|
|
|
VerifyOrQuit(Contains(seeker, 0xaaaa, 0xa1));
|
|
VerifyOrQuit(Contains(seeker, 0xaaaa, 0xa5));
|
|
VerifyOrQuit(Contains(seeker, 0xaaaa, 0xa3));
|
|
VerifyOrQuit(Contains(seeker, 0xbbbb, 0xb1));
|
|
VerifyOrQuit(Contains(seeker, 0xbbbb, 0xb2));
|
|
VerifyOrQuit(Contains(seeker, 0xcccc, 0xc1));
|
|
VerifyOrQuit(Contains(seeker, 0xdddd, 0xd1));
|
|
VerifyOrQuit(Contains(seeker, 0xeeee, 0xe1));
|
|
|
|
printf("Try adding new entry 0xb3 for 0xbbbb with better RSSI -> should replace 0xb2\n");
|
|
SaveCandidate(seeker, 0xbbbb, 0xb3, -65, true);
|
|
LogCandidates(seeker);
|
|
|
|
VerifyOrQuit(seeker.mCandidates.GetLength() == 8);
|
|
VerifyOrQuit(seeker.mCandidates.IsFull());
|
|
|
|
VerifyOrQuit(Contains(seeker, 0xbbbb, 0xb1));
|
|
VerifyOrQuit(Contains(seeker, 0xbbbb, 0xb3));
|
|
VerifyOrQuit(!Contains(seeker, 0xbbbb, 0xb2));
|
|
|
|
VerifyOrQuit(Contains(seeker, 0xaaaa, 0xa1));
|
|
VerifyOrQuit(Contains(seeker, 0xaaaa, 0xa5));
|
|
VerifyOrQuit(Contains(seeker, 0xaaaa, 0xa3));
|
|
VerifyOrQuit(Contains(seeker, 0xcccc, 0xc1));
|
|
VerifyOrQuit(Contains(seeker, 0xdddd, 0xd1));
|
|
VerifyOrQuit(Contains(seeker, 0xeeee, 0xe1));
|
|
|
|
printf("Try adding new entry 0xb4 for 0xbbbb with worst RSSI -> should be dropped\n");
|
|
SaveCandidate(seeker, 0xbbbb, 0xb4, -95, true);
|
|
LogCandidates(seeker);
|
|
|
|
VerifyOrQuit(seeker.mCandidates.GetLength() == 8);
|
|
VerifyOrQuit(seeker.mCandidates.IsFull());
|
|
|
|
VerifyOrQuit(Contains(seeker, 0xaaaa, 0xa1));
|
|
VerifyOrQuit(Contains(seeker, 0xaaaa, 0xa5));
|
|
VerifyOrQuit(Contains(seeker, 0xaaaa, 0xa3));
|
|
VerifyOrQuit(Contains(seeker, 0xbbbb, 0xb1));
|
|
VerifyOrQuit(Contains(seeker, 0xbbbb, 0xb3));
|
|
VerifyOrQuit(Contains(seeker, 0xcccc, 0xc1));
|
|
VerifyOrQuit(Contains(seeker, 0xdddd, 0xd1));
|
|
VerifyOrQuit(Contains(seeker, 0xeeee, 0xe1));
|
|
|
|
printf("Try adding new entry 0xc2 for 0xcccc with better RSSI but not preferred -> should be ignored\n");
|
|
|
|
SaveCandidate(seeker, 0xcccc, 0xc2, -40, false);
|
|
LogCandidates(seeker);
|
|
|
|
VerifyOrQuit(seeker.mCandidates.GetLength() == 8);
|
|
VerifyOrQuit(seeker.mCandidates.IsFull());
|
|
|
|
VerifyOrQuit(Contains(seeker, 0xaaaa, 0xa1));
|
|
VerifyOrQuit(Contains(seeker, 0xaaaa, 0xa5));
|
|
VerifyOrQuit(Contains(seeker, 0xaaaa, 0xa3));
|
|
VerifyOrQuit(Contains(seeker, 0xbbbb, 0xb1));
|
|
VerifyOrQuit(Contains(seeker, 0xbbbb, 0xb3));
|
|
VerifyOrQuit(Contains(seeker, 0xcccc, 0xc1));
|
|
VerifyOrQuit(Contains(seeker, 0xdddd, 0xd1));
|
|
VerifyOrQuit(Contains(seeker, 0xeeee, 0xe1));
|
|
|
|
printf("Try adding new entry 0xc3 for 0xcccc with better RSSI and preferred -> should replace 0xc1\n");
|
|
|
|
SaveCandidate(seeker, 0xcccc, 0xc3, -40, true);
|
|
LogCandidates(seeker);
|
|
|
|
VerifyOrQuit(seeker.mCandidates.GetLength() == 8);
|
|
VerifyOrQuit(seeker.mCandidates.IsFull());
|
|
|
|
VerifyOrQuit(Contains(seeker, 0xcccc, 0xc3));
|
|
VerifyOrQuit(!Contains(seeker, 0xcccc, 0xc1));
|
|
|
|
VerifyOrQuit(Contains(seeker, 0xaaaa, 0xa1));
|
|
VerifyOrQuit(Contains(seeker, 0xaaaa, 0xa5));
|
|
VerifyOrQuit(Contains(seeker, 0xaaaa, 0xa3));
|
|
VerifyOrQuit(Contains(seeker, 0xbbbb, 0xb1));
|
|
VerifyOrQuit(Contains(seeker, 0xbbbb, 0xb3));
|
|
VerifyOrQuit(Contains(seeker, 0xdddd, 0xd1));
|
|
VerifyOrQuit(Contains(seeker, 0xeeee, 0xe1));
|
|
|
|
printf("Try adding new entry 0xe2 for 0xeeee with worse RSSI but preferred -> should replace 0xe1\n");
|
|
|
|
SaveCandidate(seeker, 0xeeee, 0xe2, -99, true);
|
|
LogCandidates(seeker);
|
|
|
|
VerifyOrQuit(seeker.mCandidates.GetLength() == 8);
|
|
VerifyOrQuit(seeker.mCandidates.IsFull());
|
|
|
|
VerifyOrQuit(!Contains(seeker, 0xeeee, 0xe1));
|
|
VerifyOrQuit(Contains(seeker, 0xeeee, 0xe2));
|
|
|
|
VerifyOrQuit(Contains(seeker, 0xaaaa, 0xa1));
|
|
VerifyOrQuit(Contains(seeker, 0xaaaa, 0xa5));
|
|
VerifyOrQuit(Contains(seeker, 0xaaaa, 0xa3));
|
|
VerifyOrQuit(Contains(seeker, 0xbbbb, 0xb1));
|
|
VerifyOrQuit(Contains(seeker, 0xbbbb, 0xb3));
|
|
VerifyOrQuit(Contains(seeker, 0xcccc, 0xc3));
|
|
VerifyOrQuit(Contains(seeker, 0xdddd, 0xd1));
|
|
|
|
printf("Try adding new network, 0xf1 for 0xffff -> should evict 0xa3\n");
|
|
|
|
SaveCandidate(seeker, 0xffff, 0xf1, -65, false);
|
|
LogCandidates(seeker);
|
|
|
|
VerifyOrQuit(seeker.mCandidates.GetLength() == 8);
|
|
VerifyOrQuit(seeker.mCandidates.IsFull());
|
|
|
|
VerifyOrQuit(!Contains(seeker, 0xaaaa, 0xa3));
|
|
|
|
VerifyOrQuit(Contains(seeker, 0xaaaa, 0xa1));
|
|
VerifyOrQuit(Contains(seeker, 0xaaaa, 0xa5));
|
|
VerifyOrQuit(Contains(seeker, 0xbbbb, 0xb1));
|
|
VerifyOrQuit(Contains(seeker, 0xbbbb, 0xb3));
|
|
VerifyOrQuit(Contains(seeker, 0xcccc, 0xc3));
|
|
VerifyOrQuit(Contains(seeker, 0xdddd, 0xd1));
|
|
VerifyOrQuit(Contains(seeker, 0xeeee, 0xe2));
|
|
VerifyOrQuit(Contains(seeker, 0xffff, 0xf1));
|
|
|
|
printf("Adding two new entries for new network -> should evict 0xa1 and 0xb1\n");
|
|
|
|
SaveCandidate(seeker, 0x1234, 0x01, -80, false);
|
|
SaveCandidate(seeker, 0x5678, 0x02, -70, false);
|
|
LogCandidates(seeker);
|
|
|
|
VerifyOrQuit(seeker.mCandidates.GetLength() == 8);
|
|
VerifyOrQuit(seeker.mCandidates.IsFull());
|
|
|
|
VerifyOrQuit(!Contains(seeker, 0xaaaa, 0xa1));
|
|
VerifyOrQuit(!Contains(seeker, 0xbbbb, 0xb1));
|
|
|
|
VerifyOrQuit(Contains(seeker, 0xaaaa, 0xa5));
|
|
VerifyOrQuit(Contains(seeker, 0xbbbb, 0xb3));
|
|
VerifyOrQuit(Contains(seeker, 0xcccc, 0xc3));
|
|
VerifyOrQuit(Contains(seeker, 0xdddd, 0xd1));
|
|
VerifyOrQuit(Contains(seeker, 0xeeee, 0xe2));
|
|
VerifyOrQuit(Contains(seeker, 0xffff, 0xf1));
|
|
VerifyOrQuit(Contains(seeker, 0x1234, 0x01));
|
|
VerifyOrQuit(Contains(seeker, 0x5678, 0x02));
|
|
|
|
printf("The candidates array is full and consists of distinct networks\n");
|
|
printf("Try adding a new entry for yet another network -> should be dropped\n");
|
|
|
|
SaveCandidate(seeker, 0xabcd, 0x03, -80, true);
|
|
LogCandidates(seeker);
|
|
|
|
VerifyOrQuit(seeker.mCandidates.GetLength() == 8);
|
|
VerifyOrQuit(seeker.mCandidates.IsFull());
|
|
|
|
VerifyOrQuit(Contains(seeker, 0xaaaa, 0xa5));
|
|
VerifyOrQuit(Contains(seeker, 0xbbbb, 0xb3));
|
|
VerifyOrQuit(Contains(seeker, 0xcccc, 0xc3));
|
|
VerifyOrQuit(Contains(seeker, 0xdddd, 0xd1));
|
|
VerifyOrQuit(Contains(seeker, 0xeeee, 0xe2));
|
|
VerifyOrQuit(Contains(seeker, 0xffff, 0xf1));
|
|
VerifyOrQuit(Contains(seeker, 0x1234, 0x01));
|
|
VerifyOrQuit(Contains(seeker, 0x5678, 0x02));
|
|
|
|
selectionOrder.Clear();
|
|
SuccessOrQuit(selectionOrder.PushBack(0xc3));
|
|
SuccessOrQuit(selectionOrder.PushBack(0xb3));
|
|
SuccessOrQuit(selectionOrder.PushBack(0xe2));
|
|
SuccessOrQuit(selectionOrder.PushBack(0xa5));
|
|
SuccessOrQuit(selectionOrder.PushBack(0xd1));
|
|
SuccessOrQuit(selectionOrder.PushBack(0xf1));
|
|
SuccessOrQuit(selectionOrder.PushBack(0x02));
|
|
SuccessOrQuit(selectionOrder.PushBack(0x01));
|
|
|
|
CheckSelection(seeker, selectionOrder);
|
|
|
|
printf("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n");
|
|
printf("Selection strategy\n\n");
|
|
|
|
seeker.Stop();
|
|
|
|
SaveCandidate(seeker, 0xdddd, 0xd1, -30, false);
|
|
SaveCandidate(seeker, 0xaaaa, 0xa1, -60, false);
|
|
SaveCandidate(seeker, 0xeeee, 0xe1, -30, true);
|
|
SaveCandidate(seeker, 0xbbbb, 0xb1, -65, true);
|
|
SaveCandidate(seeker, 0xaaaa, 0xa2, -40, false);
|
|
SaveCandidate(seeker, 0xcccc, 0xc1, -90, true);
|
|
SaveCandidate(seeker, 0xaaaa, 0xa3, -70, false);
|
|
SaveCandidate(seeker, 0xcccc, 0xc2, -40, false);
|
|
LogCandidates(seeker);
|
|
|
|
VerifyOrQuit(seeker.mCandidates.GetLength() == 8);
|
|
|
|
// First we should go through all distinct networks, starting
|
|
// with most favored over all. Then go through the extra
|
|
// backup candidates.
|
|
//
|
|
// For `0xaaaa`, we have 3 candidates:
|
|
// ext-addr:a2, ext-panid:aaaa, rssi:-40, prf:0, conn-attempted:0
|
|
// ext-addr:a1, ext-panid:aaaa, rssi:-60, prf:0, conn-attempted:0
|
|
// ext-addr:a3, ext-panid:aaaa, rssi:-70, prf:0, conn-attempted:0
|
|
//
|
|
// For `0xbbbb`, only one candidate:
|
|
// ext-addr:b1, ext-panid:bbbb, rssi:-65, prf:1, conn-attempted:0
|
|
//
|
|
// For `0xcccc`, we have two:
|
|
// ext-addr:c1, ext-panid:cccc, rssi:-90, prf:1, conn-attempted:0
|
|
// ext-addr:c2, ext-panid:cccc, rssi:-40, prf:0, conn-attempted:0
|
|
//
|
|
// For `0xdddd`, we have one:
|
|
// ext-addr:d1, ext-panid:dddd, rssi:-30, prf:0, conn-attempted:0
|
|
//
|
|
// For `0xeeee`, we have one:
|
|
// ext-addr:e1, ext-panid:eeee, rssi:-30, prf:1, conn-attempted:0
|
|
//
|
|
// We go through networks first
|
|
// - e1 has highest RSSI and also preferred
|
|
// - b1 is preferred with high RSSI
|
|
// - c1 is also preferred even though it has low RSSI
|
|
// - d1 has best RSSI among non-preferred
|
|
// - a2 would be next among all `0xaaaa` candidates
|
|
//
|
|
// Next we go through remaining candidates
|
|
// - c2, a1 and a3
|
|
|
|
selectionOrder.Clear();
|
|
SuccessOrQuit(selectionOrder.PushBack(0xe1));
|
|
SuccessOrQuit(selectionOrder.PushBack(0xb1));
|
|
SuccessOrQuit(selectionOrder.PushBack(0xc1));
|
|
SuccessOrQuit(selectionOrder.PushBack(0xd1));
|
|
SuccessOrQuit(selectionOrder.PushBack(0xa2));
|
|
SuccessOrQuit(selectionOrder.PushBack(0xc2));
|
|
SuccessOrQuit(selectionOrder.PushBack(0xa1));
|
|
SuccessOrQuit(selectionOrder.PushBack(0xa3));
|
|
|
|
CheckSelection(seeker, selectionOrder);
|
|
|
|
seeker.Stop();
|
|
|
|
// Adding two candidates for 3 networks (total 6)
|
|
|
|
SaveCandidate(seeker, 0xcccc, 0xc2, -92, true);
|
|
SaveCandidate(seeker, 0xaaaa, 0xa2, -76, true);
|
|
SaveCandidate(seeker, 0xbbbb, 0xb2, -56, false);
|
|
SaveCandidate(seeker, 0xbbbb, 0xb1, -55, false);
|
|
SaveCandidate(seeker, 0xcccc, 0xc1, -90, true);
|
|
SaveCandidate(seeker, 0xaaaa, 0xa1, -75, true);
|
|
LogCandidates(seeker);
|
|
|
|
VerifyOrQuit(seeker.mCandidates.GetLength() == 6);
|
|
|
|
selectionOrder.Clear();
|
|
SuccessOrQuit(selectionOrder.PushBack(0xa1));
|
|
SuccessOrQuit(selectionOrder.PushBack(0xc1));
|
|
SuccessOrQuit(selectionOrder.PushBack(0xb1));
|
|
SuccessOrQuit(selectionOrder.PushBack(0xa2));
|
|
SuccessOrQuit(selectionOrder.PushBack(0xc2));
|
|
SuccessOrQuit(selectionOrder.PushBack(0xb2));
|
|
|
|
CheckSelection(seeker, selectionOrder);
|
|
|
|
printf("\nTestSeekerCandidates() passed\n\n");
|
|
|
|
testFreeInstance(instance);
|
|
}
|
|
};
|
|
|
|
#endif // #if OPENTHREAD_CONFIG_SEEKER_ENABLE || OPENTHREAD_CONFIG_JOINER_ENABLE
|
|
|
|
} // namespace ot
|
|
|
|
int main(void)
|
|
{
|
|
#if OPENTHREAD_CONFIG_SEEKER_ENABLE || OPENTHREAD_CONFIG_JOINER_ENABLE
|
|
#if (OPENTHREAD_CONFIG_JOINER_MAX_CANDIDATES == 8)
|
|
ot::UnitTester::TestSeekerCandidates();
|
|
printf("All tests passed\n");
|
|
#else
|
|
printf("Skipping tests as the test expects `OPENTHREAD_CONFIG_JOINER_MAX_CANDIDATES` to be `8`\n");
|
|
printf("This config is specifically set to 8 in `toranj-config` for this test\n");
|
|
#endif
|
|
#else
|
|
printf("Seeker feature is disabled, skipping the test\n");
|
|
#endif
|
|
|
|
return 0;
|
|
}
|