mirror of
https://github.com/espressif/openthread.git
synced 2026-08-08 03:37:46 +00:00
[discover-scanner] adding Mle::DiscoverScanner (#5075)
This commit adds new class `DiscoverScanner` which implements the MLE Discover Scan process (moving and simplifying all the code related to this from `Mle` and `MeshForwarder` into same file/class).
This commit is contained in:
committed by
Jonathan Hui
parent
e653478c50
commit
54ad5a3960
@@ -241,6 +241,7 @@ LOCAL_SRC_FILES := \
|
||||
src/core/thread/announce_begin_server.cpp \
|
||||
src/core/thread/announce_sender.cpp \
|
||||
src/core/thread/child_table.cpp \
|
||||
src/core/thread/discover_scanner.cpp \
|
||||
src/core/thread/dua_manager.cpp \
|
||||
src/core/thread/energy_scan_server.cpp \
|
||||
src/core/thread/indirect_sender.cpp \
|
||||
|
||||
@@ -136,6 +136,7 @@ static_library("lib-ot-core") {
|
||||
"src/core/thread/announce_begin_server.cpp",
|
||||
"src/core/thread/announce_sender.cpp",
|
||||
"src/core/thread/child_table.cpp",
|
||||
"src/core/thread/discover_scanner.cpp",
|
||||
"src/core/thread/dua_manager.cpp",
|
||||
"src/core/thread/energy_scan_server.cpp",
|
||||
"src/core/thread/indirect_sender.cpp",
|
||||
|
||||
@@ -172,6 +172,7 @@ set(COMMON_SOURCES
|
||||
thread/announce_begin_server.cpp
|
||||
thread/announce_sender.cpp
|
||||
thread/child_table.cpp
|
||||
thread/discover_scanner.cpp
|
||||
thread/dua_manager.cpp
|
||||
thread/energy_scan_server.cpp
|
||||
thread/indirect_sender.cpp
|
||||
|
||||
@@ -214,6 +214,7 @@ SOURCES_COMMON = \
|
||||
thread/announce_begin_server.cpp \
|
||||
thread/announce_sender.cpp \
|
||||
thread/child_table.cpp \
|
||||
thread/discover_scanner.cpp \
|
||||
thread/dua_manager.cpp \
|
||||
thread/energy_scan_server.cpp \
|
||||
thread/indirect_sender.cpp \
|
||||
@@ -423,6 +424,7 @@ HEADERS_COMMON = \
|
||||
thread/announce_begin_server.hpp \
|
||||
thread/announce_sender.hpp \
|
||||
thread/child_table.hpp \
|
||||
thread/discover_scanner.hpp \
|
||||
thread/dua_manager.hpp \
|
||||
thread/energy_scan_server.hpp \
|
||||
thread/indirect_sender.hpp \
|
||||
|
||||
@@ -457,15 +457,15 @@ otError otThreadDiscover(otInstance * aInstance,
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.Get<Mle::MleRouter>().Discover(static_cast<Mac::ChannelMask>(aScanChannels), aPanId, aJoiner,
|
||||
aEnableEui64Filtering, aCallback, aCallbackContext);
|
||||
return instance.Get<Mle::DiscoverScanner>().Discover(static_cast<Mac::ChannelMask>(aScanChannels), aPanId, aJoiner,
|
||||
aEnableEui64Filtering, aCallback, aCallbackContext);
|
||||
}
|
||||
|
||||
bool otThreadIsDiscoverInProgress(otInstance *aInstance)
|
||||
{
|
||||
Instance &instance = *static_cast<Instance *>(aInstance);
|
||||
|
||||
return instance.Get<Mle::MleRouter>().IsDiscoverInProgress();
|
||||
return instance.Get<Mle::DiscoverScanner>().IsInProgress();
|
||||
}
|
||||
|
||||
const otIpCounters *otThreadGetIp6Counters(otInstance *aInstance)
|
||||
|
||||
@@ -438,6 +438,11 @@ template <> inline Mle::MleRouter &Instance::Get(void)
|
||||
return mThreadNetif.mMleRouter;
|
||||
}
|
||||
|
||||
template <> inline Mle::DiscoverScanner &Instance::Get(void)
|
||||
{
|
||||
return mThreadNetif.mDiscoverScanner;
|
||||
}
|
||||
|
||||
#if OPENTHREAD_FTD
|
||||
template <> inline ChildTable &Instance::Get(void)
|
||||
{
|
||||
|
||||
@@ -122,9 +122,9 @@ otError Joiner::Start(const char * aPskd,
|
||||
SuccessOrExit(error = PrepareJoinerFinalizeMessage(aProvisioningUrl, aVendorName, aVendorModel, aVendorSwVersion,
|
||||
aVendorData));
|
||||
|
||||
SuccessOrExit(error = Get<Mle::MleRouter>().Discover(Mac::ChannelMask(0), Get<Mac::Mac>().GetPanId(),
|
||||
/* aJoiner */ true, /* aEnableFiltering */ true,
|
||||
HandleDiscoverResult, this));
|
||||
SuccessOrExit(error = Get<Mle::DiscoverScanner>().Discover(Mac::ChannelMask(0), Get<Mac::Mac>().GetPanId(),
|
||||
/* aJoiner */ true, /* aEnableFiltering */ true,
|
||||
HandleDiscoverResult, this));
|
||||
mCallback = aCallback;
|
||||
mContext = aContext;
|
||||
|
||||
|
||||
@@ -0,0 +1,351 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file implements MLE Discover Scan process.
|
||||
*/
|
||||
|
||||
#include "discover_scanner.hpp"
|
||||
|
||||
#include "common/code_utils.hpp"
|
||||
#include "common/instance.hpp"
|
||||
#include "common/locator-getters.hpp"
|
||||
#include "common/logging.hpp"
|
||||
#include "thread/mesh_forwarder.hpp"
|
||||
#include "thread/mle.hpp"
|
||||
#include "thread/mle_router.hpp"
|
||||
|
||||
namespace ot {
|
||||
namespace Mle {
|
||||
|
||||
DiscoverScanner::DiscoverScanner(Instance &aInstance)
|
||||
: InstanceLocator(aInstance)
|
||||
, mHandler(NULL)
|
||||
, mHandlerContext(NULL)
|
||||
, mTimer(aInstance, DiscoverScanner::HandleTimer, this)
|
||||
, mFilterIndexes()
|
||||
, mScanChannels()
|
||||
, mState(kStateIdle)
|
||||
, mScanChannel(0)
|
||||
, mEnableFiltering(false)
|
||||
, mShouldRestorePanId(false)
|
||||
{
|
||||
}
|
||||
|
||||
otError DiscoverScanner::Discover(const Mac::ChannelMask &aScanChannels,
|
||||
uint16_t aPanId,
|
||||
bool aJoiner,
|
||||
bool aEnableFiltering,
|
||||
Handler aCallback,
|
||||
void * aContext)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
Message * message = NULL;
|
||||
Ip6::Address destination;
|
||||
MeshCoP::DiscoveryRequestTlv discoveryRequest;
|
||||
|
||||
VerifyOrExit(mState == kStateIdle, error = OT_ERROR_BUSY);
|
||||
|
||||
mEnableFiltering = aEnableFiltering;
|
||||
|
||||
if (mEnableFiltering)
|
||||
{
|
||||
Mac::ExtAddress extAddress;
|
||||
|
||||
Get<Radio>().GetIeeeEui64(extAddress);
|
||||
MeshCoP::ComputeJoinerId(extAddress, extAddress);
|
||||
|
||||
MeshCoP::SteeringData::CalculateHashBitIndexes(extAddress, mFilterIndexes);
|
||||
}
|
||||
|
||||
mHandler = aCallback;
|
||||
mHandlerContext = aContext;
|
||||
mShouldRestorePanId = false;
|
||||
mScanChannels = Get<Mac::Mac>().GetSupportedChannelMask();
|
||||
|
||||
if (!aScanChannels.IsEmpty())
|
||||
{
|
||||
mScanChannels.Intersect(aScanChannels);
|
||||
}
|
||||
|
||||
VerifyOrExit((message = Get<Mle>().NewMleMessage()) != NULL, error = OT_ERROR_NO_BUFS);
|
||||
message->SetSubType(Message::kSubTypeMleDiscoverRequest);
|
||||
message->SetPanId(aPanId);
|
||||
SuccessOrExit(error = Get<Mle>().AppendHeader(*message, Header::kCommandDiscoveryRequest));
|
||||
|
||||
// Append MLE Discovery TLV with a single sub-TLV (MeshCoP Discovery Request).
|
||||
discoveryRequest.Init();
|
||||
discoveryRequest.SetVersion(kThreadVersion);
|
||||
discoveryRequest.SetJoiner(aJoiner);
|
||||
|
||||
SuccessOrExit(error = Tlv::AppendTlv(*message, Tlv::kDiscovery, &discoveryRequest, sizeof(discoveryRequest)));
|
||||
|
||||
destination.SetToLinkLocalAllRoutersMulticast();
|
||||
|
||||
SuccessOrExit(error = Get<Mle>().SendMessage(*message, destination));
|
||||
|
||||
if ((aPanId == Mac::kPanIdBroadcast) && (Get<Mac::Mac>().GetPanId() == Mac::kPanIdBroadcast))
|
||||
{
|
||||
// In case a specific PAN ID of a Thread Network to be
|
||||
// discovered is not known, Discovery Request messages MUST
|
||||
// have the Destination PAN ID in the IEEE 802.15.4 MAC
|
||||
// header set to be the Broadcast PAN ID (0xffff) and the
|
||||
// Source PAN ID set to a randomly generated value.
|
||||
|
||||
Get<Mac::Mac>().SetPanId(Mac::GenerateRandomPanId());
|
||||
mShouldRestorePanId = true;
|
||||
}
|
||||
|
||||
mScanChannel = Mac::ChannelMask::kChannelIteratorFirst;
|
||||
mState = (mScanChannels.GetNextChannel(mScanChannel) == OT_ERROR_NONE) ? kStateScanning : kStateScanDone;
|
||||
|
||||
otLogInfoMle("Send Discovery Request (%s)", destination.ToString().AsCString());
|
||||
|
||||
exit:
|
||||
|
||||
if (error != OT_ERROR_NONE && message != NULL)
|
||||
{
|
||||
message->Free();
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
otError DiscoverScanner::PrepareDiscoveryRequestFrame(Mac::TxFrame &aFrame)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
switch (mState)
|
||||
{
|
||||
case kStateIdle:
|
||||
case kStateScanDone:
|
||||
// If scan is finished (no more channels to scan), abort the
|
||||
// Discovery Request frame tx. The handler callback is invoked &
|
||||
// state is cleared from `HandleDiscoveryRequestFrameTxDone()`.
|
||||
error = OT_ERROR_ABORT;
|
||||
break;
|
||||
|
||||
case kStateScanning:
|
||||
aFrame.SetChannel(mScanChannel);
|
||||
IgnoreError(Get<Mac::Mac>().SetTemporaryChannel(mScanChannel));
|
||||
break;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void DiscoverScanner::HandleDiscoveryRequestFrameTxDone(Message &aMessage)
|
||||
{
|
||||
switch (mState)
|
||||
{
|
||||
case kStateIdle:
|
||||
break;
|
||||
|
||||
case kStateScanning:
|
||||
// Mark the Discovery Request message for direct tx to ensure it
|
||||
// is not dequeued and freed by `MeshForwarder` and is ready for
|
||||
// the next scan channel. Also pause message tx on `MeshForwarder`
|
||||
// while listening to receive Discovery Responses.
|
||||
aMessage.SetDirectTransmission();
|
||||
Get<MeshForwarder>().PauseMessageTransmissions();
|
||||
mTimer.Start(kDefaultScanDuration);
|
||||
break;
|
||||
|
||||
case kStateScanDone:
|
||||
HandleDiscoverComplete();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DiscoverScanner::HandleDiscoverComplete(void)
|
||||
{
|
||||
switch (mState)
|
||||
{
|
||||
case kStateIdle:
|
||||
break;
|
||||
|
||||
case kStateScanning:
|
||||
mTimer.Stop();
|
||||
Get<MeshForwarder>().ResumeMessageTransmissions();
|
||||
|
||||
// Fall through
|
||||
|
||||
case kStateScanDone:
|
||||
Get<Mac::Mac>().ClearTemporaryChannel();
|
||||
|
||||
if (mShouldRestorePanId)
|
||||
{
|
||||
Get<Mac::Mac>().SetPanId(Mac::kPanIdBroadcast);
|
||||
mShouldRestorePanId = false;
|
||||
}
|
||||
|
||||
mState = kStateIdle;
|
||||
|
||||
if (mHandler)
|
||||
{
|
||||
mHandler(NULL, mHandlerContext);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DiscoverScanner::HandleTimer(Timer &aTimer)
|
||||
{
|
||||
aTimer.GetOwner<DiscoverScanner>().HandleTimer();
|
||||
}
|
||||
|
||||
void DiscoverScanner::HandleTimer(void)
|
||||
{
|
||||
VerifyOrExit(mState == kStateScanning, OT_NOOP);
|
||||
|
||||
// Move to next scan channel and resume message transmissions on
|
||||
// `MeshForwarder` so that the queued MLE Discovery Request message
|
||||
// is prepared again for the next scan channel. If no more channel
|
||||
// to scan, change the state to `kStateScanDone` which ensures the
|
||||
// frame tx is aborted from `PrepareDiscoveryRequestFrame()` and
|
||||
// then wraps up the scan (invoking handler callback).
|
||||
|
||||
if (mScanChannels.GetNextChannel(mScanChannel) != OT_ERROR_NONE)
|
||||
{
|
||||
mState = kStateScanDone;
|
||||
}
|
||||
|
||||
Get<MeshForwarder>().ResumeMessageTransmissions();
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void DiscoverScanner::HandleDiscoveryResponse(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo) const
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
const otThreadLinkInfo * linkInfo = static_cast<const otThreadLinkInfo *>(aMessageInfo.GetLinkInfo());
|
||||
Tlv tlv;
|
||||
MeshCoP::Tlv meshcopTlv;
|
||||
MeshCoP::DiscoveryResponseTlv discoveryResponse;
|
||||
MeshCoP::NetworkNameTlv networkName;
|
||||
ScanResult result;
|
||||
uint16_t offset;
|
||||
uint16_t end;
|
||||
bool didCheckSteeringData = false;
|
||||
|
||||
otLogInfoMle("Receive Discovery Response (%s)", aMessageInfo.GetPeerAddr().ToString().AsCString());
|
||||
|
||||
VerifyOrExit(mState == kStateScanning, error = OT_ERROR_DROP);
|
||||
|
||||
// Find MLE Discovery TLV
|
||||
VerifyOrExit(Tlv::FindTlvOffset(aMessage, Tlv::kDiscovery, offset) == OT_ERROR_NONE, error = OT_ERROR_PARSE);
|
||||
aMessage.Read(offset, sizeof(tlv), &tlv);
|
||||
|
||||
offset += sizeof(tlv);
|
||||
end = offset + tlv.GetLength();
|
||||
|
||||
memset(&result, 0, sizeof(result));
|
||||
result.mPanId = linkInfo->mPanId;
|
||||
result.mChannel = linkInfo->mChannel;
|
||||
result.mRssi = linkInfo->mRss;
|
||||
result.mLqi = linkInfo->mLqi;
|
||||
aMessageInfo.GetPeerAddr().ToExtAddress(*static_cast<Mac::ExtAddress *>(&result.mExtAddress));
|
||||
|
||||
// Process MeshCoP TLVs
|
||||
while (offset < end)
|
||||
{
|
||||
aMessage.Read(offset, sizeof(meshcopTlv), &meshcopTlv);
|
||||
|
||||
switch (meshcopTlv.GetType())
|
||||
{
|
||||
case MeshCoP::Tlv::kDiscoveryResponse:
|
||||
aMessage.Read(offset, sizeof(discoveryResponse), &discoveryResponse);
|
||||
VerifyOrExit(discoveryResponse.IsValid(), error = OT_ERROR_PARSE);
|
||||
result.mVersion = discoveryResponse.GetVersion();
|
||||
result.mIsNative = discoveryResponse.IsNativeCommissioner();
|
||||
break;
|
||||
|
||||
case MeshCoP::Tlv::kExtendedPanId:
|
||||
SuccessOrExit(error = Tlv::ReadTlv(aMessage, offset, &result.mExtendedPanId, sizeof(Mac::ExtendedPanId)));
|
||||
break;
|
||||
|
||||
case MeshCoP::Tlv::kNetworkName:
|
||||
aMessage.Read(offset, sizeof(networkName), &networkName);
|
||||
IgnoreError(static_cast<Mac::NetworkName &>(result.mNetworkName).Set(networkName.GetNetworkName()));
|
||||
break;
|
||||
|
||||
case MeshCoP::Tlv::kSteeringData:
|
||||
if (meshcopTlv.GetLength() > 0)
|
||||
{
|
||||
MeshCoP::SteeringData &steeringData = static_cast<MeshCoP::SteeringData &>(result.mSteeringData);
|
||||
uint8_t dataLength = MeshCoP::SteeringData::kMaxLength;
|
||||
|
||||
if (meshcopTlv.GetLength() < dataLength)
|
||||
{
|
||||
dataLength = meshcopTlv.GetLength();
|
||||
}
|
||||
|
||||
steeringData.Init(dataLength);
|
||||
|
||||
SuccessOrExit(error = Tlv::ReadTlv(aMessage, offset, steeringData.GetData(), dataLength));
|
||||
|
||||
if (mEnableFiltering)
|
||||
{
|
||||
VerifyOrExit(steeringData.Contains(mFilterIndexes), OT_NOOP);
|
||||
}
|
||||
|
||||
didCheckSteeringData = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case MeshCoP::Tlv::kJoinerUdpPort:
|
||||
SuccessOrExit(error = Tlv::ReadUint16Tlv(aMessage, offset, result.mJoinerUdpPort));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
offset += sizeof(meshcopTlv) + meshcopTlv.GetLength();
|
||||
}
|
||||
|
||||
VerifyOrExit(!mEnableFiltering || didCheckSteeringData, OT_NOOP);
|
||||
|
||||
if (mHandler)
|
||||
{
|
||||
mHandler(&result, mHandlerContext);
|
||||
}
|
||||
|
||||
exit:
|
||||
|
||||
if (error != OT_ERROR_NONE)
|
||||
{
|
||||
otLogWarnMle("Failed to process Discovery Response: %s", otThreadErrorToString(error));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Mle
|
||||
} // namespace ot
|
||||
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2020, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file includes definitions for MLE Discover Scan process.
|
||||
*/
|
||||
|
||||
#ifndef DISCOVER_SCANNER_HPP_
|
||||
#define DISCOVER_SCANNER_HPP_
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#include "common/locator.hpp"
|
||||
#include "common/timer.hpp"
|
||||
#include "mac/channel_mask.hpp"
|
||||
#include "mac/mac.hpp"
|
||||
#include "mac/mac_types.hpp"
|
||||
#include "meshcop/meshcop.hpp"
|
||||
#include "thread/mle.hpp"
|
||||
|
||||
namespace ot {
|
||||
|
||||
class MeshForwarder;
|
||||
|
||||
namespace Mle {
|
||||
|
||||
/**
|
||||
* This class implements MLE Discover Scan.
|
||||
*
|
||||
*/
|
||||
class DiscoverScanner : public InstanceLocator
|
||||
{
|
||||
friend class ot::Instance;
|
||||
friend class ot::MeshForwarder;
|
||||
friend class Mle;
|
||||
|
||||
public:
|
||||
enum
|
||||
{
|
||||
kDefaultScanDuration = Mac::kScanDurationDefault, ///< Default scan duration (per channel), in milliseconds.
|
||||
};
|
||||
|
||||
/**
|
||||
* This type represents Discover Scan result.
|
||||
*
|
||||
*/
|
||||
typedef otActiveScanResult ScanResult;
|
||||
|
||||
/**
|
||||
* This type represents the handler function pointer called with any Discover Scan result or when the scan
|
||||
* completes.
|
||||
*
|
||||
* The handler function format is `void (*oHandler)(ScanResult *aResult, void *aContext);`. End of scan is
|
||||
* indicated by `aResult` pointer being set to NULL.
|
||||
*
|
||||
*/
|
||||
typedef otHandleActiveScanResult Handler;
|
||||
|
||||
/**
|
||||
* This constructor initializes the object.
|
||||
*
|
||||
* @param[in] aInstance A reference to the OpenThread instance.
|
||||
*
|
||||
*/
|
||||
explicit DiscoverScanner(Instance &aInstance);
|
||||
|
||||
/**
|
||||
* This method starts a Thread Discovery Scan.
|
||||
*
|
||||
* @param[in] aScanChannels Channel mask listing channels to scan (if empty, use all supported channels).
|
||||
* @param[in] aPanId The PAN ID filter (set to Broadcast PAN to disable filter).
|
||||
* @param[in] aJoiner Value of the Joiner Flag in the Discovery Request TLV.
|
||||
* @param[in] aEnableFiltering Enable filtering MLE Discovery Responses that don't match our factory EUI64.
|
||||
* @param[in] aHandler A pointer to a function that is called on receiving an MLE Discovery Response.
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully started a Thread Discovery Scan.
|
||||
* @retval OT_ERROR_NO_BUFS Could not allocate message for Discovery Request.
|
||||
* @retval OT_ERROR_BUSY Thread Discovery Scan is already in progress.
|
||||
*
|
||||
*/
|
||||
otError Discover(const Mac::ChannelMask &aScanChannels,
|
||||
Mac::PanId aPanId,
|
||||
bool aJoiner,
|
||||
bool aEnableFiltering,
|
||||
Handler aHandler,
|
||||
void * aContext);
|
||||
|
||||
/**
|
||||
* This method indicates whether or not an MLE Thread Discovery Scan is currently in progress.
|
||||
*
|
||||
* @returns true if an MLE Thread Discovery Scan is in progress, false otherwise.
|
||||
*
|
||||
*/
|
||||
bool IsInProgress(void) const { return (mState != kStateIdle); }
|
||||
|
||||
private:
|
||||
enum State
|
||||
{
|
||||
kStateIdle,
|
||||
kStateScanning,
|
||||
kStateScanDone,
|
||||
};
|
||||
|
||||
// Methods used by `MeshForwarder`
|
||||
otError PrepareDiscoveryRequestFrame(Mac::TxFrame &aFrame);
|
||||
void HandleDiscoveryRequestFrameTxDone(Message &aMessage);
|
||||
void Stop(void) { HandleDiscoverComplete(); }
|
||||
|
||||
// Methods used from `Mle`
|
||||
void HandleDiscoveryResponse(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo) const;
|
||||
|
||||
void HandleDiscoverComplete(void);
|
||||
static void HandleTimer(Timer &aTimer);
|
||||
void HandleTimer(void);
|
||||
|
||||
Handler mHandler;
|
||||
void * mHandlerContext;
|
||||
TimerMilli mTimer;
|
||||
MeshCoP::SteeringData::HashBitIndexes mFilterIndexes;
|
||||
Mac::ChannelMask mScanChannels;
|
||||
State mState;
|
||||
uint8_t mScanChannel;
|
||||
bool mEnableFiltering : 1;
|
||||
bool mShouldRestorePanId : 1;
|
||||
};
|
||||
|
||||
} // namespace Mle
|
||||
} // namespace ot
|
||||
|
||||
#endif // DISCOVER_SCANNER_HPP_
|
||||
@@ -57,20 +57,16 @@ namespace ot {
|
||||
|
||||
MeshForwarder::MeshForwarder(Instance &aInstance)
|
||||
: InstanceLocator(aInstance)
|
||||
, mDiscoverTimer(aInstance, MeshForwarder::HandleDiscoverTimer, this)
|
||||
, mUpdateTimer(aInstance, MeshForwarder::HandleUpdateTimer, this)
|
||||
, mMessageNextOffset(0)
|
||||
, mSendMessage(NULL)
|
||||
, mMeshSource()
|
||||
, mMeshDest()
|
||||
, mAddMeshHeader(false)
|
||||
, mEnabled(false)
|
||||
, mTxPaused(false)
|
||||
, mSendBusy(false)
|
||||
, mScheduleTransmissionTask(aInstance, ScheduleTransmissionTask, this)
|
||||
, mEnabled(false)
|
||||
, mScanChannels(0)
|
||||
, mScanChannel(0)
|
||||
, mRestorePanId(Mac::kPanIdBroadcast)
|
||||
, mScanning(false)
|
||||
#if OPENTHREAD_FTD
|
||||
, mIndirectSender(aInstance)
|
||||
#endif
|
||||
@@ -106,11 +102,7 @@ void MeshForwarder::Stop(void)
|
||||
|
||||
mDataPollSender.StopPolling();
|
||||
mUpdateTimer.Stop();
|
||||
|
||||
if (mScanning)
|
||||
{
|
||||
HandleDiscoverComplete();
|
||||
}
|
||||
Get<Mle::DiscoverScanner>().Stop();
|
||||
|
||||
while ((message = mSendQueue.GetHead()) != NULL)
|
||||
{
|
||||
@@ -163,6 +155,15 @@ void MeshForwarder::RemoveMessage(Message &aMessage)
|
||||
aMessage.Free();
|
||||
}
|
||||
|
||||
void MeshForwarder::ResumeMessageTransmissions(void)
|
||||
{
|
||||
if (mTxPaused)
|
||||
{
|
||||
mTxPaused = false;
|
||||
mScheduleTransmissionTask.Post();
|
||||
}
|
||||
}
|
||||
|
||||
void MeshForwarder::ScheduleTransmissionTask(Tasklet &aTasklet)
|
||||
{
|
||||
aTasklet.GetOwner<MeshForwarder>().ScheduleTransmissionTask();
|
||||
@@ -170,7 +171,7 @@ void MeshForwarder::ScheduleTransmissionTask(Tasklet &aTasklet)
|
||||
|
||||
void MeshForwarder::ScheduleTransmissionTask(void)
|
||||
{
|
||||
VerifyOrExit(!mSendBusy, OT_NOOP);
|
||||
VerifyOrExit(!mSendBusy && !mTxPaused, OT_NOOP);
|
||||
|
||||
mSendMessage = GetDirectTransmission();
|
||||
VerifyOrExit(mSendMessage != NULL, OT_NOOP);
|
||||
@@ -186,27 +187,6 @@ exit:
|
||||
return;
|
||||
}
|
||||
|
||||
otError MeshForwarder::PrepareDiscoverRequest(void)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
VerifyOrExit(!mScanning, OT_NOOP);
|
||||
|
||||
mScanChannel = Mac::ChannelMask::kChannelIteratorFirst;
|
||||
mRestorePanId = Get<Mac::Mac>().GetPanId();
|
||||
|
||||
mScanning = true;
|
||||
|
||||
if (mScanChannels.GetNextChannel(mScanChannel) != OT_ERROR_NONE)
|
||||
{
|
||||
HandleDiscoverComplete();
|
||||
ExitNow(error = OT_ERROR_DROP);
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
Message *MeshForwarder::GetDirectTransmission(void)
|
||||
{
|
||||
Message *curMessage, *nextMessage;
|
||||
@@ -226,12 +206,6 @@ Message *MeshForwarder::GetDirectTransmission(void)
|
||||
{
|
||||
case Message::kTypeIp6:
|
||||
error = UpdateIp6Route(*curMessage);
|
||||
|
||||
if (curMessage->GetSubType() == Message::kSubTypeMleDiscoverRequest)
|
||||
{
|
||||
error = PrepareDiscoverRequest();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
#if OPENTHREAD_FTD
|
||||
@@ -436,18 +410,7 @@ otError MeshForwarder::HandleFrameRequest(Mac::TxFrame &aFrame)
|
||||
case Message::kTypeIp6:
|
||||
if (mSendMessage->GetSubType() == Message::kSubTypeMleDiscoverRequest)
|
||||
{
|
||||
SuccessOrExit(error = Get<Mac::Mac>().SetTemporaryChannel(mScanChannel));
|
||||
|
||||
aFrame.SetChannel(mScanChannel);
|
||||
|
||||
// In case a specific PAN ID of a Thread Network to be discovered is not known, Discovery
|
||||
// Request messages MUST have the Destination PAN ID in the IEEE 802.15.4 MAC header set
|
||||
// to be the Broadcast PAN ID (0xFFFF) and the Source PAN ID set to a randomly generated
|
||||
// value.
|
||||
if (mSendMessage->GetPanId() == Mac::kPanIdBroadcast && Get<Mac::Mac>().GetPanId() == Mac::kPanIdBroadcast)
|
||||
{
|
||||
Get<Mac::Mac>().SetPanId(Mac::GenerateRandomPanId());
|
||||
}
|
||||
SuccessOrExit(error = Get<Mle::DiscoverScanner>().PrepareDiscoveryRequestFrame(aFrame));
|
||||
}
|
||||
|
||||
mMessageNextOffset =
|
||||
@@ -887,9 +850,7 @@ void MeshForwarder::HandleSentFrame(Mac::TxFrame &aFrame, otError aError)
|
||||
|
||||
if (mSendMessage->GetSubType() == Message::kSubTypeMleDiscoverRequest)
|
||||
{
|
||||
mSendBusy = true;
|
||||
mDiscoverTimer.Start(static_cast<uint16_t>(Mac::kScanDurationDefault));
|
||||
ExitNow();
|
||||
Get<Mle::DiscoverScanner>().HandleDiscoveryRequestFrameTxDone(*mSendMessage);
|
||||
}
|
||||
|
||||
if (!mSendMessage->GetDirectTransmission() && !mSendMessage->IsChildPending())
|
||||
@@ -920,50 +881,6 @@ exit:
|
||||
}
|
||||
}
|
||||
|
||||
void MeshForwarder::SetDiscoverParameters(const Mac::ChannelMask &aScanChannels)
|
||||
{
|
||||
uint32_t mask;
|
||||
uint32_t supportedMask = Get<Mac::Mac>().GetSupportedChannelMask().GetMask();
|
||||
|
||||
mask = aScanChannels.IsEmpty() ? supportedMask : aScanChannels.GetMask();
|
||||
mScanChannels.SetMask(mask & supportedMask);
|
||||
}
|
||||
|
||||
void MeshForwarder::HandleDiscoverTimer(Timer &aTimer)
|
||||
{
|
||||
aTimer.GetOwner<MeshForwarder>().HandleDiscoverTimer();
|
||||
}
|
||||
|
||||
void MeshForwarder::HandleDiscoverTimer(void)
|
||||
{
|
||||
if (mScanChannels.GetNextChannel(mScanChannel) != OT_ERROR_NONE)
|
||||
{
|
||||
mSendQueue.Dequeue(*mSendMessage);
|
||||
mSendMessage->Free();
|
||||
mSendMessage = NULL;
|
||||
|
||||
HandleDiscoverComplete();
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
mSendMessage->SetDirectTransmission();
|
||||
|
||||
exit:
|
||||
mSendBusy = false;
|
||||
mScheduleTransmissionTask.Post();
|
||||
}
|
||||
|
||||
void MeshForwarder::HandleDiscoverComplete(void)
|
||||
{
|
||||
OT_ASSERT(mScanning);
|
||||
|
||||
Get<Mac::Mac>().ClearTemporaryChannel();
|
||||
Get<Mac::Mac>().SetPanId(mRestorePanId);
|
||||
mScanning = false;
|
||||
Get<Mle::MleRouter>().HandleDiscoverComplete();
|
||||
mDiscoverTimer.Stop();
|
||||
}
|
||||
|
||||
void MeshForwarder::HandleReceivedFrame(Mac::RxFrame &aFrame)
|
||||
{
|
||||
otThreadLinkInfo linkInfo;
|
||||
|
||||
@@ -50,6 +50,10 @@
|
||||
|
||||
namespace ot {
|
||||
|
||||
namespace Mle {
|
||||
class DiscoverScanner;
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
kReassemblyTimeout = OPENTHREAD_CONFIG_6LOWPAN_REASSEMBLY_TIMEOUT,
|
||||
@@ -171,6 +175,7 @@ class MeshForwarder : public InstanceLocator
|
||||
friend class Instance;
|
||||
friend class DataPollSender;
|
||||
friend class IndirectSender;
|
||||
friend class Mle::DiscoverScanner;
|
||||
|
||||
public:
|
||||
/**
|
||||
@@ -312,7 +317,6 @@ public:
|
||||
*/
|
||||
const PriorityQueue &GetResolvingQueue(void) const { return mResolvingQueue; }
|
||||
#endif
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
@@ -368,7 +372,6 @@ private:
|
||||
void GetMacDestinationAddress(const Ip6::Address &aIp6Addr, Mac::Address &aMacAddr);
|
||||
void GetMacSourceAddress(const Ip6::Address &aIp6Addr, Mac::Address &aMacAddr);
|
||||
Message *GetDirectTransmission(void);
|
||||
otError PrepareDiscoverRequest(void);
|
||||
void HandleMesh(uint8_t * aFrame,
|
||||
uint16_t aFrameLength,
|
||||
const Mac::Address & aMacSource,
|
||||
@@ -438,6 +441,9 @@ private:
|
||||
|
||||
otError GetDestinationRlocByServiceAloc(uint16_t aServiceAloc, uint16_t &aMeshDest);
|
||||
|
||||
void PauseMessageTransmissions(void) { mTxPaused = true; }
|
||||
void ResumeMessageTransmissions(void);
|
||||
|
||||
void LogMessage(MessageAction aAction, const Message &aMessage, const Mac::Address *aAddress, otError aError);
|
||||
void LogFrame(const char *aActionText, const Mac::Frame &aFrame, otError aError);
|
||||
void LogFragmentFrameDrop(otError aError,
|
||||
@@ -500,7 +506,6 @@ private:
|
||||
otLogLevel aLogLevel);
|
||||
#endif // #if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_NOTE) && (OPENTHREAD_CONFIG_LOG_MAC == 1)
|
||||
|
||||
TimerMilli mDiscoverTimer;
|
||||
TimerMilli mUpdateTimer;
|
||||
|
||||
PriorityQueue mSendQueue;
|
||||
@@ -514,17 +519,12 @@ private:
|
||||
Mac::Address mMacDest;
|
||||
uint16_t mMeshSource;
|
||||
uint16_t mMeshDest;
|
||||
bool mAddMeshHeader;
|
||||
|
||||
bool mSendBusy;
|
||||
bool mAddMeshHeader : 1;
|
||||
bool mEnabled : 1;
|
||||
bool mTxPaused : 1;
|
||||
bool mSendBusy : 1;
|
||||
|
||||
Tasklet mScheduleTransmissionTask;
|
||||
bool mEnabled;
|
||||
|
||||
Mac::ChannelMask mScanChannels;
|
||||
uint8_t mScanChannel;
|
||||
uint16_t mRestorePanId;
|
||||
bool mScanning;
|
||||
|
||||
otIpCounters mIpCounters;
|
||||
|
||||
|
||||
+1
-173
@@ -91,10 +91,6 @@ Mle::Mle(Instance &aInstance)
|
||||
, mReceivedResponseFromParent(false)
|
||||
, mSocket(aInstance.Get<Ip6::Udp>())
|
||||
, mTimeout(kMleEndDeviceTimeout)
|
||||
, mDiscoverHandler(NULL)
|
||||
, mDiscoverContext(NULL)
|
||||
, mDiscoverInProgress(false)
|
||||
, mDiscoverEnableFiltering(false)
|
||||
#if OPENTHREAD_CONFIG_MLE_INFORM_PREVIOUS_PARENT_ON_REATTACH
|
||||
, mPreviousParentRloc(Mac::kShortAddrInvalid)
|
||||
#endif
|
||||
@@ -511,73 +507,6 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError Mle::Discover(const Mac::ChannelMask &aScanChannels,
|
||||
uint16_t aPanId,
|
||||
bool aJoiner,
|
||||
bool aEnableFiltering,
|
||||
DiscoverHandler aCallback,
|
||||
void * aContext)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
Message * message = NULL;
|
||||
Ip6::Address destination;
|
||||
MeshCoP::DiscoveryRequestTlv discoveryRequest;
|
||||
|
||||
VerifyOrExit(!mDiscoverInProgress, error = OT_ERROR_BUSY);
|
||||
|
||||
mDiscoverEnableFiltering = aEnableFiltering;
|
||||
|
||||
if (mDiscoverEnableFiltering)
|
||||
{
|
||||
Mac::ExtAddress extAddress;
|
||||
|
||||
Get<Radio>().GetIeeeEui64(extAddress);
|
||||
MeshCoP::ComputeJoinerId(extAddress, extAddress);
|
||||
|
||||
MeshCoP::SteeringData::CalculateHashBitIndexes(extAddress, mDiscoverFilterIndexes);
|
||||
}
|
||||
|
||||
mDiscoverHandler = aCallback;
|
||||
mDiscoverContext = aContext;
|
||||
Get<MeshForwarder>().SetDiscoverParameters(aScanChannels);
|
||||
|
||||
VerifyOrExit((message = NewMleMessage()) != NULL, error = OT_ERROR_NO_BUFS);
|
||||
message->SetSubType(Message::kSubTypeMleDiscoverRequest);
|
||||
message->SetPanId(aPanId);
|
||||
SuccessOrExit(error = AppendHeader(*message, Header::kCommandDiscoveryRequest));
|
||||
|
||||
// Append MLE Discovery TLV with a single sub-TLV (MeshCoP Discovery Request).
|
||||
discoveryRequest.Init();
|
||||
discoveryRequest.SetVersion(kThreadVersion);
|
||||
discoveryRequest.SetJoiner(aJoiner);
|
||||
|
||||
SuccessOrExit(error = Tlv::AppendTlv(*message, Tlv::kDiscovery, &discoveryRequest, sizeof(discoveryRequest)));
|
||||
|
||||
destination.SetToLinkLocalAllRoutersMulticast();
|
||||
|
||||
SuccessOrExit(error = SendMessage(*message, destination));
|
||||
|
||||
mDiscoverInProgress = true;
|
||||
|
||||
LogMleMessage("Send Discovery Request", destination);
|
||||
|
||||
exit:
|
||||
|
||||
if (error != OT_ERROR_NONE && message != NULL)
|
||||
{
|
||||
message->Free();
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void Mle::HandleDiscoverComplete(void)
|
||||
{
|
||||
mDiscoverInProgress = false;
|
||||
mDiscoverEnableFiltering = false;
|
||||
mDiscoverHandler(NULL, mDiscoverContext);
|
||||
}
|
||||
|
||||
otError Mle::BecomeDetached(void)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
@@ -2625,7 +2554,7 @@ void Mle::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageIn
|
||||
#endif
|
||||
|
||||
case Header::kCommandDiscoveryResponse:
|
||||
HandleDiscoveryResponse(aMessage, aMessageInfo);
|
||||
Get<DiscoverScanner>().HandleDiscoveryResponse(aMessage, aMessageInfo);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -3840,107 +3769,6 @@ void Mle::ProcessAnnounce(void)
|
||||
IgnoreError(Start(/* aAnnounceAttach */ true));
|
||||
}
|
||||
|
||||
void Mle::HandleDiscoveryResponse(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
const otThreadLinkInfo * linkInfo = static_cast<const otThreadLinkInfo *>(aMessageInfo.GetLinkInfo());
|
||||
Tlv tlv;
|
||||
MeshCoP::Tlv meshcopTlv;
|
||||
MeshCoP::DiscoveryResponseTlv discoveryResponse;
|
||||
MeshCoP::NetworkNameTlv networkName;
|
||||
otActiveScanResult result;
|
||||
uint16_t offset;
|
||||
uint16_t end;
|
||||
bool didCheckSteeringData = false;
|
||||
|
||||
LogMleMessage("Receive Discovery Response", aMessageInfo.GetPeerAddr());
|
||||
|
||||
VerifyOrExit(mDiscoverInProgress, error = OT_ERROR_DROP);
|
||||
|
||||
// find MLE Discovery TLV
|
||||
VerifyOrExit(Tlv::FindTlvOffset(aMessage, Tlv::kDiscovery, offset) == OT_ERROR_NONE, error = OT_ERROR_PARSE);
|
||||
aMessage.Read(offset, sizeof(tlv), &tlv);
|
||||
|
||||
offset += sizeof(tlv);
|
||||
end = offset + tlv.GetLength();
|
||||
|
||||
memset(&result, 0, sizeof(result));
|
||||
result.mPanId = linkInfo->mPanId;
|
||||
result.mChannel = linkInfo->mChannel;
|
||||
result.mRssi = linkInfo->mRss;
|
||||
result.mLqi = linkInfo->mLqi;
|
||||
aMessageInfo.GetPeerAddr().ToExtAddress(*static_cast<Mac::ExtAddress *>(&result.mExtAddress));
|
||||
|
||||
// process MeshCoP TLVs
|
||||
while (offset < end)
|
||||
{
|
||||
aMessage.Read(offset, sizeof(meshcopTlv), &meshcopTlv);
|
||||
|
||||
switch (meshcopTlv.GetType())
|
||||
{
|
||||
case MeshCoP::Tlv::kDiscoveryResponse:
|
||||
aMessage.Read(offset, sizeof(discoveryResponse), &discoveryResponse);
|
||||
VerifyOrExit(discoveryResponse.IsValid(), error = OT_ERROR_PARSE);
|
||||
result.mVersion = discoveryResponse.GetVersion();
|
||||
result.mIsNative = discoveryResponse.IsNativeCommissioner();
|
||||
break;
|
||||
|
||||
case MeshCoP::Tlv::kExtendedPanId:
|
||||
SuccessOrExit(error = Tlv::ReadTlv(aMessage, offset, &result.mExtendedPanId, sizeof(Mac::ExtendedPanId)));
|
||||
break;
|
||||
|
||||
case MeshCoP::Tlv::kNetworkName:
|
||||
aMessage.Read(offset, sizeof(networkName), &networkName);
|
||||
IgnoreError(static_cast<Mac::NetworkName &>(result.mNetworkName).Set(networkName.GetNetworkName()));
|
||||
break;
|
||||
|
||||
case MeshCoP::Tlv::kSteeringData:
|
||||
if (meshcopTlv.GetLength() > 0)
|
||||
{
|
||||
MeshCoP::SteeringData &steeringData = static_cast<MeshCoP::SteeringData &>(result.mSteeringData);
|
||||
uint8_t dataLength = MeshCoP::SteeringData::kMaxLength;
|
||||
|
||||
if (meshcopTlv.GetLength() < dataLength)
|
||||
{
|
||||
dataLength = meshcopTlv.GetLength();
|
||||
}
|
||||
|
||||
steeringData.Init(dataLength);
|
||||
|
||||
SuccessOrExit(error = Tlv::ReadTlv(aMessage, offset, steeringData.GetData(), dataLength));
|
||||
|
||||
if (mDiscoverEnableFiltering)
|
||||
{
|
||||
VerifyOrExit(steeringData.Contains(mDiscoverFilterIndexes), OT_NOOP);
|
||||
}
|
||||
|
||||
didCheckSteeringData = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case MeshCoP::Tlv::kJoinerUdpPort:
|
||||
SuccessOrExit(error = Tlv::ReadUint16Tlv(aMessage, offset, result.mJoinerUdpPort));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
offset += sizeof(meshcopTlv) + meshcopTlv.GetLength();
|
||||
}
|
||||
|
||||
VerifyOrExit(!mDiscoverEnableFiltering || didCheckSteeringData, OT_NOOP);
|
||||
|
||||
mDiscoverHandler(&result, mDiscoverContext);
|
||||
|
||||
exit:
|
||||
|
||||
if (error != OT_ERROR_NONE)
|
||||
{
|
||||
otLogWarnMle("Failed to process Discovery Response: %s", otThreadErrorToString(error));
|
||||
}
|
||||
}
|
||||
|
||||
Neighbor *Mle::GetNeighbor(uint16_t aAddress)
|
||||
{
|
||||
Neighbor *rval = NULL;
|
||||
|
||||
+2
-52
@@ -307,6 +307,8 @@ private:
|
||||
*/
|
||||
class Mle : public InstanceLocator, public Notifier::Receiver
|
||||
{
|
||||
friend class DiscoverScanner;
|
||||
|
||||
public:
|
||||
/**
|
||||
* This constructor initializes the MLE object.
|
||||
@@ -371,51 +373,6 @@ public:
|
||||
*/
|
||||
otError Store(void);
|
||||
|
||||
/**
|
||||
* This function pointer is called on receiving an MLE Discovery Response message.
|
||||
*
|
||||
* @param[in] aResult A valid pointer to the Discovery Response information or NULL when the Discovery completes.
|
||||
* @param[in] aContext A pointer to application-specific context.
|
||||
*
|
||||
*/
|
||||
typedef void (*DiscoverHandler)(otActiveScanResult *aResult, void *aContext);
|
||||
|
||||
/**
|
||||
* This method initiates a Thread Discovery.
|
||||
*
|
||||
* @param[in] aScanChannels A bit vector indicating which channels to scan.
|
||||
* @param[in] aPanId The PAN ID filter (set to Broadcast PAN to disable filter).
|
||||
* @param[in] aJoiner Value of the Joiner Flag in the Discovery Request TLV.
|
||||
* @param[in] aEnableFiltering Enable filtering out MLE discovery responses that don't match our factory
|
||||
* assigned EUI64.
|
||||
* @param[in] aHandler A pointer to a function that is called on receiving an MLE Discovery Response.
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Successfully started a Thread Discovery.
|
||||
* @retval OT_ERROR_BUSY Thread Discovery is already in progress.
|
||||
*
|
||||
*/
|
||||
otError Discover(const Mac::ChannelMask &aScanChannels,
|
||||
uint16_t aPanId,
|
||||
bool aJoiner,
|
||||
bool aEnableFiltering,
|
||||
DiscoverHandler aCallback,
|
||||
void * aContext);
|
||||
|
||||
/**
|
||||
* This method indicates whether or not an MLE Thread Discovery is currently in progress.
|
||||
*
|
||||
* @returns true if an MLE Thread Discovery is in progress, false otherwise.
|
||||
*
|
||||
*/
|
||||
bool IsDiscoverInProgress(void) const { return mDiscoverInProgress; }
|
||||
|
||||
/**
|
||||
* This method is called by the MeshForwarder to indicate that discovery is complete.
|
||||
*
|
||||
*/
|
||||
void HandleDiscoverComplete(void);
|
||||
|
||||
/**
|
||||
* This method generates an MLE Announce message.
|
||||
*
|
||||
@@ -1720,7 +1677,6 @@ private:
|
||||
void HandleDataResponse(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, const Neighbor *aNeighbor);
|
||||
void HandleParentResponse(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, uint32_t aKeySequence);
|
||||
void HandleAnnounce(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
void HandleDiscoveryResponse(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
otError HandleLeaderData(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
|
||||
void ProcessAnnounce(void);
|
||||
bool HasUnregisteredAddress(void);
|
||||
@@ -1788,12 +1744,6 @@ private:
|
||||
Ip6::UdpSocket mSocket;
|
||||
uint32_t mTimeout;
|
||||
|
||||
DiscoverHandler mDiscoverHandler;
|
||||
void * mDiscoverContext;
|
||||
MeshCoP::SteeringData::HashBitIndexes mDiscoverFilterIndexes;
|
||||
bool mDiscoverInProgress;
|
||||
bool mDiscoverEnableFiltering;
|
||||
|
||||
#if OPENTHREAD_CONFIG_MLE_INFORM_PREVIOUS_PARENT_ON_REATTACH
|
||||
uint16_t mPreviousParentRloc;
|
||||
#endif
|
||||
|
||||
@@ -72,6 +72,7 @@ ThreadNetif::ThreadNetif(Instance &aInstance)
|
||||
, mMac(aInstance)
|
||||
, mMeshForwarder(aInstance)
|
||||
, mMleRouter(aInstance)
|
||||
, mDiscoverScanner(aInstance)
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
|
||||
, mNetworkDataLocal(aInstance)
|
||||
#endif
|
||||
|
||||
@@ -75,6 +75,7 @@
|
||||
#include "net/sntp_client.hpp"
|
||||
#include "thread/address_resolver.hpp"
|
||||
#include "thread/announce_begin_server.hpp"
|
||||
#include "thread/discover_scanner.hpp"
|
||||
#include "thread/energy_scan_server.hpp"
|
||||
#include "thread/key_manager.hpp"
|
||||
#include "thread/mesh_forwarder.hpp"
|
||||
@@ -210,6 +211,7 @@ private:
|
||||
Mac::Mac mMac;
|
||||
MeshForwarder mMeshForwarder;
|
||||
Mle::MleRouter mMleRouter;
|
||||
Mle::DiscoverScanner mDiscoverScanner;
|
||||
#if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
|
||||
NetworkData::Local mNetworkDataLocal;
|
||||
#endif // OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
|
||||
|
||||
Reference in New Issue
Block a user