mirror of
https://github.com/espressif/openthread.git
synced 2026-10-14 19:57:40 +00:00
[cli] add new command neighbor linkquality (#8508)
This commit adds a new CLI command `neighbor linkqulaity` which prints the collected link quality info (such as frame error rate, message error rate, average/last RSSI) for all neighbors.
This commit is contained in:
@@ -2061,6 +2061,19 @@ Get the NAT64 translator packet and error counters.
|
|||||||
Done
|
Done
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### neighbor linkquality
|
||||||
|
|
||||||
|
Print link quality info for all neighbors.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
> neighbor linkquality
|
||||||
|
| RLOC16 | Extended MAC | Frame Error | Msg Error | Avg RSS | Last RSS | Age |
|
||||||
|
+--------+------------------+-------------+-----------+---------+----------+-------+
|
||||||
|
| 0xe800 | 9e2fa4e1b84f92db | 0.00 % | 0.00 % | -46 | -48 | 1 |
|
||||||
|
| 0xc001 | 0ad7ed6beaa6016d | 4.67 % | 0.08 % | -68 | -72 | 10 |
|
||||||
|
Done
|
||||||
|
```
|
||||||
|
|
||||||
### neighbor list
|
### neighbor list
|
||||||
|
|
||||||
List RLOC16 of neighbors.
|
List RLOC16 of neighbors.
|
||||||
|
|||||||
+31
-5
@@ -1768,9 +1768,11 @@ template <> otError Interpreter::Process<Cmd("channel")>(Arg aArgs[])
|
|||||||
OutputLine("count: %lu", ToUlong(otChannelMonitorGetSampleCount(GetInstancePtr())));
|
OutputLine("count: %lu", ToUlong(otChannelMonitorGetSampleCount(GetInstancePtr())));
|
||||||
|
|
||||||
OutputLine("occupancies:");
|
OutputLine("occupancies:");
|
||||||
|
|
||||||
for (uint8_t channel = 0; channel < channelNum; channel++)
|
for (uint8_t channel = 0; channel < channelNum; channel++)
|
||||||
{
|
{
|
||||||
uint32_t occupancy = 0;
|
uint16_t occupancy;
|
||||||
|
PercentageStringBuffer stringBuffer;
|
||||||
|
|
||||||
if (!((1UL << channel) & channelMask))
|
if (!((1UL << channel) & channelMask))
|
||||||
{
|
{
|
||||||
@@ -1779,11 +1781,10 @@ template <> otError Interpreter::Process<Cmd("channel")>(Arg aArgs[])
|
|||||||
|
|
||||||
occupancy = otChannelMonitorGetChannelOccupancy(GetInstancePtr(), channel);
|
occupancy = otChannelMonitorGetChannelOccupancy(GetInstancePtr(), channel);
|
||||||
|
|
||||||
OutputFormat("ch %u (0x%04lx) ", channel, ToUlong(occupancy));
|
OutputLine("ch %u (0x%04x) %6s%% busy", channel, occupancy,
|
||||||
occupancy = (occupancy * 10000) / 0xffff;
|
PercentageToString(occupancy, stringBuffer));
|
||||||
OutputLine("%2u.%02u%% busy", static_cast<uint16_t>(occupancy / 100),
|
|
||||||
static_cast<uint16_t>(occupancy % 100));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OutputNewLine();
|
OutputNewLine();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4987,6 +4988,31 @@ template <> otError Interpreter::Process<Cmd("neighbor")>(Arg aArgs[])
|
|||||||
|
|
||||||
OutputNewLine();
|
OutputNewLine();
|
||||||
}
|
}
|
||||||
|
else if (aArgs[0] == "linkquality")
|
||||||
|
{
|
||||||
|
static const char *const kLinkQualityTableTitles[] = {
|
||||||
|
"RLOC16", "Extended MAC", "Frame Error", "Msg Error", "Avg RSS", "Last RSS", "Age",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint8_t kLinkQualityTableColumnWidths[] = {
|
||||||
|
8, 18, 13, 11, 9, 10, 7,
|
||||||
|
};
|
||||||
|
|
||||||
|
OutputTableHeader(kLinkQualityTableTitles, kLinkQualityTableColumnWidths);
|
||||||
|
|
||||||
|
while (otThreadGetNextNeighborInfo(GetInstancePtr(), &iterator, &neighborInfo) == OT_ERROR_NONE)
|
||||||
|
{
|
||||||
|
PercentageStringBuffer stringBuffer;
|
||||||
|
|
||||||
|
OutputFormat("| 0x%04x | ", neighborInfo.mRloc16);
|
||||||
|
OutputExtAddress(neighborInfo.mExtAddress);
|
||||||
|
OutputFormat(" | %9s %% ", PercentageToString(neighborInfo.mFrameErrorRate, stringBuffer));
|
||||||
|
OutputFormat("| %7s %% ", PercentageToString(neighborInfo.mMessageErrorRate, stringBuffer));
|
||||||
|
OutputFormat("| %7d ", neighborInfo.mAverageRssi);
|
||||||
|
OutputFormat("| %8d ", neighborInfo.mLastRssi);
|
||||||
|
OutputLine("| %5lu |", ToUlong(neighborInfo.mAge));
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
error = OT_ERROR_INVALID_ARGS;
|
error = OT_ERROR_INVALID_ARGS;
|
||||||
|
|||||||
@@ -261,6 +261,18 @@ void Output::OutputDnsTxtData(const uint8_t *aTxtData, uint16_t aTxtDataLength)
|
|||||||
|
|
||||||
OutputFormat("]");
|
OutputFormat("]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *Output::PercentageToString(uint16_t aValue, PercentageStringBuffer &aBuffer)
|
||||||
|
{
|
||||||
|
uint32_t scaledValue = aValue;
|
||||||
|
StringWriter writer(aBuffer.mChars, sizeof(aBuffer.mChars));
|
||||||
|
|
||||||
|
scaledValue = (scaledValue * 10000) / 0xffff;
|
||||||
|
writer.Append("%u.%02u", static_cast<uint16_t>(scaledValue / 100), static_cast<uint16_t>(scaledValue % 100));
|
||||||
|
|
||||||
|
return aBuffer.mChars;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // OPENTHREAD_FTD || OPENTHREAD_MTD
|
#endif // OPENTHREAD_FTD || OPENTHREAD_MTD
|
||||||
|
|
||||||
void Output::OutputFormatV(const char *aFormat, va_list aArguments) { mImplementer.OutputV(aFormat, aArguments); }
|
void Output::OutputFormatV(const char *aFormat, va_list aArguments) { mImplementer.OutputV(aFormat, aArguments); }
|
||||||
|
|||||||
+27
-1
@@ -204,7 +204,7 @@ public:
|
|||||||
otInstance *GetInstancePtr(void) { return mInstance; }
|
otInstance *GetInstancePtr(void) { return mInstance; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This structure represents a buffer which is sued when converting a `uint64` value to string in decimal format.
|
* This structure represents a buffer which is used when converting a `uint64` value to string in decimal format.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
struct Uint64StringBuffer
|
struct Uint64StringBuffer
|
||||||
@@ -440,6 +440,32 @@ public:
|
|||||||
*/
|
*/
|
||||||
void OutputDnsTxtData(const uint8_t *aTxtData, uint16_t aTxtDataLength);
|
void OutputDnsTxtData(const uint8_t *aTxtData, uint16_t aTxtDataLength);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This structure represents a buffer which is used when converting an encoded rate value to percentage string.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
struct PercentageStringBuffer
|
||||||
|
{
|
||||||
|
static constexpr uint16_t kSize = 7; ///< Size of a buffer
|
||||||
|
|
||||||
|
char mChars[kSize]; ///< Char array (do not access the array directly).
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This static method converts an encoded value to a percentage representation.
|
||||||
|
*
|
||||||
|
* The encoded @p aValue is assumed to be linearly scaled such that `0` maps to 0% and `0xffff` maps to 100%.
|
||||||
|
*
|
||||||
|
* The resulting string provides two decimal accuracy, e.g., "100.00", "0.00", "75.37".
|
||||||
|
*
|
||||||
|
* @param[in] aValue The encoded percentage 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 aValue.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static const char *PercentageToString(uint16_t aValue, PercentageStringBuffer &aBuffer);
|
||||||
|
|
||||||
#endif // OPENTHREAD_FTD || OPENTHREAD_MTD
|
#endif // OPENTHREAD_FTD || OPENTHREAD_MTD
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user