[diag] add diag receive command to show received specified number of frames (#11039)

The `diag frame` command can set the frame to be sent. But developers
has no command to check if the received frame is the same as the sent
frame. This commit adds the command `diag receive [async] <number>
[lpr]` to show the detailed info of specified number of received
frames.
This commit is contained in:
Zhanglong Xia
2024-12-13 15:31:51 -08:00
committed by GitHub
parent 93ef72ad92
commit 971f05f760
4 changed files with 183 additions and 7 deletions
+11 -1
View File
@@ -199,7 +199,17 @@ void Interpreter::HandleDiagOutput(const char *aFormat, va_list aArguments, void
static_cast<Interpreter *>(aContext)->HandleDiagOutput(aFormat, aArguments);
}
void Interpreter::HandleDiagOutput(const char *aFormat, va_list aArguments) { OutputFormatV(aFormat, aArguments); }
void Interpreter::HandleDiagOutput(const char *aFormat, va_list aArguments)
{
if (strcmp(aFormat, "OT_ERROR_NONE") == 0)
{
OutputResult(OT_ERROR_NONE);
}
else
{
OutputFormatV(aFormat, aArguments);
}
}
#endif
template <> otError Interpreter::Process<Cmd("version")>(Arg aArgs[])
+20
View File
@@ -218,6 +218,26 @@ set radio from sleep to receive on channel 11
status 0x00
```
### diag radio receive \[async\] \<number\> \[lpr\]
Set the radio to receive mode and receive a specified number of frames.
- async: Use the non-blocking mode.
- number: The number of frames expected to be received.
- l: Show Lqi.
- p: Show Psdu.
- r: Show Rssi.
```bash
> diag radio receive 5 lpr
0, rssi:-49, lqi:119, len:10, psdu:000102030405060771e
1, rssi:-51, lqi:112, len:10, psdu:000102030405060771e
2, rssi:-42, lqi:120, len:10, psdu:000102030405060771e
3, rssi:-54, lqi:111, len:10, psdu:000102030405060771e
4, rssi:-56, lqi:108, len:10, psdu:000102030405060771e
Done
```
### diag radio state
Return the state of the radio.
+126 -6
View File
@@ -587,6 +587,50 @@ void Diags::TransmitPacket(void)
IgnoreError(Get<Radio>().Transmit(*static_cast<Mac::TxFrame *>(mTxPacket)));
}
Error Diags::ParseReceiveConfigFormat(const char *aFormat, ReceiveConfig &aConfig)
{
Error error = kErrorNone;
VerifyOrExit(aFormat != nullptr, error = kErrorInvalidArgs);
for (const char *arg = aFormat; *arg != '\0'; arg++)
{
switch (*arg)
{
case 'r':
aConfig.mShowRssi = true;
break;
case 'l':
aConfig.mShowLqi = true;
break;
case 'p':
aConfig.mShowPsdu = true;
break;
default:
ExitNow(error = OT_ERROR_INVALID_ARGS);
}
}
exit:
return error;
}
Error Diags::RadioReceive(void)
{
Error error;
SuccessOrExit(error = Get<Radio>().Receive(mChannel));
SuccessOrExit(error = Get<Radio>().SetTransmitPower(mTxPower));
otPlatDiagChannelSet(mChannel);
otPlatDiagTxPowerSet(mTxPower);
exit:
return error;
}
Error Diags::ProcessRadio(uint8_t aArgsLength, char *aArgs[])
{
Error error = kErrorInvalidArgs;
@@ -601,12 +645,44 @@ Error Diags::ProcessRadio(uint8_t aArgsLength, char *aArgs[])
}
else if (StringMatch(aArgs[0], "receive"))
{
SuccessOrExit(error = Get<Radio>().Receive(mChannel));
SuccessOrExit(error = Get<Radio>().SetTransmitPower(mTxPower));
otPlatDiagChannelSet(mChannel);
otPlatDiagTxPowerSet(mTxPower);
ReceiveConfig receiveConfig;
Output("set radio from sleep to receive on channel %d\r\nstatus 0x%02x\r\n", mChannel, error);
aArgs++;
aArgsLength--;
if (aArgsLength == 0)
{
SuccessOrExit(error = RadioReceive());
Output("set radio from sleep to receive on channel %d\r\nstatus 0x%02x\r\n", mChannel, error);
ExitNow();
}
if (StringMatch(aArgs[0], "async"))
{
aArgs++;
aArgsLength--;
receiveConfig.mIsAsyncCommand = true;
}
VerifyOrExit(aArgsLength > 0);
SuccessOrExit(error = Utils::CmdLineParser::ParseAsUint16(aArgs[0], receiveConfig.mNumFrames));
aArgs++;
aArgsLength--;
if (aArgsLength > 0)
{
SuccessOrExit(error = ParseReceiveConfigFormat(aArgs[0], receiveConfig));
}
SuccessOrExit(error = RadioReceive());
receiveConfig.mIsEnabled = true;
mReceiveConfig = receiveConfig;
if (!mReceiveConfig.mIsAsyncCommand)
{
error = kErrorPending;
}
}
else if (StringMatch(aArgs[0], "state"))
{
@@ -668,10 +744,54 @@ void Diags::AlarmFired(void)
}
}
void Diags::OutputReceivedFrame(const otRadioFrame *aFrame)
{
VerifyOrExit(mReceiveConfig.mIsEnabled && (aFrame != nullptr));
Output("%u", mReceiveConfig.mReceiveCount++);
if (mReceiveConfig.mShowRssi)
{
Output(", rssi:%d", aFrame->mInfo.mRxInfo.mRssi);
}
if (mReceiveConfig.mShowLqi)
{
Output(", lqi:%u", aFrame->mInfo.mRxInfo.mLqi);
}
if (mReceiveConfig.mShowPsdu)
{
static constexpr uint16_t kBufSize = 255;
char buf[kBufSize];
StringWriter writer(buf, sizeof(buf));
writer.AppendHexBytes(aFrame->mPsdu, aFrame->mLength);
Output(", len:%u, psdu:%s", aFrame->mLength, buf);
}
Output("\r\n");
if (mReceiveConfig.mReceiveCount >= mReceiveConfig.mNumFrames)
{
mReceiveConfig.mIsEnabled = false;
if (!mReceiveConfig.mIsAsyncCommand)
{
Output("OT_ERROR_NONE");
}
}
exit:
return;
}
void Diags::ReceiveDone(otRadioFrame *aFrame, Error aError)
{
if (aError == kErrorNone)
{
OutputReceivedFrame(aFrame);
// for sensitivity test, only record the rssi and lqi for the first and last packet
if (mStats.mReceivedPackets == 0)
{
@@ -910,7 +1030,7 @@ exit:
void Diags::AppendErrorResult(Error aError)
{
if (aError != kErrorNone)
if ((aError != kErrorNone) && (aError != kErrorPending))
{
Output("failed\r\nstatus %#x\r\n", aError);
}
+26
View File
@@ -177,6 +177,28 @@ private:
RawPowerSetting mRawPowerSetting;
};
struct ReceiveConfig
{
ReceiveConfig(void)
: mIsEnabled(false)
, mIsAsyncCommand(false)
, mShowRssi(true)
, mShowLqi(true)
, mShowPsdu(false)
, mReceiveCount(0)
, mNumFrames(0)
{
}
bool mIsEnabled : 1;
bool mIsAsyncCommand : 1;
bool mShowRssi : 1;
bool mShowLqi : 1;
bool mShowPsdu : 1;
uint16_t mReceiveCount;
uint16_t mNumFrames;
};
Error ParseCmd(char *aString, uint8_t &aArgsLength, char *aArgs[]);
Error ProcessChannel(uint8_t aArgsLength, char *aArgs[]);
Error ProcessFrame(uint8_t aArgsLength, char *aArgs[]);
@@ -198,6 +220,9 @@ private:
Error GetRawPowerSetting(RawPowerSetting &aRawPowerSetting);
Error GetPowerSettings(uint8_t aChannel, PowerSettings &aPowerSettings);
Error ParseReceiveConfigFormat(const char *aFormat, ReceiveConfig &aConfig);
Error RadioReceive(void);
void OutputReceivedFrame(const otRadioFrame *aFrame);
void TransmitPacket(void);
void Output(const char *aFormat, ...);
@@ -223,6 +248,7 @@ private:
bool mDiagSendOn : 1;
#endif
ReceiveConfig mReceiveConfig;
otDiagOutputCallback mOutputCallback;
void *mOutputContext;
};