From ef5e4f3e3dd4863ac798e7c9d60c40a99f1c0186 Mon Sep 17 00:00:00 2001 From: Zhanglong Xia Date: Fri, 20 Dec 2024 05:25:25 +0800 Subject: [PATCH] [diag] add `diag radio receive filter` command support (#11054) The current diag module will count any packets received. This commit adds the command `diag radio receive filter` to allow the diag module receives only frames with the specified destination mac address. --- 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 127757794..1afb88a2c 100644 --- a/src/core/diags/README.md +++ b/src/core/diags/README.md @@ -240,6 +240,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 none. Use '-' to specify none. + +```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 09ea38a3d..256d65d71 100644 --- a/src/core/diags/factory_diags.cpp +++ b/src/core/diags/factory_diags.cpp @@ -631,6 +631,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++; @@ -650,8 +695,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) { @@ -763,6 +813,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 @@ -779,6 +834,9 @@ void Diags::ReceiveDone(otRadioFrame *aFrame, Error aError) } otPlatDiagRadioReceived(&GetInstance(), aFrame, aError); + +exit: + return; } void Diags::TransmitDone(Error aError) @@ -807,6 +865,20 @@ exit: 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 0a724c8bf..d7dc9bc6d 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 @@ private: , 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 @@ private: 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 87fb718ee..890b4f489 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 7b504ad5e..233c17340 100644 --- a/src/core/mac/mac_types.hpp +++ b/src/core/mac/mac_types.hpp @@ -198,6 +198,16 @@ public: 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 @@ public: */ 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 *