mirror of
https://github.com/espressif/openthread.git
synced 2026-10-10 17:57:48 +00:00
When a router-eligible Child transitions to Router (e.g. during TestCoapObserve when Leader notifies an upgraded child at its former child RLOC16), OpenThread calls otPlatRadioSetAlternateShortAddress(), which stores the previous short address in mRadioContext.mAlternateShortAddress. Fix alternate short address handling consistently across Nexus, simulation radio, and MAC frame utils: - Advertise OT_RADIO_CAPS_ALT_SHORT_ADDR in both Nexus otPlatRadioGetCaps() and simulation gRadioCaps. - Initialize mCslShortAddress, mShortAddress, and mAlternateShortAddress in otRadioContext to OT_RADIO_INVALID_SHORT_ADDR in both Nexus::Radio::Reset() and simulation platformRadioInit(). - Drop duplicate Radio::mShortAddress and Radio::mExtAddress from Nexus::Radio and use mRadioContext consistently. - Simplify Nexus::Radio::Radio(void) to call Reset(). - Guard against Mac::kShortAddrInvalid and match both short addresses in Nexus::Radio::Matches() and otMacFrameDoesAddrMatchAny().
508 lines
16 KiB
C++
508 lines
16 KiB
C++
/*
|
|
* Copyright (c) 2019, 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 "mac_frame.h"
|
|
|
|
#include <assert.h>
|
|
|
|
#include <openthread/platform/radio.h>
|
|
|
|
#include "common/code_utils.hpp"
|
|
#include "mac/mac_frame.hpp"
|
|
|
|
using namespace ot;
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
// Helpers
|
|
|
|
static inline Error ParseAddrFields(const otRadioFrame *aFrame, Mac::Frame::ParseInfo &aFrameInfo)
|
|
{
|
|
return aFrameInfo.ParseFrom(*static_cast<const Mac::Frame *>(aFrame), Mac::Frame::kParseAddrFields);
|
|
}
|
|
|
|
static inline Error ParseSecurityHeader(const otRadioFrame *aFrame, Mac::TxFrame::ParseInfo &aFrameInfo)
|
|
{
|
|
return aFrameInfo.ParseFrom(*static_cast<const Mac::TxFrame *>(aFrame), Mac::Frame::kParseSecurityHeader);
|
|
}
|
|
|
|
static inline Error ParseFully(const otRadioFrame *aFrame, Mac::Frame::ParseInfo &aFrameInfo)
|
|
{
|
|
return aFrameInfo.ParseFrom(*static_cast<const Mac::Frame *>(aFrame), Mac::Frame::kParseFully);
|
|
}
|
|
|
|
static bool IsFrameOfType(const otRadioFrame *aFrame, Mac::Frame::Type aType)
|
|
{
|
|
bool matches = false;
|
|
Mac::Frame::ParseInfo frameInfo;
|
|
|
|
SuccessOrExit(ParseAddrFields(aFrame, frameInfo));
|
|
matches = (frameInfo.mType == aType);
|
|
|
|
exit:
|
|
return matches;
|
|
}
|
|
|
|
static bool HasFrameKeyIdMode(const otRadioFrame *aFrame, Mac::Frame::KeyIdMode aKeyIdMode)
|
|
{
|
|
bool matches = false;
|
|
Mac::TxFrame::ParseInfo frameInfo;
|
|
|
|
SuccessOrExit(ParseSecurityHeader(aFrame, frameInfo));
|
|
VerifyOrExit(frameInfo.mKeyIdMode == aKeyIdMode);
|
|
matches = true;
|
|
|
|
exit:
|
|
return matches;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
bool otMacFrameDoesAddrMatch(const otRadioFrame *aFrame,
|
|
otPanId aPanId,
|
|
otShortAddress aShortAddress,
|
|
const otExtAddress *aExtAddress)
|
|
{
|
|
return otMacFrameDoesAddrMatchAny(aFrame, aPanId, aShortAddress, Mac::kShortAddrInvalid, aExtAddress);
|
|
}
|
|
|
|
bool otMacFrameDoesAddrMatchAny(const otRadioFrame *aFrame,
|
|
otPanId aPanId,
|
|
otShortAddress aShortAddress,
|
|
otShortAddress aAltShortAddress,
|
|
const otExtAddress *aExtAddress)
|
|
{
|
|
bool rval = true;
|
|
Mac::Frame::ParseInfo frameInfo;
|
|
|
|
if (ParseAddrFields(aFrame, frameInfo) != kErrorNone)
|
|
{
|
|
rval = false;
|
|
ExitNow();
|
|
}
|
|
|
|
switch (frameInfo.mAddrs.mDestination.GetType())
|
|
{
|
|
case Mac::Address::kTypeShort:
|
|
{
|
|
Mac::ShortAddress dstAddr = frameInfo.mAddrs.mDestination.GetShort();
|
|
|
|
VerifyOrExit(dstAddr != Mac::kShortAddrInvalid, rval = false);
|
|
VerifyOrExit(dstAddr == Mac::kShortAddrBroadcast || dstAddr == aShortAddress || dstAddr == aAltShortAddress,
|
|
rval = false);
|
|
break;
|
|
}
|
|
|
|
case Mac::Address::kTypeExtended:
|
|
VerifyOrExit(frameInfo.mAddrs.mDestination.GetExtended() == *static_cast<const Mac::ExtAddress *>(aExtAddress),
|
|
rval = false);
|
|
break;
|
|
|
|
case Mac::Address::kTypeNone:
|
|
break;
|
|
}
|
|
|
|
VerifyOrExit(frameInfo.mPanIds.IsDestinationPresent());
|
|
VerifyOrExit(frameInfo.mPanIds.GetDestination() == Mac::kPanIdBroadcast ||
|
|
frameInfo.mPanIds.GetDestination() == aPanId,
|
|
rval = false);
|
|
|
|
exit:
|
|
return rval;
|
|
}
|
|
|
|
bool otMacFrameIsAck(const otRadioFrame *aFrame) { return IsFrameOfType(aFrame, Mac::Frame::kTypeAck); }
|
|
|
|
bool otMacFrameIsData(const otRadioFrame *aFrame) { return IsFrameOfType(aFrame, Mac::Frame::kTypeData); }
|
|
|
|
bool otMacFrameIsCommand(const otRadioFrame *aFrame) { return IsFrameOfType(aFrame, Mac::Frame::kTypeMacCmd); }
|
|
|
|
bool otMacFrameIsDataRequest(const otRadioFrame *aFrame)
|
|
{
|
|
bool matches = false;
|
|
Mac::Frame::ParseInfo frameInfo;
|
|
|
|
SuccessOrExit(ParseFully(aFrame, frameInfo));
|
|
VerifyOrExit(frameInfo.mType == Mac::Frame::kTypeMacCmd);
|
|
VerifyOrExit(frameInfo.mCommandId == Mac::Frame::kMacCmdDataRequest);
|
|
matches = true;
|
|
|
|
exit:
|
|
return matches;
|
|
}
|
|
|
|
bool otMacFrameIsAckRequested(const otRadioFrame *aFrame)
|
|
{
|
|
Mac::Frame::ParseInfo frameInfo;
|
|
|
|
IgnoreError(ParseAddrFields(aFrame, frameInfo));
|
|
return frameInfo.mIsAckRequest;
|
|
}
|
|
|
|
static void GetOtMacAddress(const Mac::Address &aInAddress, otMacAddress *aOutAddress)
|
|
{
|
|
switch (aInAddress.GetType())
|
|
{
|
|
case Mac::Address::kTypeNone:
|
|
aOutAddress->mType = OT_MAC_ADDRESS_TYPE_NONE;
|
|
break;
|
|
|
|
case Mac::Address::kTypeShort:
|
|
aOutAddress->mType = OT_MAC_ADDRESS_TYPE_SHORT;
|
|
aOutAddress->mAddress.mShortAddress = aInAddress.GetShort();
|
|
break;
|
|
|
|
case Mac::Address::kTypeExtended:
|
|
aOutAddress->mType = OT_MAC_ADDRESS_TYPE_EXTENDED;
|
|
aOutAddress->mAddress.mExtAddress = aInAddress.GetExtended();
|
|
break;
|
|
}
|
|
}
|
|
|
|
otError otMacFrameGetSrcAddr(const otRadioFrame *aFrame, otMacAddress *aMacAddress)
|
|
{
|
|
Error error;
|
|
Mac::Frame::ParseInfo frameInfo;
|
|
|
|
SuccessOrExit(error = ParseAddrFields(aFrame, frameInfo));
|
|
GetOtMacAddress(frameInfo.mAddrs.mSource, aMacAddress);
|
|
|
|
exit:
|
|
return error;
|
|
}
|
|
|
|
otError otMacFrameGetDstAddr(const otRadioFrame *aFrame, otMacAddress *aMacAddress)
|
|
{
|
|
Error error;
|
|
Mac::Frame::ParseInfo frameInfo;
|
|
|
|
SuccessOrExit(error = ParseAddrFields(aFrame, frameInfo));
|
|
GetOtMacAddress(frameInfo.mAddrs.mDestination, aMacAddress);
|
|
|
|
exit:
|
|
return error;
|
|
}
|
|
|
|
otError otMacFrameGetSequence(const otRadioFrame *aFrame, uint8_t *aSequence)
|
|
{
|
|
Error error;
|
|
Mac::Frame::ParseInfo frameInfo;
|
|
|
|
SuccessOrExit(error = ParseAddrFields(aFrame, frameInfo));
|
|
VerifyOrExit(frameInfo.mIsSeqNumPresent, error = kErrorParse);
|
|
*aSequence = frameInfo.mSequenceNum;
|
|
|
|
exit:
|
|
return error;
|
|
}
|
|
|
|
void otMacFrameProcessTransmitAesCcm(otRadioFrame *aFrame, const otExtAddress *aExtAddress)
|
|
{
|
|
Mac::TxFrame::ParseInfo frameInfo;
|
|
|
|
IgnoreError(ParseFully(aFrame, frameInfo));
|
|
frameInfo.ProcessTransmitAesCcm(AsCoreType(aExtAddress));
|
|
}
|
|
|
|
bool otMacFrameIsVersion2015(const otRadioFrame *aFrame)
|
|
{
|
|
Mac::Frame::ParseInfo frameInfo;
|
|
|
|
IgnoreError(ParseAddrFields(aFrame, frameInfo));
|
|
return frameInfo.mVersion == Mac::Frame::kVersion2015;
|
|
}
|
|
|
|
void otMacFrameGenerateImmAck(const otRadioFrame *aFrame, bool aIsFramePending, otRadioFrame *aAckFrame)
|
|
{
|
|
assert(aFrame != nullptr && aAckFrame != nullptr);
|
|
|
|
static_cast<Mac::TxFrame *>(aAckFrame)->GenerateImmAck(*static_cast<const Mac::RxFrame *>(aFrame), aIsFramePending);
|
|
}
|
|
|
|
#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
|
|
otError otMacFrameGenerateEnhAck(const otRadioFrame *aFrame,
|
|
bool aIsFramePending,
|
|
const uint8_t *aIeData,
|
|
uint8_t aIeLength,
|
|
otRadioFrame *aAckFrame)
|
|
{
|
|
assert(aFrame != nullptr && aAckFrame != nullptr);
|
|
|
|
return static_cast<Mac::TxFrame *>(aAckFrame)->GenerateEnhAck(*static_cast<const Mac::RxFrame *>(aFrame),
|
|
aIsFramePending, aIeData, aIeLength);
|
|
}
|
|
#endif
|
|
|
|
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
|
void otMacFrameSetCslIe(otRadioFrame *aFrame, uint16_t aCslPeriod, uint16_t aCslPhase)
|
|
{
|
|
static_cast<Mac::Frame *>(aFrame)->UpdateCslIe(aCslPeriod, aCslPhase);
|
|
}
|
|
#endif
|
|
|
|
bool otMacFrameIsSecurityEnabled(otRadioFrame *aFrame)
|
|
{
|
|
Mac::Frame::ParseInfo frameInfo;
|
|
|
|
IgnoreError(ParseAddrFields(aFrame, frameInfo));
|
|
return frameInfo.mIsSecurityEnabled;
|
|
}
|
|
|
|
bool otMacFrameIsKeyIdMode1(otRadioFrame *aFrame) { return HasFrameKeyIdMode(aFrame, Mac::Frame::kKeyIdMode1); }
|
|
|
|
bool otMacFrameIsKeyIdMode2(otRadioFrame *aFrame) { return HasFrameKeyIdMode(aFrame, Mac::Frame::kKeyIdMode2); }
|
|
|
|
uint8_t otMacFrameGetKeyId(otRadioFrame *aFrame)
|
|
{
|
|
uint8_t keyIndex = 0;
|
|
Mac::TxFrame::ParseInfo frameInfo;
|
|
|
|
SuccessOrExit(ParseSecurityHeader(aFrame, frameInfo));
|
|
keyIndex = frameInfo.mKeyIndex;
|
|
|
|
exit:
|
|
return keyIndex;
|
|
}
|
|
|
|
void otMacFrameSetKeyId(otRadioFrame *aFrame, uint8_t aKeyId)
|
|
{
|
|
Mac::TxFrame::ParseInfo frameInfo;
|
|
|
|
IgnoreError(ParseSecurityHeader(aFrame, frameInfo));
|
|
frameInfo.WriteKeyIndex(aKeyId);
|
|
}
|
|
|
|
uint32_t otMacFrameGetFrameCounter(otRadioFrame *aFrame)
|
|
{
|
|
uint32_t frameCounter = UINT32_MAX;
|
|
Mac::TxFrame::ParseInfo frameInfo;
|
|
|
|
SuccessOrExit(ParseSecurityHeader(aFrame, frameInfo));
|
|
frameCounter = frameInfo.mFrameCounter;
|
|
|
|
exit:
|
|
return frameCounter;
|
|
}
|
|
|
|
void otMacFrameSetFrameCounter(otRadioFrame *aFrame, uint32_t aFrameCounter)
|
|
{
|
|
Mac::TxFrame::ParseInfo frameInfo;
|
|
|
|
IgnoreError(ParseSecurityHeader(aFrame, frameInfo));
|
|
frameInfo.WriteFrameCounter(aFrameCounter);
|
|
}
|
|
|
|
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
|
uint8_t otMacFrameGenerateCslIeTemplate(uint8_t *aDest)
|
|
{
|
|
assert(aDest != nullptr);
|
|
|
|
reinterpret_cast<Mac::CslIe *>(aDest)->Init();
|
|
|
|
return sizeof(Mac::CslIe);
|
|
}
|
|
#endif
|
|
|
|
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
|
|
uint8_t otMacFrameGenerateEnhAckProbingIe(uint8_t *aDest, const uint8_t *aIeData, uint8_t aIeDataLength)
|
|
{
|
|
Mac::LinkMetricsProbingIe *probingIe = reinterpret_cast<Mac::LinkMetricsProbingIe *>(aDest);
|
|
|
|
assert(aDest != nullptr);
|
|
|
|
probingIe->Init(aIeDataLength);
|
|
|
|
if (aIeData != nullptr)
|
|
{
|
|
probingIe->WriteMetricsDataFrom(aIeData);
|
|
}
|
|
|
|
return probingIe->GetSize();
|
|
}
|
|
|
|
void otMacFrameSetEnhAckProbingIe(otRadioFrame *aFrame, const uint8_t *aData, uint8_t aDataLen)
|
|
{
|
|
assert(aFrame != nullptr && aData != nullptr);
|
|
|
|
reinterpret_cast<Mac::Frame *>(aFrame)->UpdateEnhAckProbingIe(aData, aDataLen);
|
|
}
|
|
#endif // OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
|
|
|
|
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
|
static uint16_t ComputeCslPhase(uint32_t aRadioTime, otRadioContext *aRadioContext)
|
|
{
|
|
return (aRadioContext->mCslSampleTime - aRadioTime) % (aRadioContext->mCslPeriod * OT_US_PER_TEN_SYMBOLS) /
|
|
OT_US_PER_TEN_SYMBOLS;
|
|
}
|
|
#endif
|
|
otError otMacFrameProcessTransmitSecurity(otRadioFrame *aFrame, otRadioContext *aRadioContext)
|
|
{
|
|
otError error = OT_ERROR_NONE;
|
|
#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
|
|
otMacKeyMaterial *key = nullptr;
|
|
uint8_t keyId;
|
|
uint32_t frameCounter;
|
|
bool processKeyId;
|
|
|
|
processKeyId = otMacFrameIsKeyIdMode1(aFrame);
|
|
|
|
VerifyOrExit(otMacFrameIsSecurityEnabled(aFrame) && processKeyId && !aFrame->mInfo.mTxInfo.mIsSecurityProcessed);
|
|
|
|
if (otMacFrameIsAck(aFrame))
|
|
{
|
|
keyId = otMacFrameGetKeyId(aFrame);
|
|
|
|
VerifyOrExit(keyId != 0, error = OT_ERROR_FAILED);
|
|
|
|
if (keyId == aRadioContext->mKeyId)
|
|
{
|
|
key = &aRadioContext->mCurrKey;
|
|
frameCounter = aRadioContext->mMacFrameCounter++;
|
|
}
|
|
else if (keyId == aRadioContext->mKeyId - 1)
|
|
{
|
|
key = &aRadioContext->mPrevKey;
|
|
frameCounter = aRadioContext->mPrevMacFrameCounter++;
|
|
}
|
|
else if (keyId == aRadioContext->mKeyId + 1)
|
|
{
|
|
key = &aRadioContext->mNextKey;
|
|
frameCounter = 0;
|
|
}
|
|
else
|
|
{
|
|
ExitNow(error = OT_ERROR_SECURITY);
|
|
}
|
|
}
|
|
else if (!aFrame->mInfo.mTxInfo.mIsHeaderUpdated)
|
|
{
|
|
key = &aRadioContext->mCurrKey;
|
|
keyId = aRadioContext->mKeyId;
|
|
frameCounter = aRadioContext->mMacFrameCounter++;
|
|
}
|
|
|
|
if (key != nullptr)
|
|
{
|
|
aFrame->mInfo.mTxInfo.mAesKey = key;
|
|
|
|
otMacFrameSetKeyId(aFrame, keyId);
|
|
otMacFrameSetFrameCounter(aFrame, frameCounter);
|
|
aFrame->mInfo.mTxInfo.mIsHeaderUpdated = true;
|
|
}
|
|
#else
|
|
VerifyOrExit(!aFrame->mInfo.mTxInfo.mIsSecurityProcessed);
|
|
#endif // OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
|
|
|
|
otMacFrameProcessTransmitAesCcm(aFrame, &aRadioContext->mExtAddress);
|
|
|
|
exit:
|
|
return error;
|
|
}
|
|
|
|
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
|
|
void otMacFrameUpdateTimeIe(otRadioFrame *aFrame, uint64_t aRadioTime, otRadioContext *aRadioContext)
|
|
{
|
|
uint8_t *timeIe;
|
|
uint64_t time;
|
|
|
|
OT_UNUSED_VARIABLE(aRadioContext);
|
|
VerifyOrExit((aFrame->mInfo.mTxInfo.mIeInfo != nullptr) && (aFrame->mInfo.mTxInfo.mIeInfo->mTimeIeOffset != 0));
|
|
|
|
timeIe = aFrame->mPsdu + aFrame->mInfo.mTxInfo.mIeInfo->mTimeIeOffset;
|
|
time = aRadioTime + aFrame->mInfo.mTxInfo.mIeInfo->mNetworkTimeOffset;
|
|
*timeIe = aFrame->mInfo.mTxInfo.mIeInfo->mTimeSyncSeq;
|
|
|
|
*(++timeIe) = static_cast<uint8_t>(time & 0xff);
|
|
for (uint8_t i = 1; i < sizeof(uint64_t); i++)
|
|
{
|
|
time = time >> 8;
|
|
*(++timeIe) = static_cast<uint8_t>(time & 0xff);
|
|
}
|
|
|
|
exit:
|
|
return;
|
|
}
|
|
#endif // OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
|
|
|
|
otError otMacFrameProcessTxSfd(otRadioFrame *aFrame, uint64_t aRadioTime, otRadioContext *aRadioContext)
|
|
{
|
|
otError error = OT_ERROR_NONE;
|
|
|
|
aFrame->mInfo.mTxInfo.mTimestamp = aRadioTime;
|
|
|
|
VerifyOrExit(!otMacFrameIsSecurityEnabled(aFrame) || !aFrame->mInfo.mTxInfo.mIsSecurityProcessed);
|
|
|
|
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
|
{
|
|
Mac::Frame::ParseInfo frameInfo;
|
|
|
|
if ((ParseFully(aFrame, frameInfo) == kErrorNone) && frameInfo.Has<Mac::CslIe>())
|
|
{
|
|
otMacFrameSetCslIe(aFrame, aRadioContext->mCslPeriod,
|
|
ComputeCslPhase(static_cast<uint32_t>(aRadioTime), aRadioContext));
|
|
}
|
|
}
|
|
#endif
|
|
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
|
|
otMacFrameUpdateTimeIe(aFrame, aRadioTime, aRadioContext);
|
|
#endif
|
|
error = otMacFrameProcessTransmitSecurity(aFrame, aRadioContext);
|
|
|
|
exit:
|
|
return error;
|
|
}
|
|
|
|
bool otMacFrameSrcAddrMatchCslReceiverPeer(const otRadioFrame *aFrame, const otRadioContext *aRadioContext)
|
|
{
|
|
bool matches = false;
|
|
Mac::Frame::ParseInfo frameInfo;
|
|
|
|
SuccessOrExit(ParseAddrFields(aFrame, frameInfo));
|
|
|
|
switch (frameInfo.mAddrs.mSource.GetType())
|
|
{
|
|
case Mac::Address::kTypeShort:
|
|
VerifyOrExit(aRadioContext->mCslShortAddress != Mac::kShortAddrBroadcast &&
|
|
aRadioContext->mCslShortAddress != Mac::kShortAddrInvalid);
|
|
VerifyOrExit(frameInfo.mAddrs.mSource.GetShort() == aRadioContext->mCslShortAddress);
|
|
matches = true;
|
|
break;
|
|
|
|
case Mac::Address::kTypeExtended:
|
|
VerifyOrExit(frameInfo.mAddrs.mSource.GetExtended() == AsCoreType(&aRadioContext->mCslExtAddress));
|
|
matches = true;
|
|
break;
|
|
|
|
case Mac::Address::kTypeNone:
|
|
matches = false;
|
|
break;
|
|
}
|
|
|
|
exit:
|
|
return matches;
|
|
}
|