From 70d315af23cd7216f7fc360d01de43c85c7a539f Mon Sep 17 00:00:00 2001 From: Zhanglong Xia Date: Thu, 9 Jan 2025 03:21:13 +0800 Subject: [PATCH] [diag] add `diag send async` command support (#11111) The original `diag send` command is an asynchronous command. Users must wait for a certain period of time and then run the `diag stats` command to query how many packets have been sent to know whether all packets have been sent. This is very inefficient, and it is not convenient for scripts to process this command. This commit changes the command `diag send` from an asynchronous command to a synchronous command, and add the asynchronous command `diag send async`. --- 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 | 22 +++++++++++++++--- tools/otci/otci/otci.py | 11 +++++---- 5 files changed, 64 insertions(+), 14 deletions(-) diff --git a/src/core/diags/README.md b/src/core/diags/README.md index b5f4396ad..810069805 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 de78c4d6d..204a80b4e 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 82e68b71f..f06cafeeb 100644 --- a/src/core/diags/factory_diags.hpp +++ b/src/core/diags/factory_diags.hpp @@ -255,6 +255,7 @@ private: 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 e0f81e6d9..f7c8be8f2 100755 --- a/tests/scripts/expect/cli-diags.exp +++ b/tests/scripts/expect/cli-diags.exp @@ -57,8 +57,6 @@ expect_line "Done" send "diag send 10 100\n" expect_line "Done" -sleep 2 - send "diag stats\n" expect "received packets: 0" expect "sent success packets: 10" @@ -69,10 +67,25 @@ 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_line "Done" + +sleep 2 + +send "diag stats\n" +expect "received packets: 0" +expect "sent success packets: 20" +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" + 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 +152,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 6f8aa964c..948919f72 100644 --- a/tools/otci/otci/otci.py +++ b/tools/otci/otci/otci.py @@ -2579,12 +2579,13 @@ class OTCI(object): """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):