From 8c13df5a51f4b0428d73f0bc57a01506c178e421 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Duda?= Date: Tue, 19 Feb 2019 20:37:45 +0100 Subject: [PATCH] [cli] add command to retrieve mle counters (#3605) --- examples/drivers/windows/include/otLwfIoctl.h | 7 +- examples/drivers/windows/otApi/otApi.cpp | 21 ++++ examples/drivers/windows/otLwf/iocontrol.c | 32 ++++++ examples/drivers/windows/otLwf/iocontrol.h | 1 + include/openthread/thread.h | 2 +- src/cli/cli.cpp | 101 ++++++++++++------ 6 files changed, 127 insertions(+), 37 deletions(-) diff --git a/examples/drivers/windows/include/otLwfIoctl.h b/examples/drivers/windows/include/otLwfIoctl.h index ab6864109..de00cae2c 100644 --- a/examples/drivers/windows/include/otLwfIoctl.h +++ b/examples/drivers/windows/include/otLwfIoctl.h @@ -728,8 +728,13 @@ typedef struct otCommissionConfig // GUID - InterfaceGuid // uint8_t - aMaxRouterId +#define IOCTL_OTLWF_OT_MLE_COUNTERS \ + OTLWF_CTL_CODE(203, METHOD_BUFFERED, FILE_READ_DATA) + // GUID - InterfaceGuid + // otMleCounters - aCounters + // OpenThread function IOCTL codes #define MIN_OTLWF_IOCTL_FUNC_CODE 100 -#define MAX_OTLWF_IOCTL_FUNC_CODE 202 +#define MAX_OTLWF_IOCTL_FUNC_CODE 203 #endif //__OTLWFIOCTL_H__ diff --git a/examples/drivers/windows/otApi/otApi.cpp b/examples/drivers/windows/otApi/otApi.cpp index 788a4131c..7af9dbd04 100644 --- a/examples/drivers/windows/otApi/otApi.cpp +++ b/examples/drivers/windows/otApi/otApi.cpp @@ -3977,3 +3977,24 @@ otThreadSetParentPriority( if (aInstance == nullptr) return OT_ERROR_INVALID_ARGS; return DwordToThreadError(SetIOCTL(aInstance, IOCTL_OTLWF_OT_PARENT_PRIORITY, aParentPriority)); } + +OTAPI +const otMleCounters* +OTCALL +otThreadGetMleCounters( + _In_ otInstance *aInstance + ) +{ + if (aInstance == nullptr) return nullptr; + + otMleCounters* aCounters = (otMleCounters*)malloc(sizeof(otMleCounters)); + if (aCounters) + { + if (ERROR_SUCCESS != QueryIOCTL(aInstance, IOCTL_OTLWF_OT_MLE_COUNTERS, aCounters)) + { + free(aCounters); + aCounters = nullptr; + } + } + return aCounters; +} diff --git a/examples/drivers/windows/otLwf/iocontrol.c b/examples/drivers/windows/otLwf/iocontrol.c index 7e4a8bba9..dca54f655 100644 --- a/examples/drivers/windows/otLwf/iocontrol.c +++ b/examples/drivers/windows/otLwf/iocontrol.c @@ -147,6 +147,7 @@ OTLWF_IOCTL_HANDLER IoCtls[] = { "IOCTL_OTLWF_OT_NEXT_MAC_FIXED_RSS", REF_IOCTL_FUNC(otNextMacFixedRss) }, { "IOCTL_OTLWF_OT_CLEAR_MAC_FIXED_RSS", REF_IOCTL_FUNC_WITH_TUN(otClearMacFixedRss) }, { "IOCTL_OTLWF_OT_NEXT_ROUTE", REF_IOCTL_FUNC(otNextRoute) }, + { "IOCTL_OTLWF_OT_MLE_COUNTERS", REF_IOCTL_FUNC(otMleCounters) }, }; // intentionally -1 in the end due to that IOCTL_OTLWF_OT_ASSIGN_LINK_QUALITY (#161) is removed now. @@ -6590,3 +6591,34 @@ otLwfIoCtl_otNextMacFixedRss( return status; } + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +otLwfIoCtl_otMleCounters( + _In_ PMS_FILTER pFilter, + _In_reads_bytes_(InBufferLength) + PUCHAR InBuffer, + _In_ ULONG InBufferLength, + _Out_writes_bytes_(*OutBufferLength) + PVOID OutBuffer, + _Inout_ PULONG OutBufferLength + ) +{ + NTSTATUS status = STATUS_INVALID_PARAMETER; + + UNREFERENCED_PARAMETER(InBuffer); + UNREFERENCED_PARAMETER(InBufferLength); + + if (*OutBufferLength >= sizeof(otMleCounters)) + { + memcpy_s(OutBuffer, *OutBufferLength, otThreadGetMleCounters(pFilter->otCtx), sizeof(otMleCounters)); + *OutBufferLength = sizeof(otMleCounters); + status = STATUS_SUCCESS; + } + else + { + *OutBufferLength = 0; + } + + return status; +} diff --git a/examples/drivers/windows/otLwf/iocontrol.h b/examples/drivers/windows/otLwf/iocontrol.h index 12c5a5feb..aa34c4eab 100644 --- a/examples/drivers/windows/otLwf/iocontrol.h +++ b/examples/drivers/windows/otLwf/iocontrol.h @@ -233,5 +233,6 @@ DECL_IOCTL_FUNC_WITH_TUN(otRemoveMacFixedRss); DECL_IOCTL_FUNC(otNextMacFixedRss); DECL_IOCTL_FUNC_WITH_TUN(otClearMacFixedRss); DECL_IOCTL_FUNC(otNextRoute); +DECL_IOCTL_FUNC(otMleCounters); #endif // _IOCONTROL_H diff --git a/include/openthread/thread.h b/include/openthread/thread.h index c9dd15299..c78a8886f 100644 --- a/include/openthread/thread.h +++ b/include/openthread/thread.h @@ -733,7 +733,7 @@ OTAPI const otIpCounters *OTCALL otThreadGetIp6Counters(otInstance *aInstance); * @returns A pointer to the Thread MLE counters. * */ -const otMleCounters *otThreadGetMleCounters(otInstance *aInstance); +OTAPI const otMleCounters *OTCALL otThreadGetMleCounters(otInstance *aInstance); /** * Reset the Thread MLE counters. diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp index b0fab19f2..9c165e014 100644 --- a/src/cli/cli.cpp +++ b/src/cli/cli.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #if OPENTHREAD_CONFIG_ENABLE_TIME_SYNC #include #endif @@ -126,7 +127,7 @@ const struct Command Interpreter::sCommands[] = { #if OPENTHREAD_FTD {"contextreusedelay", &Interpreter::ProcessContextIdReuseDelay}, #endif - {"counter", &Interpreter::ProcessCounters}, + {"counters", &Interpreter::ProcessCounters}, {"dataset", &Interpreter::ProcessDataset}, #if OPENTHREAD_FTD {"delaytimermin", &Interpreter::ProcessDelayTimerMin}, @@ -279,6 +280,7 @@ public: }; typedef otPtr otMacCountersPtr; +typedef otPtr otMleCountersPtr; typedef otPtr otNetifAddressPtr; typedef otPtr otBufferPtr; typedef otPtr otStringPtr; @@ -808,49 +810,78 @@ exit: void Interpreter::ProcessCounters(int argc, char *argv[]) { + otError error = OT_ERROR_NONE; + if (argc == 0) { mServer->OutputFormat("mac\r\n"); - mServer->OutputFormat("Done\r\n"); + mServer->OutputFormat("mle\r\n"); } - else + else if (argc == 1) { if (strcmp(argv[0], "mac") == 0) { - otMacCountersPtr counters(otLinkGetCounters(mInstance)); - mServer->OutputFormat("TxTotal: %d\r\n", counters->mTxTotal); - mServer->OutputFormat(" TxUnicast: %d\r\n", counters->mTxUnicast); - mServer->OutputFormat(" TxBroadcast: %d\r\n", counters->mTxBroadcast); - mServer->OutputFormat(" TxAckRequested: %d\r\n", counters->mTxAckRequested); - mServer->OutputFormat(" TxAcked: %d\r\n", counters->mTxAcked); - mServer->OutputFormat(" TxNoAckRequested: %d\r\n", counters->mTxNoAckRequested); - mServer->OutputFormat(" TxData: %d\r\n", counters->mTxData); - mServer->OutputFormat(" TxDataPoll: %d\r\n", counters->mTxDataPoll); - mServer->OutputFormat(" TxBeacon: %d\r\n", counters->mTxBeacon); - mServer->OutputFormat(" TxBeaconRequest: %d\r\n", counters->mTxBeaconRequest); - mServer->OutputFormat(" TxOther: %d\r\n", counters->mTxOther); - mServer->OutputFormat(" TxRetry: %d\r\n", counters->mTxRetry); - mServer->OutputFormat(" TxErrCca: %d\r\n", counters->mTxErrCca); - mServer->OutputFormat(" TxErrBusyChannel: %d\r\n", counters->mTxErrBusyChannel); - mServer->OutputFormat("RxTotal: %d\r\n", counters->mRxTotal); - mServer->OutputFormat(" RxUnicast: %d\r\n", counters->mRxUnicast); - mServer->OutputFormat(" RxBroadcast: %d\r\n", counters->mRxBroadcast); - mServer->OutputFormat(" RxData: %d\r\n", counters->mRxData); - mServer->OutputFormat(" RxDataPoll: %d\r\n", counters->mRxDataPoll); - mServer->OutputFormat(" RxBeacon: %d\r\n", counters->mRxBeacon); - mServer->OutputFormat(" RxBeaconRequest: %d\r\n", counters->mRxBeaconRequest); - mServer->OutputFormat(" RxOther: %d\r\n", counters->mRxOther); - mServer->OutputFormat(" RxAddressFiltered: %d\r\n", counters->mRxAddressFiltered); - mServer->OutputFormat(" RxDestAddrFiltered: %d\r\n", counters->mRxDestAddrFiltered); - mServer->OutputFormat(" RxDuplicated: %d\r\n", counters->mRxDuplicated); - mServer->OutputFormat(" RxErrNoFrame: %d\r\n", counters->mRxErrNoFrame); - mServer->OutputFormat(" RxErrNoUnknownNeighbor: %d\r\n", counters->mRxErrUnknownNeighbor); - mServer->OutputFormat(" RxErrInvalidSrcAddr: %d\r\n", counters->mRxErrInvalidSrcAddr); - mServer->OutputFormat(" RxErrSec: %d\r\n", counters->mRxErrSec); - mServer->OutputFormat(" RxErrFcs: %d\r\n", counters->mRxErrFcs); - mServer->OutputFormat(" RxErrOther: %d\r\n", counters->mRxErrOther); + otMacCountersPtr macCounters(otLinkGetCounters(mInstance)); + + mServer->OutputFormat("TxTotal: %d\r\n", macCounters->mTxTotal); + mServer->OutputFormat(" TxUnicast: %d\r\n", macCounters->mTxUnicast); + mServer->OutputFormat(" TxBroadcast: %d\r\n", macCounters->mTxBroadcast); + mServer->OutputFormat(" TxAckRequested: %d\r\n", macCounters->mTxAckRequested); + mServer->OutputFormat(" TxAcked: %d\r\n", macCounters->mTxAcked); + mServer->OutputFormat(" TxNoAckRequested: %d\r\n", macCounters->mTxNoAckRequested); + mServer->OutputFormat(" TxData: %d\r\n", macCounters->mTxData); + mServer->OutputFormat(" TxDataPoll: %d\r\n", macCounters->mTxDataPoll); + mServer->OutputFormat(" TxBeacon: %d\r\n", macCounters->mTxBeacon); + mServer->OutputFormat(" TxBeaconRequest: %d\r\n", macCounters->mTxBeaconRequest); + mServer->OutputFormat(" TxOther: %d\r\n", macCounters->mTxOther); + mServer->OutputFormat(" TxRetry: %d\r\n", macCounters->mTxRetry); + mServer->OutputFormat(" TxErrCca: %d\r\n", macCounters->mTxErrCca); + mServer->OutputFormat(" TxErrBusyChannel: %d\r\n", macCounters->mTxErrBusyChannel); + mServer->OutputFormat("RxTotal: %d\r\n", macCounters->mRxTotal); + mServer->OutputFormat(" RxUnicast: %d\r\n", macCounters->mRxUnicast); + mServer->OutputFormat(" RxBroadcast: %d\r\n", macCounters->mRxBroadcast); + mServer->OutputFormat(" RxData: %d\r\n", macCounters->mRxData); + mServer->OutputFormat(" RxDataPoll: %d\r\n", macCounters->mRxDataPoll); + mServer->OutputFormat(" RxBeacon: %d\r\n", macCounters->mRxBeacon); + mServer->OutputFormat(" RxBeaconRequest: %d\r\n", macCounters->mRxBeaconRequest); + mServer->OutputFormat(" RxOther: %d\r\n", macCounters->mRxOther); + mServer->OutputFormat(" RxAddressFiltered: %d\r\n", macCounters->mRxAddressFiltered); + mServer->OutputFormat(" RxDestAddrFiltered: %d\r\n", macCounters->mRxDestAddrFiltered); + mServer->OutputFormat(" RxDuplicated: %d\r\n", macCounters->mRxDuplicated); + mServer->OutputFormat(" RxErrNoFrame: %d\r\n", macCounters->mRxErrNoFrame); + mServer->OutputFormat(" RxErrNoUnknownNeighbor: %d\r\n", macCounters->mRxErrUnknownNeighbor); + mServer->OutputFormat(" RxErrInvalidSrcAddr: %d\r\n", macCounters->mRxErrInvalidSrcAddr); + mServer->OutputFormat(" RxErrSec: %d\r\n", macCounters->mRxErrSec); + mServer->OutputFormat(" RxErrFcs: %d\r\n", macCounters->mRxErrFcs); + mServer->OutputFormat(" RxErrOther: %d\r\n", macCounters->mRxErrOther); + } + else if (strcmp(argv[0], "mle") == 0) + { + otMleCountersPtr mleCounters(otThreadGetMleCounters(mInstance)); + + mServer->OutputFormat("Role Disabled: %d\r\n", mleCounters->mDisabledRole); + mServer->OutputFormat("Role Detached: %d\r\n", mleCounters->mDetachedRole); + mServer->OutputFormat("Role Child: %d\r\n", mleCounters->mChildRole); + mServer->OutputFormat("Role Router: %d\r\n", mleCounters->mRouterRole); + mServer->OutputFormat("Role Leader: %d\r\n", mleCounters->mLeaderRole); + mServer->OutputFormat("Attach Attempts: %d\r\n", mleCounters->mAttachAttempts); + mServer->OutputFormat("Partition Id Changes: %d\r\n", mleCounters->mPartitionIdChanges); + mServer->OutputFormat("Better Partition Attach Attempts: %d\r\n", + mleCounters->mBetterPartitionAttachAttempts); + mServer->OutputFormat("Parent Changes: %d\r\n", mleCounters->mParentChanges); + } + else + { + ExitNow(error = OT_ERROR_INVALID_ARGS); } } + else + { + ExitNow(error = OT_ERROR_INVALID_ARGS); + } + +exit: + AppendResult(error); } #if OPENTHREAD_FTD