diff --git a/CMakeLists.txt b/CMakeLists.txt index 78ac7d4d..d43393fe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -80,7 +80,7 @@ if (NOF_USE_VCPKG) find_package(nlohmann_json CONFIG ${VERSION_NLOHMANN_JSON} REQUIRED) find_package(magic_enum CONFIG ${VERSION_MAGIC_ENUM} REQUIRED) find_package(CLI11 CONFIG ${VERSION_CLI11} REQUIRED) - find_package(plog CONFIG ${VERSION_PLOG} REQUIRED) + find_package(plog CONFIG REQUIRED) else() set(JSON_ImplicitConversions OFF) FetchContent_Declare(json URL https://github.com/nlohmann/json/releases/download/v${VERSION_NLOHMANN_JSON}/json.tar.xz) diff --git a/lib/uwb/include/uwb/protocols/fira/FiraDevice.hxx b/lib/uwb/include/uwb/protocols/fira/FiraDevice.hxx index 86b30618..4099f131 100644 --- a/lib/uwb/include/uwb/protocols/fira/FiraDevice.hxx +++ b/lib/uwb/include/uwb/protocols/fira/FiraDevice.hxx @@ -305,6 +305,12 @@ enum class UwbSessionType { RangingSession, TestMode, }; +enum class UwbSessionState { + Initialized, + Deinitialized, + Active, + Idle, +}; enum class UwbSessionReasonCode { StateChangeWithSessionManagementCommands, MaxRangignRoundRetryCountReached, @@ -339,7 +345,7 @@ struct UwbDeviceInfoVendor virtual ~UwbDeviceInfoVendor() = default; }; -struct UwbDeviceInfo +struct UwbDeviceInfoInformation { UwbVersion VersionUwb; UwbVersion VersionUci; @@ -363,11 +369,6 @@ enum class UwbApplicationConfigurationParameterType { struct UwbApplicationConfigurationParameter {}; -struct UwbSessionState -{ - uint32_t Id; -}; - struct UwbStatusMulticastList { uint16_t ControleeMacAddress; // why is this uint16_t? TODO: replace with uwb::UwbMacAddress diff --git a/windows/devices/uwb/CMakeLists.txt b/windows/devices/uwb/CMakeLists.txt index c10a8436..64084280 100644 --- a/windows/devices/uwb/CMakeLists.txt +++ b/windows/devices/uwb/CMakeLists.txt @@ -7,9 +7,11 @@ target_sources(uwbcxadapter PRIVATE ${CMAKE_CURRENT_LIST_DIR}/UwbCxAdapter.cxx ${CMAKE_CURRENT_LIST_DIR}/UwbAppConfiguration.cxx + ${CMAKE_CURRENT_LIST_DIR}/UwbCxAdapterDdiLrp.cxx PUBLIC - ${UWBCXADAPTER_DIR_PUBLIC_INCLUDE_PREFIX}/UwbCxAdapter.hxx ${UWBCXADAPTER_DIR_PUBLIC_INCLUDE_PREFIX}/UwbAppConfiguration.hxx + ${UWBCXADAPTER_DIR_PUBLIC_INCLUDE_PREFIX}/UwbCxAdapter.hxx + ${UWBCXADAPTER_DIR_PUBLIC_INCLUDE_PREFIX}/UwbCxAdapterDdiLrp.hxx ) target_include_directories(uwbcxadapter @@ -29,8 +31,9 @@ target_link_libraries(uwbcxadapter ) list(APPEND UWBCXADAPTER_PUBLIC_HEADERS - ${UWBCXADAPTER_DIR_PUBLIC_INCLUDE_PREFIX}/UwbCxAdapter.hxx ${UWBCXADAPTER_DIR_PUBLIC_INCLUDE_PREFIX}/UwbAppConfiguration.hxx + ${UWBCXADAPTER_DIR_PUBLIC_INCLUDE_PREFIX}/UwbCxAdapter.hxx + ${UWBCXADAPTER_DIR_PUBLIC_INCLUDE_PREFIX}/UwbCxAdapterDdiLrp.hxx ) set_target_properties(uwbcxadapter PROPERTIES FOLDER windows/devices/uwb) diff --git a/windows/devices/uwb/UwbCxAdapterDdiLrp.cxx b/windows/devices/uwb/UwbCxAdapterDdiLrp.cxx new file mode 100644 index 00000000..6924ff90 --- /dev/null +++ b/windows/devices/uwb/UwbCxAdapterDdiLrp.cxx @@ -0,0 +1,106 @@ + +#include +#include +#include +#include +#include +#include + +#include + +using namespace ::uwb::protocol::fira; + +UWB_STATUS +windows::devices::uwb::ddi::lrp::From(const UwbStatus& uwbStatus) +{ + static const std::unordered_map StatusMapGeneric{ + { UwbStatusGeneric::Ok, UWB_STATUS_OK }, + { UwbStatusGeneric::Rejected, UWB_STATUS_REJECTED }, + { UwbStatusGeneric::Failed, UWB_STATUS_FAILED }, + { UwbStatusGeneric::SyntaxError, UWB_STATUS_SYNTAX_ERROR }, + { UwbStatusGeneric::InvalidParameter, UWB_STATUS_INVALID_PARAM }, + { UwbStatusGeneric::InvalidRange, UWB_STATUS_INVALID_RANGE }, + { UwbStatusGeneric::InvalidMessageSize, UWB_STATUS_INVALID_MESSAGE_SIZE }, + { UwbStatusGeneric::UnknownGid, UWB_STATUS_UNKNOWN_GID }, + { UwbStatusGeneric::UnknownOid, UWB_STATUS_UNKNOWN_OID }, + { UwbStatusGeneric::ReadOnly, UWB_STATUS_READ_ONLY }, + { UwbStatusGeneric::CommandRetry, UWB_STATUS_COMMAND_RETRY }, + }; + static const std::unordered_map StatusMapSession{ + { UwbStatusSession::NotExist, UWB_STATUS_ERROR_SESSION_NOT_EXIST }, + { UwbStatusSession::Duplicate, UWB_STATUS_ERROR_SESSION_DUPLICATE }, + { UwbStatusSession::Active, UWB_STATUS_ERROR_SESSION_ACTIVE }, + { UwbStatusSession::MaxSessionsExceeded, UWB_STATUS_ERROR_MAX_SESSIONS_EXCEEDED }, + { UwbStatusSession::NotConfigured, UWB_STATUS_ERROR_SESSION_NOT_CONFIGURED }, + { UwbStatusSession::ActiveSessionsOngoing, UWB_STATUS_ERROR_ACTIVE_SESSIONS_ONGOING }, + { UwbStatusSession::MulticastListFull, UWB_STATUS_ERROR_MULTICAST_LIST_FULL }, + { UwbStatusSession::AddressNotFound, UWB_STATUS_ERROR_ADDRESS_NOT_FOUND }, + { UwbStatusSession::AddressAlreadyPresent, UWB_STATUS_ERROR_ADDRESS_ALREADY_PRESENT }, + }; + static const std::unordered_map StatusMapRanging{ + { UwbStatusRanging::TxFailed, UWB_STATUS_RANGING_TX_FAILED }, + { UwbStatusRanging::RxTimeout, UWB_STATUS_RANGING_RX_TIMEOUT }, + { UwbStatusRanging::RxPhyDecodingFailed, UWB_STATUS_RANGING_RX_PHY_DEC_FAILED }, + { UwbStatusRanging::RxPhyToaFailed, UWB_STATUS_RANGING_RX_PHY_TOA_FAILED }, + { UwbStatusRanging::RxPhyStsFailed, UWB_STATUS_RANGING_RX_PHY_STS_FAILED }, + { UwbStatusRanging::MacDecodingFailed, UWB_STATUS_RANGING_RX_MAC_DEC_FAILED }, + { UwbStatusRanging::RxMacIeDecodingFailed, UWB_STATUS_RANGING_RX_MAC_IE_DEC_FAILED }, + { UwbStatusRanging::RxMacIeMissing, UWB_STATUS_RANGING_RX_MAC_IE_MISSING }, + }; + + UWB_STATUS status = UWB_STATUS_FAILED; + + std::visit([&status](auto&& arg) { + using T = std::decay_t; + if constexpr (std::is_same_v) { + status = StatusMapGeneric.at(arg); + } else if constexpr (std::is_same_v) { + status = StatusMapSession.at(arg); + } else if constexpr (std::is_same_v) { + status = StatusMapRanging.at(arg); + } else { + throw std::runtime_error("unknown UwbStatus variant value encountered"); + } + }, + uwbStatus); + + return status; +} + +UWB_SESSION_STATE +windows::devices::uwb::ddi::lrp::From(const UwbSessionState uwbSessionState) +{ + switch (uwbSessionState) { + case UwbSessionState::Initialized: + return UWB_SESSION_STATE_INIT; + case UwbSessionState::Deinitialized: + return UWB_SESSION_STATE_DEINIT; + case UwbSessionState::Active: + return UWB_SESSION_STATE_ACTIVE; + case UwbSessionState::Idle: + return UWB_SESSION_STATE_IDLE; + } + + throw std::runtime_error("unknown enumeration value"); +} + +UWB_DEVICE_INFO +windows::devices::uwb::ddi::lrp::From(const UwbDeviceInfoInformation& uwbDeviceInfo) +{ + UWB_DEVICE_INFO deviceInfo{}; + deviceInfo.size = sizeof deviceInfo; + deviceInfo.status = From(uwbDeviceInfo.Status); + deviceInfo.vendorSpecificInfoLength = 0; + // TODO: fill in remaining fields + return deviceInfo; +} + +UWB_DEVICE_CAPABILITIES +windows::devices::uwb::ddi::lrp::From(const UwbDeviceCapabilities& /*uwbDeviceCapabilities*/) +{ + UWB_DEVICE_CAPABILITIES deviceCapabilities{}; + deviceCapabilities.size = sizeof deviceCapabilities; + deviceCapabilities.capabilityParamsCount = 0; + // TODO: implement this properly + return deviceCapabilities; +} diff --git a/windows/devices/uwb/UwbDevice.cxx b/windows/devices/uwb/UwbDevice.cxx index 140341be..2ddd1f22 100644 --- a/windows/devices/uwb/UwbDevice.cxx +++ b/windows/devices/uwb/UwbDevice.cxx @@ -3,8 +3,7 @@ #include #include -#include - +#include #include #include diff --git a/windows/devices/uwb/UwbSession.cxx b/windows/devices/uwb/UwbSession.cxx index 6afb094e..732823d4 100644 --- a/windows/devices/uwb/UwbSession.cxx +++ b/windows/devices/uwb/UwbSession.cxx @@ -1,5 +1,4 @@ -#include #include #include @@ -7,6 +6,7 @@ #include #include +#include #include using namespace windows::devices::uwb; diff --git a/windows/devices/uwb/include/windows/devices/uwb/UwbAppConfiguration.hxx b/windows/devices/uwb/include/windows/devices/uwb/UwbAppConfiguration.hxx index d7aa013a..c7f75a46 100644 --- a/windows/devices/uwb/include/windows/devices/uwb/UwbAppConfiguration.hxx +++ b/windows/devices/uwb/include/windows/devices/uwb/UwbAppConfiguration.hxx @@ -14,8 +14,7 @@ #include #include - -#include +#include namespace windows::devices::uwb { diff --git a/windows/devices/uwb/include/windows/devices/uwb/UwbCxAdapterDdiLrp.hxx b/windows/devices/uwb/include/windows/devices/uwb/UwbCxAdapterDdiLrp.hxx new file mode 100644 index 00000000..94bf1f5e --- /dev/null +++ b/windows/devices/uwb/include/windows/devices/uwb/UwbCxAdapterDdiLrp.hxx @@ -0,0 +1,59 @@ + +#ifndef UWB_CX_ADAPTER_DDI_LRP_HXX +#define UWB_CX_ADAPTER_DDI_LRP_HXX + +#include +#include + +/** + * @brief Define LRP DDI conversion functionality as free functions in a + * namespace. + * + * The namespace name is intended to be used explicitly in the + * function call, which can help identify the type of conversion being done. + * This allows usage such as: + * + * UwbStatus uwbStatus = GetStatus(); + * UWB_STATUS ddiStatus = uwb::ddi::lrp::From(uwbStatus); + */ +namespace windows::devices::uwb::ddi::lrp +{ +/** + * @brief Converts UwbStatus to UWB_STATUS. + * + * @param uwbStatus + * @return UWB_STATUS + */ +UWB_STATUS +From(const ::uwb::protocol::fira::UwbStatus &uwbStatus); + +/** + * @brief Converts UwbSessionState to UWB_SESSION_STATE. + * + * @param uwbSessionState + * @return UWB_SESSION_STATE + */ +UWB_SESSION_STATE +From(const ::uwb::protocol::fira::UwbSessionState uwbSessionState); + +/** + * @brief Converts UwbDeviceInfoInformation to UWB_DEVICE_INFO. + * + * @param uwbDeviceInfo + * @return UWB_DEVICE_INFO + */ +UWB_DEVICE_INFO +From(const ::uwb::protocol::fira::UwbDeviceInfoInformation &uwbDeviceInfo); + +/** + * @brief Converts UwbDeviceCapabilities to UWB_DEVICE_CAPABILITIES. + * + * @param uwbDeviceCapabilities + * @return UWB_DEVICE_CAPABILITIES + */ +UWB_DEVICE_CAPABILITIES +From(const ::uwb::protocol::fira::UwbDeviceCapabilities &uwbDeviceCapabilities); + +} // namespace windows::devices::uwb::ddi::lrp + +#endif // UWB_CX_ADAPTER_DDI_LRP_HXX diff --git a/windows/drivers/uwb/cx/CMakeLists.txt b/windows/drivers/uwb/cx/CMakeLists.txt index 98d1ef00..78d7c518 100644 --- a/windows/drivers/uwb/cx/CMakeLists.txt +++ b/windows/drivers/uwb/cx/CMakeLists.txt @@ -2,22 +2,22 @@ add_library(uwbcx-driver INTERFACE) set(UWBCXDRIVER_DIR_PUBLIC_INCLUDE ${CMAKE_CURRENT_LIST_DIR}/include) -set(UWBCXDRIVER_DIR_PUBLIC_INCLUDE_PREFIX ${UWBCXDRIVER_DIR_PUBLIC_INCLUDE}) +set(UWBCXDRIVER_DIR_PUBLIC_INCLUDE_PREFIX ${UWBCXDRIVER_DIR_PUBLIC_INCLUDE}/windows/devices/uwb) target_sources(uwbcx-driver INTERFACE + ${UWBCXDRIVER_DIR_PUBLIC_INCLUDE_PREFIX}/UwbCxDdiLrp.hxx ${UWBCXDRIVER_DIR_PUBLIC_INCLUDE_PREFIX}/UwbCxLrpDevice.h - ${UWBCXDRIVER_DIR_PUBLIC_INCLUDE_PREFIX}/UwbCxLrpDeviceGlue.h ) target_include_directories(uwbcx-driver INTERFACE - ${UWBCXDRIVER_DIR_PUBLIC_INCLUDE_PREFIX} + ${UWBCXDRIVER_DIR_PUBLIC_INCLUDE} ) list(APPEND UWBCXDRIVER_PUBLIC_HEADERS + ${UWBCXDRIVER_DIR_PUBLIC_INCLUDE_PREFIX}/UwbCxDdiLrp.hxx ${UWBCXDRIVER_DIR_PUBLIC_INCLUDE_PREFIX}/UwbCxLrpDevice.h - ${UWBCXDRIVER_DIR_PUBLIC_INCLUDE_PREFIX}/UwbCxLrpDeviceGlue.h ) set_target_properties(uwbcx-driver PROPERTIES FOLDER windows/devices/uwb) @@ -26,4 +26,5 @@ set_target_properties(uwbcx-driver PROPERTIES PUBLIC_HEADER "${UWBCXDRIVER_PUBLI install( TARGETS uwbcx-driver EXPORT uwbcx-driver + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/windows/devices/uwb ) diff --git a/windows/drivers/uwb/cx/include/UwbCxLrpDeviceGlue.h b/windows/drivers/uwb/cx/include/UwbCxLrpDeviceGlue.h deleted file mode 100644 index 6c77ef4e..00000000 --- a/windows/drivers/uwb/cx/include/UwbCxLrpDeviceGlue.h +++ /dev/null @@ -1,12 +0,0 @@ - -#ifndef UWBCX_LRP_DEVICE_GLUE_H -#define UWBCX_LRP_DEVICE_GLUE_H - -// NB: This must come before any other Windows include -#include -#include -#include - -#include - -#endif // UWBCX_LRP_DEVICE_GLUE_H diff --git a/windows/drivers/uwb/cx/include/windows/devices/uwb/UwbCxDdiLrp.hxx b/windows/drivers/uwb/cx/include/windows/devices/uwb/UwbCxDdiLrp.hxx new file mode 100644 index 00000000..47932d19 --- /dev/null +++ b/windows/drivers/uwb/cx/include/windows/devices/uwb/UwbCxDdiLrp.hxx @@ -0,0 +1,12 @@ + +#ifndef UWBCX_DDI_LRP_HXX +#define UWBCX_DDI_LRP_HXX + +// NB: This must come before any other Windows include +#include +#include +#include + +#include + +#endif // UWBCX_DDI_LRP_HXX diff --git a/windows/drivers/uwb/cx/include/UwbCxLrpDevice.h b/windows/drivers/uwb/cx/include/windows/devices/uwb/UwbCxLrpDevice.h similarity index 100% rename from windows/drivers/uwb/cx/include/UwbCxLrpDevice.h rename to windows/drivers/uwb/cx/include/windows/devices/uwb/UwbCxLrpDevice.h diff --git a/windows/drivers/uwb/simulator/UwbSimulatorDdiCallbacksLrp.hxx b/windows/drivers/uwb/simulator/UwbSimulatorDdiCallbacksLrp.hxx index cd19918c..369c8d38 100644 --- a/windows/drivers/uwb/simulator/UwbSimulatorDdiCallbacksLrp.hxx +++ b/windows/drivers/uwb/simulator/UwbSimulatorDdiCallbacksLrp.hxx @@ -38,7 +38,7 @@ struct UwbSimulatorDdiCallbacksLrp * @return UwbStatus */ virtual UwbStatus - DeviceGetInformation(UwbDeviceInfo &deviceInfo) = 0; + DeviceGetInformation(UwbDeviceInfoInformation &deviceInfo) = 0; /** * @brief @@ -126,7 +126,7 @@ struct UwbSimulatorDdiCallbacksLrp * @return UwbStatus */ virtual UwbStatus - SessionGetState(uint32_t sessionId, UwbSessionState *sessionState) = 0; + SessionGetState(uint32_t sessionId, UwbSessionState &sessionState) = 0; /** * @brief @@ -166,9 +166,9 @@ struct UwbSimulatorDdiCallbacksLrp SessionGetRangingCount(uint32_t sessionId, uint32_t *rangingCount) = 0; /** - * @brief - * - * @param notificationData + * @brief + * + * @param notificationData */ virtual void UwbNotification(UwbNotificationData notificationData) = 0; diff --git a/windows/drivers/uwb/simulator/UwbSimulatorDdiCallbacksLrpNoop.cxx b/windows/drivers/uwb/simulator/UwbSimulatorDdiCallbacksLrpNoop.cxx index 5abf3f65..107f0366 100644 --- a/windows/drivers/uwb/simulator/UwbSimulatorDdiCallbacksLrpNoop.cxx +++ b/windows/drivers/uwb/simulator/UwbSimulatorDdiCallbacksLrpNoop.cxx @@ -11,7 +11,7 @@ UwbSimulatorDdiCallbacksLrpNoop::DeviceReset() } UwbStatus -UwbSimulatorDdiCallbacksLrpNoop::DeviceGetInformation(UwbDeviceInfo &deviceInfo) +UwbSimulatorDdiCallbacksLrpNoop::DeviceGetInformation(UwbDeviceInfoInformation &deviceInfo) { deviceInfo = {}; return UwbStatusOk; @@ -72,7 +72,7 @@ UwbSimulatorDdiCallbacksLrpNoop::GetSessionCount(uint32_t * /* sessionCount */) } UwbStatus -UwbSimulatorDdiCallbacksLrpNoop::SessionGetState(uint32_t /* sessionId */, UwbSessionState * /* sessionState */) +UwbSimulatorDdiCallbacksLrpNoop::SessionGetState(uint32_t /* sessionId */, UwbSessionState & /* sessionState */) { return UwbStatusOk; } @@ -104,5 +104,4 @@ UwbSimulatorDdiCallbacksLrpNoop::SessionGetRangingCount(uint32_t /* sessionId */ void UwbSimulatorDdiCallbacksLrpNoop::UwbNotification(UwbNotificationData notificationData) { - } diff --git a/windows/drivers/uwb/simulator/UwbSimulatorDdiCallbacksLrpNoop.hxx b/windows/drivers/uwb/simulator/UwbSimulatorDdiCallbacksLrpNoop.hxx index 288fcf74..42967efd 100644 --- a/windows/drivers/uwb/simulator/UwbSimulatorDdiCallbacksLrpNoop.hxx +++ b/windows/drivers/uwb/simulator/UwbSimulatorDdiCallbacksLrpNoop.hxx @@ -16,7 +16,7 @@ struct UwbSimulatorDdiCallbacksLrpNoop : DeviceReset() override; virtual UwbStatus - DeviceGetInformation(UwbDeviceInfo &deviceInfo) override; + DeviceGetInformation(UwbDeviceInfoInformation &deviceInfo) override; virtual UwbStatus DeviceGetCapabilities(UwbDeviceCapabilities &deviceCapabilities) override; @@ -43,7 +43,7 @@ struct UwbSimulatorDdiCallbacksLrpNoop : GetSessionCount(uint32_t *sessionCount) override; virtual UwbStatus - SessionGetState(uint32_t sessionId, UwbSessionState *sessionState) override; + SessionGetState(uint32_t sessionId, UwbSessionState &sessionState) override; virtual UwbStatus SessionUpdateControllerMulticastList(const std::vector &controlees) override; diff --git a/windows/drivers/uwb/simulator/UwbSimulatorDdiHandlerLrp.cxx b/windows/drivers/uwb/simulator/UwbSimulatorDdiHandlerLrp.cxx index 51471800..210272df 100644 --- a/windows/drivers/uwb/simulator/UwbSimulatorDdiHandlerLrp.cxx +++ b/windows/drivers/uwb/simulator/UwbSimulatorDdiHandlerLrp.cxx @@ -1,15 +1,22 @@ #include - -#include "UwbCxLrpDeviceGlue.h" +#include +#include +#include +#include #include "UwbSimulatorDdiCallbacksLrpNoop.hxx" #include "UwbSimulatorDdiHandlerLrp.hxx" +#include +#include + using namespace windows::devices::uwb::simulator; +namespace UwbCxDdi = windows::devices::uwb::ddi::lrp; + /** - * TODO: min+max sizes need filling in. Get these numbers from the UwbCx driver. + * TODO: min+max sizes need filling in. Get these numbers from the UwbCx driver. */ const std::initializer_list> UwbSimulatorDdiHandlerLrp::Dispatch{ UwbSimulatorDispatchEntry{ IOCTL_UWB_DEVICE_RESET, 0, 0, 0, 0, &UwbSimulatorDdiHandlerLrp::OnUwbDeviceReset }, @@ -30,22 +37,63 @@ const std::initializer_list UwbSimulatorDispatchEntry{ IOCTL_UWB_NOTIFICATION, 0, 0, 0, 0, &UwbSimulatorDdiHandlerLrp::OnUwbNotification }, }; +// IOCTL_UWB_DEVICE_RESET NTSTATUS -UwbSimulatorDdiHandlerLrp::OnUwbDeviceReset(WDFREQUEST /*request*/, std::span /*inputBuffer*/, std::span /*outputBuffer*/) +UwbSimulatorDdiHandlerLrp::OnUwbDeviceReset(WDFREQUEST request, std::span /*inputBuffer*/, std::span outputBuffer) { - return STATUS_NOT_IMPLEMENTED; + NTSTATUS status = STATUS_SUCCESS; + + // Execute callback. + auto statusUwb = m_callbacks->DeviceReset(); + + // Convert neutral types to DDI types. + auto &outputValue = *reinterpret_cast(std::data(outputBuffer)); + outputValue = UwbCxDdi::From(statusUwb); + + // Complete the request. + WdfRequestCompleteWithInformation(request, status, sizeof outputValue); + + return status; } +// IOCTL_UWB_GET_DEVICE_INFO NTSTATUS -UwbSimulatorDdiHandlerLrp::OnUwbGetDeviceInformation(WDFREQUEST /*request*/, std::span /*inputBuffer*/, std::span /*outputBuffer*/) +UwbSimulatorDdiHandlerLrp::OnUwbGetDeviceInformation(WDFREQUEST request, std::span /*inputBuffer*/, std::span outputBuffer) { - return STATUS_NOT_IMPLEMENTED; + NTSTATUS status = STATUS_SUCCESS; + + // Execute callback. + UwbDeviceInfoInformation deviceInformation{}; + auto statusUwb = m_callbacks->DeviceGetInformation(deviceInformation); + + // Convert neutral types to DDI types. + auto &outputValue = *reinterpret_cast(std::data(outputBuffer)); + outputValue = UwbCxDdi::From(deviceInformation); + + // Complete the request. + WdfRequestCompleteWithInformation(request, status, outputValue.size); + + return status; } +// IOCTL_UWB_GET_DEVICE_CAPABILITIES NTSTATUS -UwbSimulatorDdiHandlerLrp::OnUwbGetDeviceCapabilities(WDFREQUEST /*request*/, std::span /*inputBuffer*/, std::span /*outputBuffer*/) +UwbSimulatorDdiHandlerLrp::OnUwbGetDeviceCapabilities(WDFREQUEST request, std::span /*inputBuffer*/, std::span outputBuffer) { - return STATUS_NOT_IMPLEMENTED; + NTSTATUS status = STATUS_SUCCESS; + + // Execute callback. + UwbDeviceCapabilities deviceCapabilities{}; + auto statusUwb = m_callbacks->DeviceGetCapabilities(deviceCapabilities); + + // Convert neutral types to DDI types. + auto &outputValue = *reinterpret_cast(std::data(outputBuffer)); + outputValue = UwbCxDdi::From(deviceCapabilities); + + // Complete the request. + WdfRequestCompleteWithInformation(request, status, outputValue.size); + + return status; } NTSTATUS @@ -91,9 +139,25 @@ UwbSimulatorDdiHandlerLrp::OnUwbSessionDeinitialize(WDFREQUEST /*request*/, std: } NTSTATUS -UwbSimulatorDdiHandlerLrp::OnUwbGetSessionState(WDFREQUEST /*request*/, std::span /*inputBuffer*/, std::span /*outputBuffer*/) +UwbSimulatorDdiHandlerLrp::OnUwbGetSessionState(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer) { - return STATUS_NOT_IMPLEMENTED; + NTSTATUS status = STATUS_SUCCESS; + + // Convert DDI input type to neutral type. + auto &sessionStateIn = *reinterpret_cast(std::data(inputBuffer)); + UwbSessionState sessionStateResult{}; + auto statusUwb = m_callbacks->SessionGetState(sessionStateIn.sessionId, sessionStateResult); + + // Convert neutral types to DDI types. + auto &outputValue = *reinterpret_cast(std::data(outputBuffer)); + outputValue.size = sizeof outputValue; + outputValue.status = UwbCxDdi::From(statusUwb); + outputValue.sessionState = UwbCxDdi::From(sessionStateResult); + + // Complete the request. + WdfRequestCompleteWithInformation(request, status, outputValue.size); + + return status; } NTSTATUS @@ -146,7 +210,7 @@ UwbSimulatorDdiHandlerLrp::TryGetDispatchEntry(ULONG ioControlCode) bool UwbSimulatorDdiHandlerLrp::HandlesIoControlCode(ULONG ioControlCode) { - return std::ranges::any_of(Dispatch, [&](const auto& dispatchEntry) { + return std::ranges::any_of(Dispatch, [&](const auto &dispatchEntry) { return (dispatchEntry.IoControlCode == ioControlCode); }); } @@ -162,7 +226,17 @@ UwbSimulatorDdiHandlerLrp::ValidateRequest(WDFREQUEST /* request */, ULONG ioCon } NTSTATUS -UwbSimulatorDdiHandlerLrp::HandleRequest(WDFREQUEST /* request */, ULONG /* ioControlCode */, std::span /* inputBuffer */, std::span /* outputBuffer */) +UwbSimulatorDdiHandlerLrp::HandleRequest(WDFREQUEST request, ULONG ioControlCode, std::span inputBuffer, std::span outputBuffer) { - return STATUS_NOT_IMPLEMENTED; + auto dispatchEntry = TryGetDispatchEntry(ioControlCode); + if (!dispatchEntry.has_value()) { + return STATUS_NOT_SUPPORTED; + } else if (dispatchEntry->Handler == nullptr) { + return STATUS_NOT_IMPLEMENTED; + } + + // The handler function is an unbound member function so use std::invoke to + // bind it to this object instance, forwarding the request arguments. + NTSTATUS status = std::invoke(dispatchEntry->Handler, this, request, inputBuffer, outputBuffer); + return status; } diff --git a/windows/drivers/uwb/simulator/UwbSimulatorDdiHandlerLrp.hxx b/windows/drivers/uwb/simulator/UwbSimulatorDdiHandlerLrp.hxx index 52ab6f7e..767b2601 100644 --- a/windows/drivers/uwb/simulator/UwbSimulatorDdiHandlerLrp.hxx +++ b/windows/drivers/uwb/simulator/UwbSimulatorDdiHandlerLrp.hxx @@ -80,8 +80,8 @@ private: OnUwbSetApplicationConfigurationParameters(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); NTSTATUS - OnUwbGetSessionCount(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); - + OnUwbGetSessionCount(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); + NTSTATUS OnUwbSessionInitialize(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); @@ -93,7 +93,7 @@ private: NTSTATUS OnUwbSessionUpdateControllerMulticastList(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); - + NTSTATUS OnUwbSessionStartRanging(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); @@ -105,7 +105,7 @@ private: NTSTATUS OnUwbNotification(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); - + std::optional> TryGetDispatchEntry(ULONG ioControlCode); diff --git a/windows/drivers/uwb/simulator/UwbSimulatorDeviceFile.cxx b/windows/drivers/uwb/simulator/UwbSimulatorDeviceFile.cxx index 7befb512..0630e550 100644 --- a/windows/drivers/uwb/simulator/UwbSimulatorDeviceFile.cxx +++ b/windows/drivers/uwb/simulator/UwbSimulatorDeviceFile.cxx @@ -68,6 +68,7 @@ UwbSimulatorDeviceFile::OnRequest(WDFREQUEST request, ULONG ioControlCode, size_ if (inputBufferLength != 0) { status = WdfRequestRetrieveInputBuffer(request, 0, &inputBufferPtr, nullptr); if (status != STATUS_SUCCESS) { + WdfRequestComplete(request, status); return status; } } @@ -75,6 +76,7 @@ UwbSimulatorDeviceFile::OnRequest(WDFREQUEST request, ULONG ioControlCode, size_ if (outputBufferLength != 0) { status = WdfRequestRetrieveOutputBuffer(request, 0, &outputBufferPtr, nullptr); if (status != STATUS_SUCCESS) { + WdfRequestComplete(request, status); return status; } } diff --git a/windows/drivers/uwb/simulator/UwbSimulatorDispatchEntry.hxx b/windows/drivers/uwb/simulator/UwbSimulatorDispatchEntry.hxx index 4392d361..82d639f2 100644 --- a/windows/drivers/uwb/simulator/UwbSimulatorDispatchEntry.hxx +++ b/windows/drivers/uwb/simulator/UwbSimulatorDispatchEntry.hxx @@ -16,7 +16,7 @@ namespace windows::devices::uwb::simulator /** * @brief Represents an entry used to dispatch WDF requests to a handler * implementation. - * + * * @tparam ClassT The type of the containing class which defines the * implementation handler functions. This limits the member functions which can * be used to dispatch execution. @@ -36,7 +36,7 @@ struct UwbSimulatorDispatchEntry /** * @brief Determines whether the specified request parameters are valid for * this dispatch entry. - * + * * @param inputBufferSize The size of the request input buffer, in bytes. * @param outputBufferSize The size of the request output buffer, in bytes. * @return NTSTATUS