diff --git a/examples/drivers/windows/include/otLwfIoctl.h b/examples/drivers/windows/include/otLwfIoctl.h index 5d414c728..d21ec4f00 100644 --- a/examples/drivers/windows/include/otLwfIoctl.h +++ b/examples/drivers/windows/include/otLwfIoctl.h @@ -717,8 +717,16 @@ typedef struct otCommissionConfig OTLWF_CTL_CODE(200, METHOD_BUFFERED, FILE_WRITE_DATA) // GUID - InterfaceGuid +#define IOCTL_OTLWF_OT_NEXT_ROUTE \ + OTLWF_CTL_CODE(201, METHOD_BUFFERED, FILE_READ_DATA) + // GUID - InterfaceGuid + // BOOLEAN - aLocal (input) + // uint8_t - aIterator (input) + // uint8_t - aNewIterator (output) + // otExternalRouteConfig - aConfig (output) + // OpenThread function IOCTL codes #define MIN_OTLWF_IOCTL_FUNC_CODE 100 -#define MAX_OTLWF_IOCTL_FUNC_CODE 200 +#define MAX_OTLWF_IOCTL_FUNC_CODE 201 #endif //__OTLWFIOCTL_H__ diff --git a/examples/drivers/windows/otApi/otApi.cpp b/examples/drivers/windows/otApi/otApi.cpp index 87774d8d1..7f3335d1c 100644 --- a/examples/drivers/windows/otApi/otApi.cpp +++ b/examples/drivers/windows/otApi/otApi.cpp @@ -1840,6 +1840,42 @@ otBorderRouterGetNextOnMeshPrefix( return aError; } +OTAPI +otError +OTCALL +otBorderRouterGetNextRoute( + _In_ otInstance *aInstance, + _Inout_ otNetworkDataIterator *aIterator, + _Out_ otExternalRouteConfig *aConfig + ) +{ + if (aInstance == nullptr || aConfig == nullptr) return OT_ERROR_INVALID_ARGS; + + BOOLEAN aLocal = TRUE; + PackedBuffer3 InBuffer(aInstance->InterfaceGuid, aLocal, *aIterator); + BYTE OutBuffer[sizeof(uint8_t) + sizeof(otExternalRouteConfig)]; + + otError aError = + DwordToThreadError( + SendIOCTL( + aInstance->ApiHandle, + IOCTL_OTLWF_OT_NEXT_ROUTE, + &InBuffer, sizeof(InBuffer), + OutBuffer, sizeof(OutBuffer))); + + if (aError == OT_ERROR_NONE) + { + memcpy(aIterator, OutBuffer, sizeof(uint8_t)); + memcpy(aConfig, OutBuffer + sizeof(uint8_t), sizeof(otExternalRouteConfig)); + } + else + { + ZeroMemory(aConfig, sizeof(otExternalRouteConfig)); + } + + return aError; +} + OTAPI otPanId OTCALL diff --git a/examples/drivers/windows/otLwf/iocontrol.c b/examples/drivers/windows/otLwf/iocontrol.c index 6b0d4aebf..721061a2c 100644 --- a/examples/drivers/windows/otLwf/iocontrol.c +++ b/examples/drivers/windows/otLwf/iocontrol.c @@ -145,6 +145,7 @@ OTLWF_IOCTL_HANDLER IoCtls[] = { "IOCTL_OTLWF_OT_REMOVE_MAC_FIXED_RSS", REF_IOCTL_FUNC_WITH_TUN(otRemoveMacFixedRss) }, { "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) }, }; // intentionally -1 in the end due to that IOCTL_OTLWF_OT_ASSIGN_LINK_QUALITY (#161) is removed now. @@ -4868,6 +4869,58 @@ otLwfIoCtl_otNextOnMeshPrefix( return status; } +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +otLwfIoCtl_otNextRoute( + _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; + + if (InBufferLength >= sizeof(BOOLEAN) + sizeof(uint32_t) && + *OutBufferLength >= sizeof(uint32_t) + sizeof(otExternalRouteConfig)) + { + BOOLEAN aLocal = *(BOOLEAN*)InBuffer; + uint32_t aIterator = *(uint32_t*)(InBuffer + sizeof(BOOLEAN)); + otExternalRouteConfig* aConfig = (otExternalRouteConfig*)((PUCHAR)OutBuffer + sizeof(uint32_t)); + if (aLocal) + { + status = ThreadErrorToNtstatus( + otBorderRouterGetNextRoute( + pFilter->otCtx, + &aIterator, + aConfig) + ); + } + else + { + status = ThreadErrorToNtstatus( + otNetDataGetNextRoute( + pFilter->otCtx, + &aIterator, + aConfig) + ); + } + *OutBufferLength = sizeof(uint8_t) + sizeof(otExternalRouteConfig); + if (status == STATUS_SUCCESS) + { + *(uint32_t*)OutBuffer = aIterator; + } + } + else + { + *OutBufferLength = 0; + } + + return status; +} + _IRQL_requires_max_(PASSIVE_LEVEL) NTSTATUS otLwfIoCtl_otPollPeriod( diff --git a/examples/drivers/windows/otLwf/iocontrol.h b/examples/drivers/windows/otLwf/iocontrol.h index b3f39e4d1..fd1973021 100644 --- a/examples/drivers/windows/otLwf/iocontrol.h +++ b/examples/drivers/windows/otLwf/iocontrol.h @@ -231,5 +231,6 @@ DECL_IOCTL_FUNC_WITH_TUN(otAddMacFixedRss); DECL_IOCTL_FUNC_WITH_TUN(otRemoveMacFixedRss); DECL_IOCTL_FUNC(otNextMacFixedRss); DECL_IOCTL_FUNC_WITH_TUN(otClearMacFixedRss); +DECL_IOCTL_FUNC(otNextRoute); #endif // _IOCONTROL_H diff --git a/include/openthread/border_router.h b/include/openthread/border_router.h index 87e335377..f4d78ff9f 100644 --- a/include/openthread/border_router.h +++ b/include/openthread/border_router.h @@ -151,9 +151,9 @@ OTAPI otError OTCALL otBorderRouterRemoveRoute(otInstance *aInstance, const otIp * @retval OT_ERROR_NOT_FOUND No subsequent external route entry exists in the Thread Network Data. * */ -otError otBorderRouterGetNextRoute(otInstance * aInstance, - otNetworkDataIterator *aIterator, - otExternalRouteConfig *aConfig); +OTAPI otError OTCALL otBorderRouterGetNextRoute(otInstance * aInstance, + otNetworkDataIterator *aIterator, + otExternalRouteConfig *aConfig); /** * Immediately register the local network data with the Leader. diff --git a/src/cli/README.md b/src/cli/README.md index 4924bcbb0..4ab8f90aa 100644 --- a/src/cli/README.md +++ b/src/cli/README.md @@ -1289,6 +1289,16 @@ Set the customized data poll period for sleepy end device (seconds). Only for ce Done ``` +### prefix + +Get the prefix list in the local Network Data. + +```bash +> prefix +2001:dead:beef:cafe::/64 paros med +Done +``` + ### prefix add \ [pvdcsr] [prf] Add a valid prefix to the Network Data. @@ -1369,9 +1379,19 @@ Get the Thread RLOC16 value. Done ``` +### route + +Get the external route list in the local Network Data. + +```bash +> route +2001:dead:beef:cafe::/64 s med +Done +``` + ### route add \ [s] [prf] -Add a valid prefix to the Network Data. +Add a valid external route to the Network Data. * s: Stable flag * prf: Default Router Preference, which may be: 'high', 'med', or 'low'. @@ -1383,7 +1403,7 @@ Done ### route remove \ -Invalidate a prefix in the Network Data. +Invalidate a external route in the Network Data. ```bash > route remove 2001:dead:beef:cafe::/64 diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp index 7226f39bf..7e53ec645 100644 --- a/src/cli/cli.cpp +++ b/src/cli/cli.cpp @@ -2246,13 +2246,51 @@ exit: return error; } +otError Interpreter::ProcessRouteList(void) +{ + otNetworkDataIterator iterator = OT_NETWORK_DATA_ITERATOR_INIT; + otExternalRouteConfig config; + + while (otBorderRouterGetNextRoute(mInstance, &iterator, &config) == OT_ERROR_NONE) + { + mServer->OutputFormat("%x:%x:%x:%x::/%d ", HostSwap16(config.mPrefix.mPrefix.mFields.m16[0]), + HostSwap16(config.mPrefix.mPrefix.mFields.m16[1]), + HostSwap16(config.mPrefix.mPrefix.mFields.m16[2]), + HostSwap16(config.mPrefix.mPrefix.mFields.m16[3]), config.mPrefix.mLength); + + if (config.mStable) + { + mServer->OutputFormat("s"); + } + + switch (config.mPreference) + { + case OT_ROUTE_PREFERENCE_LOW: + mServer->OutputFormat(" low\r\n"); + break; + + case OT_ROUTE_PREFERENCE_MED: + mServer->OutputFormat(" med\r\n"); + break; + + case OT_ROUTE_PREFERENCE_HIGH: + mServer->OutputFormat(" high\r\n"); + break; + } + } + + return OT_ERROR_NONE; +} + void Interpreter::ProcessRoute(int argc, char *argv[]) { otError error = OT_ERROR_NONE; - VerifyOrExit(argc > 0, error = OT_ERROR_PARSE); - - if (strcmp(argv[0], "add") == 0) + if (argc == 0) + { + SuccessOrExit(error = ProcessRouteList()); + } + else if (strcmp(argv[0], "add") == 0) { SuccessOrExit(error = ProcessRouteAdd(argc - 1, argv + 1)); } diff --git a/src/cli/cli.hpp b/src/cli/cli.hpp index 38f5e980b..347007deb 100644 --- a/src/cli/cli.hpp +++ b/src/cli/cli.hpp @@ -289,6 +289,7 @@ private: void ProcessRoute(int argc, char *argv[]); otError ProcessRouteAdd(int argc, char *argv[]); otError ProcessRouteRemove(int argc, char *argv[]); + otError ProcessRouteList(void); #endif #if OPENTHREAD_FTD void ProcessRouter(int argc, char *argv[]);