From 4f2eec909b158d6b019aed6ba88296000d774519 Mon Sep 17 00:00:00 2001 From: Zhanglong Xia Date: Tue, 10 Dec 2024 23:59:12 +0800 Subject: [PATCH] [diag] add options `-b`, `-C`, `-d` and `-r` to the `diag frame` command (#11010) --- src/core/diags/README.md | 8 ++- src/core/diags/factory_diags.cpp | 83 +++++++++++++++++++++++++------- src/core/diags/factory_diags.hpp | 2 + 3 files changed, 74 insertions(+), 19 deletions(-) diff --git a/src/core/diags/README.md b/src/core/diags/README.md index 9ec39c2cf..95cedf531 100644 --- a/src/core/diags/README.md +++ b/src/core/diags/README.md @@ -80,13 +80,17 @@ Done ### diag frame -Usage: `diag frame [-c] [-p TX_POWER] [-s] ` +Usage: `diag frame [-b MaxCsmaBackoffs] [-c] [-C RxChannelAfterTxDone] [-d TxDelay] [-p TxPower] [-r MaxFrameRetries] [-s] ` Set the frame (hex encoded) to be used by `diag send` and `diag repeat`. The frame may be overwritten by `diag send` and `diag repeat`. -- Specify `-s` to indicate that tx security is already processed so that it should be skipped in the radio layer. +- Specify `-b` to specify the `mInfo.mTxInfo.mMaxCsmaBackoffs` field for this frame. - Specify `-c` to enable CSMA/CA for this frame in the radio layer. +- Specify `-C` to specify the `mInfo.mTxInfo.mRxChannelAfterTxDone` field for this frame. +- Specify `-d` to specify the `mInfo.mTxInfo.mTxDelay` field for this frame and the `mInfo.mTxInfo.mTxDelayBaseTime` field is set to the current radio time. - Specify `-p` to specify the tx power in dBm for this frame. +- Specify `-r` to specify the `mInfo.mTxInfo.mMaxFrameRetries` field for this frame. +- Specify `-s` to indicate that tx security is already processed thus it should be skipped in the radio layer. ```bash > diag frame 11223344 diff --git a/src/core/diags/factory_diags.cpp b/src/core/diags/factory_diags.cpp index c879f8628..784585bc2 100644 --- a/src/core/diags/factory_diags.cpp +++ b/src/core/diags/factory_diags.cpp @@ -88,7 +88,7 @@ Error Diags::ProcessChannel(uint8_t aArgsLength, char *aArgs[]) VerifyOrExit(aArgsLength == 1, error = kErrorInvalidArgs); SuccessOrExit(error = Utils::CmdLineParser::ParseAsUint8(aArgs[0], channel)); - VerifyOrExit(channel >= Radio::kChannelMin && channel <= Radio::kChannelMax, error = kErrorInvalidArgs); + VerifyOrExit(IsChannelValid(channel), error = kErrorInvalidArgs); otPlatDiagChannelSet(channel); @@ -227,17 +227,48 @@ void Diags::ResetTxPacket(void) Error Diags::ProcessFrame(uint8_t aArgsLength, char *aArgs[]) { - Error error = kErrorNone; - uint16_t size = OT_RADIO_FRAME_MAX_SIZE; - bool securityProcessed = false; - bool csmaCaEnabled = false; - int8_t txPower = OT_RADIO_POWER_INVALID; + Error error = kErrorNone; + uint16_t size = OT_RADIO_FRAME_MAX_SIZE; + bool securityProcessed = false; + bool csmaCaEnabled = false; + int8_t txPower = OT_RADIO_POWER_INVALID; + uint8_t maxFrameRetries = 0; + uint8_t maxCsmaBackoffs = 0; + uint8_t rxChannelAfterTxDone = mChannel; + uint32_t txDelayBaseTime = 0; + uint32_t txDelay = 0; while (aArgsLength > 1) { - if (StringMatch(aArgs[0], "-s")) + if (StringMatch(aArgs[0], "-b")) { - securityProcessed = true; + aArgs++; + aArgsLength--; + + VerifyOrExit(aArgsLength > 1, error = kErrorInvalidArgs); + SuccessOrExit(error = Utils::CmdLineParser::ParseAsUint8(aArgs[0], maxCsmaBackoffs)); + } + else if (StringMatch(aArgs[0], "-c")) + { + csmaCaEnabled = true; + } + else if (StringMatch(aArgs[0], "-C")) + { + aArgs++; + aArgsLength--; + + VerifyOrExit(aArgsLength > 1, error = kErrorInvalidArgs); + SuccessOrExit(error = Utils::CmdLineParser::ParseAsUint8(aArgs[0], rxChannelAfterTxDone)); + VerifyOrExit(IsChannelValid(rxChannelAfterTxDone), error = kErrorInvalidArgs); + } + else if (StringMatch(aArgs[0], "-d")) + { + aArgs++; + aArgsLength--; + + VerifyOrExit(aArgsLength > 1, error = kErrorInvalidArgs); + SuccessOrExit(error = Utils::CmdLineParser::ParseAsUint32(aArgs[0], txDelay)); + txDelayBaseTime = static_cast(otPlatRadioGetNow(&GetInstance())); } else if (StringMatch(aArgs[0], "-p")) { @@ -247,9 +278,17 @@ Error Diags::ProcessFrame(uint8_t aArgsLength, char *aArgs[]) VerifyOrExit(aArgsLength > 1, error = kErrorInvalidArgs); SuccessOrExit(error = Utils::CmdLineParser::ParseAsInt8(aArgs[0], txPower)); } - else if (StringMatch(aArgs[0], "-c")) + else if (StringMatch(aArgs[0], "-r")) { - csmaCaEnabled = true; + aArgs++; + aArgsLength--; + + VerifyOrExit(aArgsLength > 1, error = kErrorInvalidArgs); + SuccessOrExit(error = Utils::CmdLineParser::ParseAsUint8(aArgs[0], maxFrameRetries)); + } + else if (StringMatch(aArgs[0], "-s")) + { + securityProcessed = true; } else { @@ -267,11 +306,16 @@ Error Diags::ProcessFrame(uint8_t aArgsLength, char *aArgs[]) VerifyOrExit(size >= OT_RADIO_FRAME_MIN_SIZE, error = kErrorInvalidArgs); ResetTxPacket(); - mTxPacket->mInfo.mTxInfo.mCsmaCaEnabled = csmaCaEnabled; - mTxPacket->mInfo.mTxInfo.mIsSecurityProcessed = securityProcessed; - mTxPacket->mInfo.mTxInfo.mTxPower = txPower; - mTxPacket->mLength = size; - mIsTxPacketSet = true; + mTxPacket->mInfo.mTxInfo.mCsmaCaEnabled = csmaCaEnabled; + mTxPacket->mInfo.mTxInfo.mIsSecurityProcessed = securityProcessed; + mTxPacket->mInfo.mTxInfo.mTxPower = txPower; + mTxPacket->mInfo.mTxInfo.mTxDelayBaseTime = txDelayBaseTime; + mTxPacket->mInfo.mTxInfo.mTxDelay = txDelay; + mTxPacket->mInfo.mTxInfo.mMaxFrameRetries = maxFrameRetries; + mTxPacket->mInfo.mTxInfo.mMaxCsmaBackoffs = maxCsmaBackoffs; + mTxPacket->mInfo.mTxInfo.mRxChannelAfterTxDone = rxChannelAfterTxDone; + mTxPacket->mLength = size; + mIsTxPacketSet = true; exit: AppendErrorResult(error); @@ -293,7 +337,7 @@ Error Diags::ProcessChannel(uint8_t aArgsLength, char *aArgs[]) uint8_t channel; SuccessOrExit(error = Utils::CmdLineParser::ParseAsUint8(aArgs[0], channel)); - VerifyOrExit(channel >= Radio::kChannelMin && channel <= Radio::kChannelMax, error = kErrorInvalidArgs); + VerifyOrExit(IsChannelValid(channel), error = kErrorInvalidArgs); mChannel = channel; IgnoreError(Get().Receive(mChannel)); @@ -739,7 +783,7 @@ Error Diags::ProcessPowerSettings(uint8_t aArgsLength, char *aArgs[]) else if (aArgsLength == 1) { SuccessOrExit(error = Utils::CmdLineParser::ParseAsUint8(aArgs[0], channel)); - VerifyOrExit(channel >= Radio::kChannelMin && channel <= Radio::kChannelMax, error = kErrorInvalidArgs); + VerifyOrExit(IsChannelValid(channel), error = kErrorInvalidArgs); SuccessOrExit(error = GetPowerSettings(channel, powerSettings)); Output("TargetPower(0.01dBm): %d\r\nActualPower(0.01dBm): %d\r\nRawPowerSetting: %s\r\n", @@ -848,6 +892,11 @@ void Diags::AppendErrorResult(Error aError) } } +bool Diags::IsChannelValid(uint8_t aChannel) +{ + return (aChannel >= Radio::kChannelMin && aChannel <= Radio::kChannelMax); +} + Error Diags::ParseCmd(char *aString, uint8_t &aArgsLength, char *aArgs[]) { Error error; diff --git a/src/core/diags/factory_diags.hpp b/src/core/diags/factory_diags.hpp index a538edf93..074006202 100644 --- a/src/core/diags/factory_diags.hpp +++ b/src/core/diags/factory_diags.hpp @@ -204,6 +204,8 @@ private: void AppendErrorResult(Error aError); void ResetTxPacket(void); + static bool IsChannelValid(uint8_t aChannel); + static const struct Command sCommands[]; #if OPENTHREAD_FTD || OPENTHREAD_MTD || (OPENTHREAD_RADIO && OPENTHREAD_RADIO_CLI)