From fa71a8afa3fa2eac8848c3c0dfda13780484f39a Mon Sep 17 00:00:00 2001 From: Yakun Xu Date: Thu, 13 Jun 2024 22:53:48 +0800 Subject: [PATCH] [diag] specify sending frame (#10359) This commit adds an extra command `diag frame` to specify the frame used for `diag send` and `diag repeat`, so that we can use this command to send arbitrary 802.15.4 frames. --- src/core/diags/README.md | 19 ++++++--- src/core/diags/factory_diags.cpp | 66 ++++++++++++++++++++++++++---- src/core/diags/factory_diags.hpp | 2 + tests/scripts/expect/cli-diags.exp | 29 +++++++++++++ 4 files changed, 104 insertions(+), 12 deletions(-) diff --git a/src/core/diags/README.md b/src/core/diags/README.md index 2ddb658ac..ee447b3f9 100644 --- a/src/core/diags/README.md +++ b/src/core/diags/README.md @@ -77,6 +77,15 @@ Stop transmitting continuous carrier wave. Done ``` +### diag frame \ + +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`. + +```bash +> diag frame 11223344 +Done +``` + ### diag stream start Start transmitting a stream of characters. @@ -143,11 +152,11 @@ RawPowerSetting: 223344 Done ``` -### diag send \ \ +### diag send \ [length] -Transmit a fixed number of packets with fixed length. +Transmit a fixed number of packets. -Length parameter has to be in range [3, 127]. +Send the frame set by `diag frame` if length is omitted. Otherwise overwrite the frame set by `diag frame` and send a frame of the given length(MUST be in range [3, 127]). ```bash > diag send 20 100 @@ -155,11 +164,11 @@ sending 0x14 packet(s), length 0x64 status 0x00 ``` -### diag repeat \ \ +### diag repeat \ [length] Transmit packets repeatedly with a fixed interval. -Length parameter has to be in range [3, 127]. +Send the frame set by `diag frame` if length is omitted. Otherwise overwrite the frame set by `diag frame` and send a frame of the given length (MUST be in range [3, 127]). ```bash > diag repeat 100 100 diff --git a/src/core/diags/factory_diags.cpp b/src/core/diags/factory_diags.cpp index 78845f1aa..03ce33d72 100644 --- a/src/core/diags/factory_diags.cpp +++ b/src/core/diags/factory_diags.cpp @@ -32,6 +32,7 @@ */ #include "factory_diags.hpp" +#include "common/error.hpp" #if OPENTHREAD_CONFIG_DIAG_ENABLE @@ -187,6 +188,7 @@ extern "C" void otPlatDiagAlarmFired(otInstance *aInstance) { otPlatDiagAlarmCal const struct Diags::Command Diags::sCommands[] = { {"channel", &Diags::ProcessChannel}, {"cw", &Diags::ProcessContinuousWave}, + {"frame", &Diags::ProcessFrame}, {"gpio", &Diags::ProcessGpio}, {"power", &Diags::ProcessPower}, {"powersettings", &Diags::ProcessPowerSettings}, @@ -208,12 +210,31 @@ Diags::Diags(Instance &aInstance) , mChannel(20) , mTxPower(0) , mTxLen(0) + , mIsTxPacketSet(false) , mRepeatActive(false) , mDiagSendOn(false) { mStats.Clear(); } +Error Diags::ProcessFrame(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen) +{ + Error error = kErrorNone; + uint16_t size = OT_RADIO_FRAME_MAX_SIZE; + + VerifyOrExit(aArgsLength == 1, error = kErrorInvalidArgs); + + SuccessOrExit(error = Utils::CmdLineParser::ParseAsHexString(aArgs[0], size, mTxPacket->mPsdu)); + VerifyOrExit(size <= OT_RADIO_FRAME_MAX_SIZE, error = kErrorInvalidArgs); + VerifyOrExit(size >= OT_RADIO_FRAME_MIN_SIZE, error = kErrorInvalidArgs); + mTxPacket->mLength = size; + mIsTxPacketSet = true; + +exit: + AppendErrorResult(error, aOutput, aOutputMaxLen); + return error; +} + Error Diags::ProcessChannel(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen) { Error error = kErrorNone; @@ -288,12 +309,25 @@ Error Diags::ProcessRepeat(uint8_t aArgsLength, char *aArgs[], char *aOutput, si { long value; - VerifyOrExit(aArgsLength == 2, error = kErrorInvalidArgs); + VerifyOrExit(aArgsLength >= 1, error = kErrorInvalidArgs); SuccessOrExit(error = ParseLong(aArgs[0], value)); mTxPeriod = static_cast(value); - SuccessOrExit(error = ParseLong(aArgs[1], value)); + if (aArgsLength >= 2) + { + SuccessOrExit(error = ParseLong(aArgs[1], value)); + mIsTxPacketSet = false; + } + else if (mIsTxPacketSet) + { + value = mTxPacket->mLength; + } + else + { + ExitNow(error = kErrorInvalidArgs); + } + VerifyOrExit(value <= OT_RADIO_FRAME_MAX_SIZE, error = kErrorInvalidArgs); VerifyOrExit(value >= OT_RADIO_FRAME_MIN_SIZE, error = kErrorInvalidArgs); mTxLen = static_cast(value); @@ -316,12 +350,25 @@ Error Diags::ProcessSend(uint8_t aArgsLength, char *aArgs[], char *aOutput, size long value; VerifyOrExit(otPlatDiagModeGet(), error = kErrorInvalidState); - VerifyOrExit(aArgsLength == 2, error = kErrorInvalidArgs); + VerifyOrExit(aArgsLength >= 1, error = kErrorInvalidArgs); SuccessOrExit(error = ParseLong(aArgs[0], value)); mTxPackets = static_cast(value); - SuccessOrExit(error = ParseLong(aArgs[1], value)); + if (aArgsLength >= 2) + { + SuccessOrExit(ParseLong(aArgs[1], value)); + mIsTxPacketSet = false; + } + else if (mIsTxPacketSet) + { + value = mTxPacket->mLength; + } + else + { + ExitNow(error = kErrorInvalidArgs); + } + VerifyOrExit(value <= OT_RADIO_FRAME_MAX_SIZE, error = kErrorInvalidArgs); VerifyOrExit(value >= OT_RADIO_FRAME_MIN_SIZE, error = kErrorInvalidArgs); mTxLen = static_cast(value); @@ -420,12 +467,16 @@ exit: void Diags::TransmitPacket(void) { - mTxPacket->mLength = mTxLen; mTxPacket->mChannel = mChannel; - for (uint8_t i = 0; i < mTxLen; i++) + if (!mIsTxPacketSet) { - mTxPacket->mPsdu[i] = i; + mTxPacket->mLength = mTxLen; + + for (uint8_t i = 0; i < mTxLen; i++) + { + mTxPacket->mPsdu[i] = i; + } } mDiagSendOn = true; @@ -986,4 +1037,5 @@ OT_TOOL_WEAK otError otPlatDiagRadioGetPowerSettings(otInstance *aInstance, return OT_ERROR_NOT_IMPLEMENTED; } + #endif // OPENTHREAD_CONFIG_DIAG_ENABLE diff --git a/src/core/diags/factory_diags.hpp b/src/core/diags/factory_diags.hpp index 1b72a1563..cb1c7b95b 100644 --- a/src/core/diags/factory_diags.hpp +++ b/src/core/diags/factory_diags.hpp @@ -181,6 +181,7 @@ private: Error ParseCmd(char *aString, uint8_t &aArgsLength, char *aArgs[]); Error ProcessChannel(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen); + Error ProcessFrame(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen); Error ProcessContinuousWave(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen); Error ProcessGpio(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen); Error ProcessPower(uint8_t aArgsLength, char *aArgs[], char *aOutput, size_t aOutputMaxLen); @@ -217,6 +218,7 @@ private: uint8_t mChannel; int8_t mTxPower; uint8_t mTxLen; + bool mIsTxPacketSet; bool mRepeatActive; bool mDiagSendOn; #endif diff --git a/tests/scripts/expect/cli-diags.exp b/tests/scripts/expect/cli-diags.exp index e5d2fbfab..b9ab58071 100755 --- a/tests/scripts/expect/cli-diags.exp +++ b/tests/scripts/expect/cli-diags.exp @@ -126,6 +126,35 @@ expect "start diagnostics mode" expect "status 0x00" expect_line "Done" +send_user "input too short test\n" +send "diag frame 11\n" +expect "Error" + +send_user "input too long test\n" +send "diag frame 11223344556677889900112233445566778899001122334455667788990011223344556677889900112233445566778899001122334455667788990011223344556677889900112233445566778899001122334455667788990011223344556677889900112233445566778899001122334455667788990011223344556677889900\n" +expect "Error" + +send_user "input odd length test\n" +send "diag frame 123\n" +expect "Error" + +send_user "shortest frame test\n" +send "diag frame 112233\n" +expect "Done" +send "diag send 1\n" +expect "length 0x3" +expect "Done" + +send_user "longest frame test\n" +send "diag frame 11223344556677889900112233445566778899001122334455667788990011223344556677889900112233445566778899001122334455667788990011223344556677889900112233445566778899001122334455667788990011223344556677889900112233445566778899001122334455667788990011223344556677\n" +expect "Done" +send "diag repeat 1\n" +expect "length 0x7f" +expect "Done" + +send "diag repeat stop\n" +expect "Done" + send "diag channel 11\n" expect "set channel to 11" expect "status 0x00"