mirror of
https://github.com/espressif/openthread.git
synced 2026-08-03 17:37:46 +00:00
[cli] add OutputUint64() for 64-bit integer value in decimal format (#8354)
This commit also adds a helper `Uint64ToString()` method to convert a `uint64_t` to decimal format string. The new methods allow us to output `uint64_t` values without needing to cast to `unsigned long long` and/or use of `%llu` (which may not be provided by certain embedded libraries).
This commit is contained in:
+58
-34
@@ -876,45 +876,47 @@ template <> otError Interpreter::Process<Cmd("nat64")>(Arg aArgs[])
|
||||
otNat64InitAddressMappingIterator(GetInstancePtr(), &iterator);
|
||||
while (otNat64GetNextAddressMapping(GetInstancePtr(), &iterator, &mapping) == OT_ERROR_NONE)
|
||||
{
|
||||
char ip4AddressString[OT_IP4_ADDRESS_STRING_SIZE];
|
||||
char ip6AddressString[OT_IP6_PREFIX_STRING_SIZE];
|
||||
char ip4AddressString[OT_IP4_ADDRESS_STRING_SIZE];
|
||||
char ip6AddressString[OT_IP6_PREFIX_STRING_SIZE];
|
||||
Uint64StringBuffer u64StringBuffer;
|
||||
|
||||
otIp6AddressToString(&mapping.mIp6, ip6AddressString, sizeof(ip6AddressString));
|
||||
otIp4AddressToString(&mapping.mIp4, ip4AddressString, sizeof(ip4AddressString));
|
||||
|
||||
OutputFormat("| %016llx ", mapping.mId);
|
||||
OutputFormat("| %08lx%08lx ", ToUlong(static_cast<uint32_t>(mapping.mId >> 32)),
|
||||
ToUlong(static_cast<uint32_t>(mapping.mId & 0xffffffff)));
|
||||
OutputFormat("| %40s ", ip6AddressString);
|
||||
OutputFormat("| %16s ", ip4AddressString);
|
||||
OutputFormat("| %5llus ", mapping.mRemainingTimeMs / 1000);
|
||||
OutputFormat("| %8llu ", mapping.mCounters.mTotal.m4To6Packets);
|
||||
OutputFormat("| %12llu ", mapping.mCounters.mTotal.m4To6Bytes);
|
||||
OutputFormat("| %8llu ", mapping.mCounters.mTotal.m6To4Packets);
|
||||
OutputFormat("| %12llu ", mapping.mCounters.mTotal.m6To4Bytes);
|
||||
OutputFormat("| %5lus ", ToUlong(mapping.mRemainingTimeMs / 1000));
|
||||
OutputFormat("| %8s ", Uint64ToString(mapping.mCounters.mTotal.m4To6Packets, u64StringBuffer));
|
||||
OutputFormat("| %12s ", Uint64ToString(mapping.mCounters.mTotal.m4To6Bytes, u64StringBuffer));
|
||||
OutputFormat("| %8s ", Uint64ToString(mapping.mCounters.mTotal.m6To4Packets, u64StringBuffer));
|
||||
OutputFormat("| %12s ", Uint64ToString(mapping.mCounters.mTotal.m6To4Bytes, u64StringBuffer));
|
||||
|
||||
OutputLine("|");
|
||||
|
||||
OutputFormat("| %016s ", "");
|
||||
OutputFormat("| %68s ", "TCP");
|
||||
OutputFormat("| %8llu ", mapping.mCounters.mTcp.m4To6Packets);
|
||||
OutputFormat("| %12llu ", mapping.mCounters.mTcp.m4To6Bytes);
|
||||
OutputFormat("| %8llu ", mapping.mCounters.mTcp.m6To4Packets);
|
||||
OutputFormat("| %12llu ", mapping.mCounters.mTcp.m6To4Bytes);
|
||||
OutputFormat("| %8s ", Uint64ToString(mapping.mCounters.mTcp.m4To6Packets, u64StringBuffer));
|
||||
OutputFormat("| %12s ", Uint64ToString(mapping.mCounters.mTcp.m4To6Bytes, u64StringBuffer));
|
||||
OutputFormat("| %8s ", Uint64ToString(mapping.mCounters.mTcp.m6To4Packets, u64StringBuffer));
|
||||
OutputFormat("| %12s ", Uint64ToString(mapping.mCounters.mTcp.m6To4Bytes, u64StringBuffer));
|
||||
OutputLine("|");
|
||||
|
||||
OutputFormat("| %016s ", "");
|
||||
OutputFormat("| %68s ", "UDP");
|
||||
OutputFormat("| %8llu ", mapping.mCounters.mUdp.m4To6Packets);
|
||||
OutputFormat("| %12llu ", mapping.mCounters.mUdp.m4To6Bytes);
|
||||
OutputFormat("| %8llu ", mapping.mCounters.mUdp.m6To4Packets);
|
||||
OutputFormat("| %12llu ", mapping.mCounters.mUdp.m6To4Bytes);
|
||||
OutputFormat("| %8s ", Uint64ToString(mapping.mCounters.mUdp.m4To6Packets, u64StringBuffer));
|
||||
OutputFormat("| %12s ", Uint64ToString(mapping.mCounters.mUdp.m4To6Bytes, u64StringBuffer));
|
||||
OutputFormat("| %8s ", Uint64ToString(mapping.mCounters.mUdp.m6To4Packets, u64StringBuffer));
|
||||
OutputFormat("| %12s ", Uint64ToString(mapping.mCounters.mUdp.m6To4Bytes, u64StringBuffer));
|
||||
OutputLine("|");
|
||||
|
||||
OutputFormat("| %016s ", "");
|
||||
OutputFormat("| %68s ", "ICMP");
|
||||
OutputFormat("| %8llu ", mapping.mCounters.mIcmp.m4To6Packets);
|
||||
OutputFormat("| %12llu ", mapping.mCounters.mIcmp.m4To6Bytes);
|
||||
OutputFormat("| %8llu ", mapping.mCounters.mIcmp.m6To4Packets);
|
||||
OutputFormat("| %12llu ", mapping.mCounters.mIcmp.m6To4Bytes);
|
||||
OutputFormat("| %8s ", Uint64ToString(mapping.mCounters.mIcmp.m4To6Packets, u64StringBuffer));
|
||||
OutputFormat("| %12s ", Uint64ToString(mapping.mCounters.mIcmp.m4To6Bytes, u64StringBuffer));
|
||||
OutputFormat("| %8s ", Uint64ToString(mapping.mCounters.mIcmp.m6To4Packets, u64StringBuffer));
|
||||
OutputFormat("| %12s ", Uint64ToString(mapping.mCounters.mIcmp.m6To4Bytes, u64StringBuffer));
|
||||
OutputLine("|");
|
||||
}
|
||||
}
|
||||
@@ -979,6 +981,7 @@ template <> otError Interpreter::Process<Cmd("nat64")>(Arg aArgs[])
|
||||
|
||||
otNat64ProtocolCounters counters;
|
||||
otNat64ErrorCounters errorCounters;
|
||||
Uint64StringBuffer u64StringBuffer;
|
||||
|
||||
OutputTableHeader(kNat64CounterTableHeader, kNat64CounterTableHeaderColumns);
|
||||
OutputTableHeader(kNat64CounterTableSubHeader, kNat64CounterTableSubHeaderColumns);
|
||||
@@ -986,20 +989,36 @@ template <> otError Interpreter::Process<Cmd("nat64")>(Arg aArgs[])
|
||||
otNat64GetCounters(GetInstancePtr(), &counters);
|
||||
otNat64GetErrorCounters(GetInstancePtr(), &errorCounters);
|
||||
|
||||
OutputLine("| %13s | %8llu | %12llu | %8llu | %12llu |", "Total", counters.mTotal.m4To6Packets,
|
||||
counters.mTotal.m4To6Bytes, counters.mTotal.m6To4Packets, counters.mTotal.m6To4Bytes);
|
||||
OutputLine("| %13s | %8llu | %12llu | %8llu | %12llu |", "TCP", counters.mTcp.m4To6Packets,
|
||||
counters.mTcp.m4To6Bytes, counters.mTcp.m6To4Packets, counters.mTcp.m6To4Bytes);
|
||||
OutputLine("| %13s | %8llu | %12llu | %8llu | %12llu |", "UDP", counters.mUdp.m4To6Packets,
|
||||
counters.mUdp.m4To6Bytes, counters.mUdp.m6To4Packets, counters.mUdp.m6To4Bytes);
|
||||
OutputLine("| %13s | %8llu | %12llu | %8llu | %12llu |", "ICMP", counters.mIcmp.m4To6Packets,
|
||||
counters.mIcmp.m4To6Bytes, counters.mIcmp.m6To4Packets, counters.mIcmp.m6To4Bytes);
|
||||
OutputFormat("| %13s ", "Total");
|
||||
OutputFormat("| %8s ", Uint64ToString(counters.mTotal.m4To6Packets, u64StringBuffer));
|
||||
OutputFormat("| %12s ", Uint64ToString(counters.mTotal.m4To6Bytes, u64StringBuffer));
|
||||
OutputFormat("| %8s ", Uint64ToString(counters.mTotal.m6To4Packets, u64StringBuffer));
|
||||
OutputLine("| %12s |", Uint64ToString(counters.mTotal.m6To4Bytes, u64StringBuffer));
|
||||
|
||||
OutputFormat("| %13s ", "TCP");
|
||||
OutputFormat("| %8s ", Uint64ToString(counters.mTcp.m4To6Packets, u64StringBuffer));
|
||||
OutputFormat("| %12s ", Uint64ToString(counters.mTcp.m4To6Bytes, u64StringBuffer));
|
||||
OutputFormat("| %8s ", Uint64ToString(counters.mTcp.m6To4Packets, u64StringBuffer));
|
||||
OutputLine("| %12s |", Uint64ToString(counters.mTcp.m6To4Bytes, u64StringBuffer));
|
||||
|
||||
OutputFormat("| %13s ", "UDP");
|
||||
OutputFormat("| %8s ", Uint64ToString(counters.mUdp.m4To6Packets, u64StringBuffer));
|
||||
OutputFormat("| %12s ", Uint64ToString(counters.mUdp.m4To6Bytes, u64StringBuffer));
|
||||
OutputFormat("| %8s ", Uint64ToString(counters.mUdp.m6To4Packets, u64StringBuffer));
|
||||
OutputLine("| %12s |", Uint64ToString(counters.mUdp.m6To4Bytes, u64StringBuffer));
|
||||
|
||||
OutputFormat("| %13s ", "ICMP");
|
||||
OutputFormat("| %8s ", Uint64ToString(counters.mIcmp.m4To6Packets, u64StringBuffer));
|
||||
OutputFormat("| %12s ", Uint64ToString(counters.mIcmp.m4To6Bytes, u64StringBuffer));
|
||||
OutputFormat("| %8s ", Uint64ToString(counters.mIcmp.m6To4Packets, u64StringBuffer));
|
||||
OutputLine("| %12s |", Uint64ToString(counters.mIcmp.m6To4Bytes, u64StringBuffer));
|
||||
|
||||
OutputTableHeader(kNat64CounterTableErrorSubHeader, kNat64CounterTableErrorSubHeaderColumns);
|
||||
for (uint8_t i = 0; i < OT_NAT64_DROP_REASON_COUNT; i++)
|
||||
{
|
||||
OutputLine("| %13s | %23llu | %23llu |", kNat64CounterErrorType[i], errorCounters.mCount4To6[i],
|
||||
errorCounters.mCount6To4[i]);
|
||||
OutputFormat("| %13s | %23s ", kNat64CounterErrorType[i],
|
||||
Uint64ToString(errorCounters.mCount4To6[i], u64StringBuffer));
|
||||
OutputLine("| %23s |", Uint64ToString(errorCounters.mCount6To4[i], u64StringBuffer));
|
||||
}
|
||||
}
|
||||
#endif // OPENTHREAD_CONFIG_NAT64_TRANSLATOR_ENABLE
|
||||
@@ -2652,9 +2671,12 @@ template <> otError Interpreter::Process<Cmd("counters")>(Arg aArgs[])
|
||||
|
||||
for (const MleTimeCounterName &counter : kTimeCounterNames)
|
||||
{
|
||||
OutputLine("Time %s Milli: %lu", counter.mName, mleCounters->*counter.mValuePtr);
|
||||
OutputFormat("Time %s Milli: ", counter.mName);
|
||||
OutputUint64Line(mleCounters->*counter.mValuePtr);
|
||||
}
|
||||
OutputLine("Time Tracked Milli: %lu", mleCounters->mTrackedTime);
|
||||
|
||||
OutputFormat("Time Tracked Milli: ");
|
||||
OutputUint64Line(mleCounters->mTrackedTime);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -5076,7 +5098,9 @@ template <> otError Interpreter::Process<Cmd("networktime")>(Arg aArgs[])
|
||||
|
||||
networkTimeStatus = otNetworkTimeGet(GetInstancePtr(), &time);
|
||||
|
||||
OutputFormat("Network Time: %luus", time);
|
||||
OutputFormat("Network Time: ");
|
||||
OutputUint64(time);
|
||||
OutputFormat("us");
|
||||
|
||||
switch (networkTimeStatus)
|
||||
{
|
||||
@@ -6336,7 +6360,7 @@ template <> otError Interpreter::Process<Cmd("uptime")>(Arg aArgs[])
|
||||
}
|
||||
else if (aArgs[0] == "ms")
|
||||
{
|
||||
OutputLine("%lu", otInstanceGetUptime(GetInstancePtr()));
|
||||
OutputUint64Line(otInstanceGetUptime(GetInstancePtr()));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -117,7 +117,9 @@ template <> otError Commissioner::Process<Cmd("joiner")>(Arg aArgs[])
|
||||
break;
|
||||
|
||||
case OT_JOINER_INFO_TYPE_DISCERNER:
|
||||
OutputFormat("| 0x%016llx/%2u", static_cast<unsigned long long>(joinerInfo.mSharedId.mDiscerner.mValue),
|
||||
OutputFormat("| 0x%08lx%08lx/%2u",
|
||||
static_cast<unsigned long>(joinerInfo.mSharedId.mDiscerner.mValue >> 32),
|
||||
static_cast<unsigned long>(joinerInfo.mSharedId.mDiscerner.mValue & 0xffffffff),
|
||||
joinerInfo.mSharedId.mDiscerner.mLength);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -51,12 +51,14 @@ otError Dataset::Print(otOperationalDataset &aDataset)
|
||||
{
|
||||
if (aDataset.mComponents.mIsPendingTimestampPresent)
|
||||
{
|
||||
OutputLine("Pending Timestamp: %lu", aDataset.mPendingTimestamp.mSeconds);
|
||||
OutputFormat("Pending Timestamp: ");
|
||||
OutputUint64Line(aDataset.mPendingTimestamp.mSeconds);
|
||||
}
|
||||
|
||||
if (aDataset.mComponents.mIsActiveTimestampPresent)
|
||||
{
|
||||
OutputLine("Active Timestamp: %lu", aDataset.mActiveTimestamp.mSeconds);
|
||||
OutputFormat("Active Timestamp: ");
|
||||
OutputUint64Line(aDataset.mActiveTimestamp.mSeconds);
|
||||
}
|
||||
|
||||
if (aDataset.mComponents.mIsChannelPresent)
|
||||
@@ -264,7 +266,7 @@ template <> otError Dataset::Process<Cmd("activetimestamp")>(Arg aArgs[])
|
||||
{
|
||||
if (sDataset.mComponents.mIsActiveTimestampPresent)
|
||||
{
|
||||
OutputLine("%lu", sDataset.mActiveTimestamp.mSeconds);
|
||||
OutputUint64Line(sDataset.mActiveTimestamp.mSeconds);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -666,7 +668,7 @@ template <> otError Dataset::Process<Cmd("pendingtimestamp")>(Arg aArgs[])
|
||||
{
|
||||
if (sDataset.mComponents.mIsPendingTimestampPresent)
|
||||
{
|
||||
OutputLine("%lu", sDataset.mPendingTimestamp.mSeconds);
|
||||
OutputUint64Line(sDataset.mPendingTimestamp.mSeconds);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
+10
-1
@@ -62,7 +62,16 @@ template <> otError Joiner::Process<Cmd("discerner")>(Arg aArgs[])
|
||||
|
||||
VerifyOrExit(discerner != nullptr, error = OT_ERROR_NOT_FOUND);
|
||||
|
||||
OutputLine("0x%llx/%u", static_cast<unsigned long long>(discerner->mValue), discerner->mLength);
|
||||
if (discerner->mValue <= 0xffffffff)
|
||||
{
|
||||
OutputLine("0x%lx/%u", static_cast<unsigned long>(discerner->mValue & 0xffffffff), discerner->mLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
OutputLine("0x%lx%08lx/%u", static_cast<unsigned long>(discerner->mValue >> 32),
|
||||
static_cast<unsigned long>(discerner->mValue & 0xffffffff), discerner->mLength);
|
||||
}
|
||||
|
||||
error = OT_ERROR_NONE;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -127,6 +127,40 @@ void Output::OutputBytesLine(const uint8_t *aBytes, uint16_t aLength)
|
||||
OutputLine("");
|
||||
}
|
||||
|
||||
const char *Output::Uint64ToString(uint64_t aUint64, Uint64StringBuffer &aBuffer)
|
||||
{
|
||||
char *cur = &aBuffer.mChars[Uint64StringBuffer::kSize - 1];
|
||||
|
||||
*cur = '\0';
|
||||
|
||||
if (aUint64 == 0)
|
||||
{
|
||||
*(--cur) = '0';
|
||||
}
|
||||
else
|
||||
{
|
||||
for (; aUint64 != 0; aUint64 /= 10)
|
||||
{
|
||||
*(--cur) = static_cast<char>('0' + static_cast<uint8_t>(aUint64 % 10));
|
||||
}
|
||||
}
|
||||
|
||||
return cur;
|
||||
}
|
||||
|
||||
void Output::OutputUint64(uint64_t aUint64)
|
||||
{
|
||||
Uint64StringBuffer buffer;
|
||||
|
||||
OutputFormat("%s", Uint64ToString(aUint64, buffer));
|
||||
}
|
||||
|
||||
void Output::OutputUint64Line(uint64_t aUint64)
|
||||
{
|
||||
OutputUint64(aUint64);
|
||||
OutputLine("");
|
||||
}
|
||||
|
||||
void Output::OutputEnabledDisabledStatus(bool aEnabled)
|
||||
{
|
||||
OutputLine(aEnabled ? "Enabled" : "Disabled");
|
||||
|
||||
@@ -202,6 +202,28 @@ public:
|
||||
*/
|
||||
otInstance *GetInstancePtr(void) { return mInstance; }
|
||||
|
||||
/**
|
||||
* This structure represents a buffer which is sued when converting a `uint64` value to string in decimal format.
|
||||
*
|
||||
*/
|
||||
struct Uint64StringBuffer
|
||||
{
|
||||
static constexpr uint16_t kSize = 21; ///< Size of a buffer
|
||||
|
||||
char mChars[kSize]; ///< Char array (do not access the array directly).
|
||||
};
|
||||
|
||||
/**
|
||||
* This static method converts a `uint64_t` value to a decimal format string.
|
||||
*
|
||||
* @param[in] aUint64 The `uint64_t` value to convert.
|
||||
* @param[in] aBuffer A buffer to allocate the string from.
|
||||
*
|
||||
* @returns A pointer to the start of the string (null-terminated) representation of @p aUint64.
|
||||
*
|
||||
*/
|
||||
static const char *Uint64ToString(uint64_t aUint64, Uint64StringBuffer &aBuffer);
|
||||
|
||||
/**
|
||||
* This method delivers a formatted output string to the CLI console.
|
||||
*
|
||||
@@ -312,6 +334,22 @@ public:
|
||||
*/
|
||||
void OutputExtAddressLine(const otExtAddress &aExtAddress) { OutputBytesLine(aExtAddress.m8); }
|
||||
|
||||
/**
|
||||
* This method outputs a `uint64_t` value in decimal format.
|
||||
*
|
||||
* @param[in] aUint64 The `uint64_t` value to output.
|
||||
*
|
||||
*/
|
||||
void OutputUint64(uint64_t aUint64);
|
||||
|
||||
/**
|
||||
* This method outputs a `uint64_t` value in decimal format and at the end it also outputs newline "\r\n".
|
||||
*
|
||||
* @param[in] aUint64 The `uint64_t` value to output.
|
||||
*
|
||||
*/
|
||||
void OutputUint64Line(uint64_t aUint64);
|
||||
|
||||
/**
|
||||
* This method outputs "Enabled" or "Disabled" status to the CLI console (it also appends newline "\r\n").
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user