diff --git a/src/cli/README_TCP.md b/src/cli/README_TCP.md index 3869570b8..6281fd88b 100644 --- a/src/cli/README_TCP.md +++ b/src/cli/README_TCP.md @@ -60,7 +60,7 @@ For a more in-depth example, see [this video](https://youtu.be/ppZ784YUKlI). - [bind](#bind-ip-port) - [connect](#connect-ip-port) - [send](#send-message) -- [benchmark](#benchmark-size) +- [benchmark](#benchmark-run-size) - [sendend](#sendend) - [abort](#abort) - [listen](#listen-ip-port) @@ -78,19 +78,34 @@ TCP: Connection reset Done ``` -### benchmark [\] +### benchmark run [\] Transfers the specified number of bytes using the TCP connection currently associated with the example TCP endpoint (this TCP connection must be established before using this command). - size: the number of bytes to send for the benchmark. If it is left unspecified, the default size is used. ```bash -> tcp benchmark +> tcp benchmark run Done TCP Benchmark Complete: Transferred 73728 bytes in 7233 milliseconds TCP Goodput: 81.546 kb/s ``` +### benchmark result + +Get the last result of TCP benchmark. If the benchmark is ongoing, it will show that benchmark is ongoing. This command is used for test scripts which automate the tcp benchmark test. + +``` +> tcp benchmark result +TCP Benchmark Status: Ongoing +Done + +> tcp benchmark result +TCP Benchmark Status: Completed +TCP Benchmark Complete: Transferred 73728 bytes in 7056 milliseconds +TCP Goodput: 83.592 kb/s +``` + ### bind \ \ Associates a name (i.e. IPv6 address and port) to the example TCP endpoint. diff --git a/src/cli/cli_tcp.cpp b/src/cli/cli_tcp.cpp index 3e1cc82ff..f74f43331 100644 --- a/src/cli/cli_tcp.cpp +++ b/src/cli/cli_tcp.cpp @@ -70,6 +70,7 @@ TcpExample::TcpExample(otInstance *aInstance, OutputImplementer &aOutputImplemen , mTlsHandshakeComplete(false) , mBenchmarkBytesTotal(0) , mBenchmarkBytesUnsent(0) + , mBenchmarkTimeUsed(0) { mEndpointAndCircularSendBuffer.mEndpoint = &mEndpoint; mEndpointAndCircularSendBuffer.mSendBuffer = &mSendBuffer; @@ -377,48 +378,73 @@ template <> otError TcpExample::Process(Arg aArgs[]) { otError error = OT_ERROR_NONE; - VerifyOrExit(!mSendBusy, error = OT_ERROR_BUSY); - VerifyOrExit(mBenchmarkBytesTotal == 0, error = OT_ERROR_BUSY); - - if (aArgs[0].IsEmpty()) + if (aArgs[0] == "result") { - mBenchmarkBytesTotal = OPENTHREAD_CONFIG_CLI_TCP_DEFAULT_BENCHMARK_SIZE; - } - else - { - SuccessOrExit(error = aArgs[0].ParseAsUint32(mBenchmarkBytesTotal)); - VerifyOrExit(mBenchmarkBytesTotal != 0, error = OT_ERROR_INVALID_ARGS); - } - VerifyOrExit(aArgs[1].IsEmpty(), error = OT_ERROR_INVALID_ARGS); - - mBenchmarkStart = TimerMilli::GetNow(); - mBenchmarkBytesUnsent = mBenchmarkBytesTotal; - - if (mUseCircularSendBuffer) - { - SuccessOrExit(error = ContinueBenchmarkCircularSend()); - } - else - { - uint32_t benchmarkLinksLeft = (mBenchmarkBytesTotal + sizeof(mSendBufferBytes) - 1) / sizeof(mSendBufferBytes); - uint32_t toSendOut = OT_MIN(OT_ARRAY_LENGTH(mBenchmarkLinks), benchmarkLinksLeft); - - /* We could also point the linked buffers directly to sBenchmarkData. */ - memset(mSendBufferBytes, 'a', sizeof(mSendBufferBytes)); - - for (uint32_t i = 0; i != toSendOut; i++) + OutputFormat("TCP Benchmark Status: "); + if (mBenchmarkBytesTotal != 0) { - mBenchmarkLinks[i].mNext = nullptr; - mBenchmarkLinks[i].mData = mSendBufferBytes; - mBenchmarkLinks[i].mLength = sizeof(mSendBufferBytes); - if (i == 0 && mBenchmarkBytesTotal % sizeof(mSendBufferBytes) != 0) - { - mBenchmarkLinks[i].mLength = mBenchmarkBytesTotal % sizeof(mSendBufferBytes); - } - error = otTcpSendByReference(&mEndpoint, &mBenchmarkLinks[i], - i == toSendOut - 1 ? 0 : OT_TCP_SEND_MORE_TO_COME); - VerifyOrExit(error == OT_ERROR_NONE, mBenchmarkBytesTotal = 0); + OutputLine("Ongoing"); } + else if (mBenchmarkTimeUsed != 0) + { + OutputLine("Completed"); + OutputBenchmarkResult(); + } + else + { + OutputLine("Untested"); + } + } + else if (aArgs[0] == "run") + { + VerifyOrExit(!mSendBusy, error = OT_ERROR_BUSY); + VerifyOrExit(mBenchmarkBytesTotal == 0, error = OT_ERROR_BUSY); + + if (aArgs[1].IsEmpty()) + { + mBenchmarkBytesTotal = OPENTHREAD_CONFIG_CLI_TCP_DEFAULT_BENCHMARK_SIZE; + } + else + { + SuccessOrExit(error = aArgs[1].ParseAsUint32(mBenchmarkBytesTotal)); + VerifyOrExit(mBenchmarkBytesTotal != 0, error = OT_ERROR_INVALID_ARGS); + } + VerifyOrExit(aArgs[2].IsEmpty(), error = OT_ERROR_INVALID_ARGS); + + mBenchmarkStart = TimerMilli::GetNow(); + mBenchmarkBytesUnsent = mBenchmarkBytesTotal; + + if (mUseCircularSendBuffer) + { + SuccessOrExit(error = ContinueBenchmarkCircularSend()); + } + else + { + uint32_t benchmarkLinksLeft = + (mBenchmarkBytesTotal + sizeof(mSendBufferBytes) - 1) / sizeof(mSendBufferBytes); + uint32_t toSendOut = OT_MIN(OT_ARRAY_LENGTH(mBenchmarkLinks), benchmarkLinksLeft); + + /* We could also point the linked buffers directly to sBenchmarkData. */ + memset(mSendBufferBytes, 'a', sizeof(mSendBufferBytes)); + + for (uint32_t i = 0; i != toSendOut; i++) + { + mBenchmarkLinks[i].mNext = nullptr; + mBenchmarkLinks[i].mData = mSendBufferBytes; + mBenchmarkLinks[i].mLength = sizeof(mSendBufferBytes); + if (i == 0 && mBenchmarkBytesTotal % sizeof(mSendBufferBytes) != 0) + { + mBenchmarkLinks[i].mLength = mBenchmarkBytesTotal % sizeof(mSendBufferBytes); + } + error = otTcpSendByReference(&mEndpoint, &mBenchmarkLinks[i], + i == toSendOut - 1 ? 0 : OT_TCP_SEND_MORE_TO_COME); + VerifyOrExit(error == OT_ERROR_NONE, mBenchmarkBytesTotal = 0); + } + } + } + else + { + error = OT_ERROR_INVALID_ARGS; } exit: @@ -860,15 +886,24 @@ exit: return error; } -void TcpExample::CompleteBenchmark(void) +void TcpExample::OutputBenchmarkResult(void) { - uint32_t milliseconds = TimerMilli::GetNow() - mBenchmarkStart; - uint32_t thousandTimesGoodput = (1000 * (mBenchmarkBytesTotal << 3) + (milliseconds >> 1)) / milliseconds; + uint32_t thousandTimesGoodput = + (1000 * (mBenchmarkLastBytesTotal << 3) + (mBenchmarkTimeUsed >> 1)) / mBenchmarkTimeUsed; - OutputLine("TCP Benchmark Complete: Transferred %lu bytes in %lu milliseconds", ToUlong(mBenchmarkBytesTotal), - ToUlong(milliseconds)); + OutputLine("TCP Benchmark Complete: Transferred %lu bytes in %lu milliseconds", ToUlong(mBenchmarkLastBytesTotal), + ToUlong(mBenchmarkTimeUsed)); OutputLine("TCP Goodput: %lu.%03u kb/s", ToUlong(thousandTimesGoodput / 1000), static_cast(thousandTimesGoodput % 1000)); +} + +void TcpExample::CompleteBenchmark(void) +{ + mBenchmarkTimeUsed = TimerMilli::GetNow() - mBenchmarkStart; + mBenchmarkLastBytesTotal = mBenchmarkBytesTotal; + + OutputBenchmarkResult(); + mBenchmarkBytesTotal = 0; } diff --git a/src/cli/cli_tcp.hpp b/src/cli/cli_tcp.hpp index 745af2be7..24bb75fd1 100644 --- a/src/cli/cli_tcp.hpp +++ b/src/cli/cli_tcp.hpp @@ -131,6 +131,8 @@ private: static void MbedTlsDebugOutput(void *ctx, int level, const char *file, int line, const char *str); #endif + void OutputBenchmarkResult(void); + otTcpEndpoint mEndpoint; otTcpListener mListener; @@ -151,7 +153,8 @@ private: uint32_t mBenchmarkBytesTotal; uint32_t mBenchmarkBytesUnsent; TimeMilli mBenchmarkStart; - + uint32_t mBenchmarkTimeUsed; + uint32_t mBenchmarkLastBytesTotal; otTcpEndpointAndCircularSendBuffer mEndpointAndCircularSendBuffer; #if OPENTHREAD_CONFIG_TLS_ENABLE