mirror of
https://github.com/espressif/openthread.git
synced 2026-08-11 21:27:46 +00:00
[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.
This commit is contained in:
@@ -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 \<destaddress\>
|
||||
|
||||
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.
|
||||
|
||||
@@ -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<const Mac::RxFrame &>(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[])
|
||||
|
||||
@@ -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, ...);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user