From be849968060307bf5ffb59488f2fab195a0d64dc Mon Sep 17 00:00:00 2001 From: Zhanglong Xia Date: Thu, 12 Dec 2024 14:04:35 +0800 Subject: [PATCH] [diag] add 'diag radio receive filter' command support --- src/core/diags/README.md | 33 ++++++++++++++ src/core/diags/factory_diags.cpp | 76 +++++++++++++++++++++++++++++++- src/core/diags/factory_diags.hpp | 21 ++++++--- src/core/mac/mac_types.cpp | 31 +++++++++++++ src/core/mac/mac_types.hpp | 20 +++++++++ 5 files changed, 172 insertions(+), 9 deletions(-) diff --git a/src/core/diags/README.md b/src/core/diags/README.md index 3db8fae04b1..77711b1a4cf 100644 --- a/src/core/diags/README.md +++ b/src/core/diags/README.md @@ -238,6 +238,39 @@ Set the radio to receive mode and receive a specified number of frames. Done ``` +### diag radio receive filter enable + +Enable the diag filter module to only receive frames with a specified destination address. + +```bash +> diag radio receive filter enable +Done +``` + +### diag radio receive filter disable + +Disable the diag filter module from only receiving frames with a specified destination address. + +```bash +> diag radio receive filter disable +Done +``` + +### diag radio receive filter \ + +Set the destination address of the radio receive filter. + +- destaddress: The destination mac address. It can be a short, extended or empty mac address. Input '-' to specify an empty mac address. + +```bash +> diag radio receive filter - +Done +> diag radio receive filter 0x0a17 +Done +> diag radio receive filter dead00beef00cafe +Done +``` + ### diag radio state Return the state of the radio. diff --git a/src/core/diags/factory_diags.cpp b/src/core/diags/factory_diags.cpp index 2048d1c3ba9..bca43dfc851 100644 --- a/src/core/diags/factory_diags.cpp +++ b/src/core/diags/factory_diags.cpp @@ -657,6 +657,51 @@ Error Diags::ProcessRadio(uint8_t aArgsLength, char *aArgs[]) ExitNow(); } + if (StringMatch(aArgs[0], "filter")) + { + aArgs++; + aArgsLength--; + + VerifyOrExit(aArgsLength > 0); + + if (StringMatch(aArgs[0], "enable")) + { + mReceiveConfig.mIsFilterEnabled = true; + error = kErrorNone; + } + else if (StringMatch(aArgs[0], "disable")) + { + mReceiveConfig.mIsFilterEnabled = false; + error = kErrorNone; + } + else + { + Mac::Address dstAddress; + + if (StringMatch(aArgs[0], "-")) + { + dstAddress.SetNone(); + error = kErrorNone; + } + else if (strlen(aArgs[0]) == 2 * sizeof(Mac::ExtAddress)) + { + Mac::ExtAddress extAddress; + + SuccessOrExit(error = Utils::CmdLineParser::ParseAsHexString(aArgs[0], extAddress.m8)); + mReceiveConfig.mFilterAddress.SetExtended(extAddress); + } + else + { + Mac::ShortAddress shortAddress; + + SuccessOrExit(error = Utils::CmdLineParser::ParseAsUint16(aArgs[0], shortAddress)); + mReceiveConfig.mFilterAddress.SetShort(shortAddress); + } + } + + ExitNow(); + } + if (StringMatch(aArgs[0], "async")) { aArgs++; @@ -676,8 +721,13 @@ Error Diags::ProcessRadio(uint8_t aArgsLength, char *aArgs[]) SuccessOrExit(error = RadioReceive()); - receiveConfig.mIsEnabled = true; - mReceiveConfig = receiveConfig; + mReceiveConfig.mIsEnabled = true; + mReceiveConfig.mIsAsyncCommand = receiveConfig.mIsAsyncCommand; + mReceiveConfig.mShowRssi = receiveConfig.mShowRssi; + mReceiveConfig.mShowLqi = receiveConfig.mShowLqi; + mReceiveConfig.mShowPsdu = receiveConfig.mShowPsdu; + mReceiveConfig.mReceiveCount = receiveConfig.mReceiveCount; + mReceiveConfig.mNumFrames = receiveConfig.mNumFrames; if (!mReceiveConfig.mIsAsyncCommand) { @@ -790,6 +840,11 @@ void Diags::ReceiveDone(otRadioFrame *aFrame, Error aError) { if (aError == kErrorNone) { + if (mReceiveConfig.mIsFilterEnabled) + { + VerifyOrExit(ShouldHandleReceivedFrame(*aFrame)); + } + OutputReceivedFrame(aFrame); // for sensitivity test, only record the rssi and lqi for the first and last packet @@ -806,6 +861,9 @@ void Diags::ReceiveDone(otRadioFrame *aFrame, Error aError) } otPlatDiagRadioReceived(&GetInstance(), aFrame, aError); + +exit: + return; } void Diags::TransmitDone(Error aError) @@ -834,6 +892,20 @@ void Diags::TransmitDone(Error aError) return; } +bool Diags::ShouldHandleReceivedFrame(const otRadioFrame &aFrame) const +{ + bool ret = false; + const Mac::RxFrame &frame = static_cast(aFrame); + Mac::Address dstAddress; + + VerifyOrExit(frame.GetDstAddr(dstAddress) == kErrorNone); + VerifyOrExit(dstAddress == mReceiveConfig.mFilterAddress); + ret = true; + +exit: + return ret; +} + #endif // OPENTHREAD_RADIO Error Diags::ProcessContinuousWave(uint8_t aArgsLength, char *aArgs[]) diff --git a/src/core/diags/factory_diags.hpp b/src/core/diags/factory_diags.hpp index 0a724c8bf8d..d7dc9bc6d3b 100644 --- a/src/core/diags/factory_diags.hpp +++ b/src/core/diags/factory_diags.hpp @@ -48,6 +48,7 @@ #include "common/locator.hpp" #include "common/non_copyable.hpp" #include "common/string.hpp" +#include "mac/mac_types.hpp" namespace ot { namespace FactoryDiags { @@ -185,18 +186,23 @@ class Diags : public InstanceLocator, private NonCopyable , mShowRssi(true) , mShowLqi(true) , mShowPsdu(false) + , mIsFilterEnabled(false) , mReceiveCount(0) , mNumFrames(0) + , mFilterAddress() { } - bool mIsEnabled : 1; - bool mIsAsyncCommand : 1; - bool mShowRssi : 1; - bool mShowLqi : 1; - bool mShowPsdu : 1; - uint16_t mReceiveCount; - uint16_t mNumFrames; + bool mIsEnabled : 1; + bool mIsAsyncCommand : 1; + bool mShowRssi : 1; + bool mShowLqi : 1; + bool mShowPsdu : 1; + bool mIsFilterEnabled : 1; + + uint16_t mReceiveCount; + uint16_t mNumFrames; + Mac::Address mFilterAddress; }; Error ParseCmd(char *aString, uint8_t &aArgsLength, char *aArgs[]); @@ -223,6 +229,7 @@ class Diags : public InstanceLocator, private NonCopyable Error ParseReceiveConfigFormat(const char *aFormat, ReceiveConfig &aConfig); Error RadioReceive(void); void OutputReceivedFrame(const otRadioFrame *aFrame); + bool ShouldHandleReceivedFrame(const otRadioFrame &aFrame) const; void TransmitPacket(void); void Output(const char *aFormat, ...); diff --git a/src/core/mac/mac_types.cpp b/src/core/mac/mac_types.cpp index 87fb718eed4..890b4f48908 100644 --- a/src/core/mac/mac_types.cpp +++ b/src/core/mac/mac_types.cpp @@ -63,6 +63,8 @@ void ExtAddress::GenerateRandom(void) } #endif +bool ExtAddress::operator==(const ExtAddress &aOther) const { return (memcmp(m8, aOther.m8, sizeof(m8)) == 0); } + ExtAddress::InfoString ExtAddress::ToString(void) const { InfoString string; @@ -90,6 +92,35 @@ void ExtAddress::CopyAddress(uint8_t *aDst, const uint8_t *aSrc, CopyByteOrder a } } +bool Address::operator==(const Address &aOther) const +{ + bool ret = false; + + VerifyOrExit(GetType() == aOther.GetType()); + + switch (GetType()) + { + case kTypeNone: + ret = true; + break; + + case kTypeShort: + ret = (GetShort() == aOther.GetShort()); + break; + + case kTypeExtended: + ret = (GetExtended() == aOther.GetExtended()); + break; + + default: + OT_ASSERT(false); + break; + } + +exit: + return ret; +} + Address::InfoString Address::ToString(void) const { InfoString string; diff --git a/src/core/mac/mac_types.hpp b/src/core/mac/mac_types.hpp index 7b504ad5ec6..233c1734039 100644 --- a/src/core/mac/mac_types.hpp +++ b/src/core/mac/mac_types.hpp @@ -198,6 +198,16 @@ class ExtAddress : public otExtAddress, public Equatable, public Cle CopyAddress(aBuffer, m8, aByteOrder); } + /** + * Overloads operator `==` to evaluate whether or not two `ExtAddress` instances are equal. + * + * @param[in] aOther The other `ExtAddress` instance to compare with. + * + * @retval TRUE If the two `ExtAddress` instances are equal. + * @retval FALSE If the two `ExtAddress` instances are not equal. + */ + bool operator==(const ExtAddress &aOther) const; + /** * Converts an address to a string. * @@ -358,6 +368,16 @@ class Address */ bool IsShortAddrInvalid(void) const { return ((mType == kTypeShort) && (GetShort() == kShortAddrInvalid)); } + /** + * Overloads operator `==` to evaluate whether or not two `Address` instances are equal. + * + * @param[in] aOther The other `Address` instance to compare with. + * + * @retval TRUE If the two `Address` instances are equal. + * @retval FALSE If the two `Address` instances are not equal. + */ + bool operator==(const Address &aOther) const; + /** * Converts an address to a null-terminated string *