From c8cbfbe12d6bfae42a888930c0d2b4ffe7e21329 Mon Sep 17 00:00:00 2001 From: Zhanglong Xia Date: Fri, 3 Jan 2025 06:25:22 +0000 Subject: [PATCH] [diag] add 'diag send async' command support --- src/core/diags/README.md | 7 ++++-- src/core/diags/factory_diags.cpp | 37 ++++++++++++++++++++++++++---- src/core/diags/factory_diags.hpp | 1 + tests/scripts/expect/cli-diags.exp | 21 +++++++++++++++-- tools/otci/otci/otci.py | 11 +++++---- 5 files changed, 64 insertions(+), 13 deletions(-) diff --git a/src/core/diags/README.md b/src/core/diags/README.md index b5f4396ad95..810069805cd 100644 --- a/src/core/diags/README.md +++ b/src/core/diags/README.md @@ -14,7 +14,7 @@ The diagnostics module supports common diagnostics features that are listed belo - [diag stream](#diag-stream-start) - [diag power](#diag-power) - [diag powersettings](#diag-powersettings) -- [diag send](#diag-send-packets-length) +- [diag send](#diag-send-async-packets-length) - [diag repeat](#diag-repeat-delay-length) - [diag radio](#diag-radio-sleep) - [diag rawpowersetting](#diag-rawpowersetting) @@ -163,10 +163,11 @@ RawPowerSetting: 223344 Done ``` -### diag send \ [length] +### diag send [async] \ [length] Transmit a fixed number of packets. +- async: Use the non-blocking mode. - packets: The number of packets to be sent. - length: The length of packet. The valid range is [3, 127]. @@ -175,6 +176,8 @@ Send the frame set by `diag frame` if length is omitted. Otherwise overwrite the ```bash > diag send 20 100 Done +> diag send async 20 100 +Done ``` ### diag repeat \ [length] diff --git a/src/core/diags/factory_diags.cpp b/src/core/diags/factory_diags.cpp index de78c4d6dc3..204a80b4e81 100644 --- a/src/core/diags/factory_diags.cpp +++ b/src/core/diags/factory_diags.cpp @@ -199,6 +199,7 @@ Diags::Diags(Instance &aInstance) , mTxPower(0) , mTxLen(0) , mIsTxPacketSet(false) + , mIsAsyncSend(false) , mRepeatActive(false) , mDiagSendOn(false) , mOutputCallback(nullptr) @@ -429,6 +430,18 @@ Error Diags::ProcessSend(uint8_t aArgsLength, char *aArgs[]) VerifyOrExit(aArgsLength >= 1, error = kErrorInvalidArgs); + if (StringMatch(aArgs[0], "async")) + { + aArgs++; + aArgsLength--; + VerifyOrExit(aArgsLength >= 1, error = kErrorInvalidArgs); + mIsAsyncSend = true; + } + else + { + mIsAsyncSend = false; + } + SuccessOrExit(error = Utils::CmdLineParser::ParseAsUint32(aArgs[0], txPackets)); mTxPackets = txPackets; @@ -452,6 +465,11 @@ Error Diags::ProcessSend(uint8_t aArgsLength, char *aArgs[]) TransmitPacket(); + if (!mIsAsyncSend) + { + error = kErrorPending; + } + exit: return error; } @@ -852,11 +870,22 @@ void Diags::TransmitDone(Error aError) break; } - VerifyOrExit(!mRepeatActive); - VerifyOrExit(mTxPackets > 1); - mTxPackets--; + VerifyOrExit(!mRepeatActive && (mTxPackets > 0)); - TransmitPacket(); + if (mTxPackets > 1) + { + mTxPackets--; + TransmitPacket(); + } + else + { + mTxPackets = 0; + + if (!mIsAsyncSend) + { + Output("OT_ERROR_NONE"); + } + } exit: return; diff --git a/src/core/diags/factory_diags.hpp b/src/core/diags/factory_diags.hpp index 82e68b71f67..f06cafeebf1 100644 --- a/src/core/diags/factory_diags.hpp +++ b/src/core/diags/factory_diags.hpp @@ -255,6 +255,7 @@ class Diags : public InstanceLocator, private NonCopyable uint8_t mTxLen; bool mIsHeaderUpdated : 1; bool mIsTxPacketSet : 1; + bool mIsAsyncSend : 1; bool mRepeatActive : 1; bool mDiagSendOn : 1; #endif diff --git a/tests/scripts/expect/cli-diags.exp b/tests/scripts/expect/cli-diags.exp index e0f81e6d9f7..abe27a7f2ec 100755 --- a/tests/scripts/expect/cli-diags.exp +++ b/tests/scripts/expect/cli-diags.exp @@ -57,11 +57,25 @@ expect_line "Done" send "diag send 10 100\n" expect_line "Done" +send "diag stats\n" +expect "received packets: 0" +expect "sent success packets: 10" +expect "sent error cca packets: 0" +expect "sent error abort packets: 0" +expect "sent error others packets: 0" +expect "first received packet: rssi=0, lqi=0" +expect "last received packet: rssi=0, lqi=0" +expect_line "Done" + +send "diag send async 10 100\n" +expect "sending 0xa packet(s), length 0x64" +expect_line "Done" + sleep 2 send "diag stats\n" expect "received packets: 0" -expect "sent success packets: 10" +expect "sent success packets: 20" expect "sent error cca packets: 0" expect "sent error abort packets: 0" expect "sent error others packets: 0" @@ -72,7 +86,7 @@ expect_line "Done" switch_node 1 send "diag stats\n" -expect "received packets: 10" +expect "received packets: 20" expect "sent success packets: 0" expect "sent error cca packets: 0" expect "sent error abort packets: 0" @@ -139,6 +153,9 @@ expect "Done" send "diag repeat 1\n" expect "Done" +send "diag repeat stop\n" +expect "Done" + send_user "send frame with security processed\n" send "diag frame -s 112233\n" expect "Done" diff --git a/tools/otci/otci/otci.py b/tools/otci/otci/otci.py index 6f8aa964cdb..948919f72dd 100644 --- a/tools/otci/otci/otci.py +++ b/tools/otci/otci/otci.py @@ -2579,12 +2579,13 @@ def diag_stream_stop(self): """Stop transmitting a stream of characters.""" self.execute_command('diag stream stop') - def diag_send(self, packets: int, length: Optional[int] = None): + def diag_send(self, packets: int, length: Optional[int] = None, is_async: bool = True): """Transmit a fixed number of packets.""" - if length is None: - command = f'diag send {packets}' - else: - command = f'diag send {packets} {length}' + command = 'diag send ' + command += 'async ' if is_async else '' + command += f'{packets} ' + command += f'{length}' if length is not None else '' + self.execute_command(command) def diag_repeat(self, delay: int, length: Optional[int] = None):