diff --git a/windows/drivers/uwb/simulator/IUwbSimulator.hxx b/windows/drivers/uwb/simulator/IUwbSimulator.hxx new file mode 100644 index 00000000..dbc5c25a --- /dev/null +++ b/windows/drivers/uwb/simulator/IUwbSimulator.hxx @@ -0,0 +1,17 @@ + +#ifndef I_UWB_SIMULATOR_HXX +#define I_UWB_SIMULATOR_HXX + +#include + +namespace windows::devices::uwb::simulator +{ +struct IUwbSimulator +{ + static constexpr uint8_t VersionMajor = 1; + static constexpr uint8_t VersionMinor = 0; + static constexpr uint32_t Version = (VersionMajor << 16U) | VersionMinor; +}; +} // namespace windows::devices::uwb::simulator + +#endif // I_UWB_SIMULATOR_HXX diff --git a/windows/drivers/uwb/simulator/UwbSimulatorDdiCallbacksLrp.hxx b/windows/drivers/uwb/simulator/IUwbSimulatorDdiCallbacksLrp.hxx similarity index 91% rename from windows/drivers/uwb/simulator/UwbSimulatorDdiCallbacksLrp.hxx rename to windows/drivers/uwb/simulator/IUwbSimulatorDdiCallbacksLrp.hxx index 93960d97..1f6238e0 100644 --- a/windows/drivers/uwb/simulator/UwbSimulatorDdiCallbacksLrp.hxx +++ b/windows/drivers/uwb/simulator/IUwbSimulatorDdiCallbacksLrp.hxx @@ -1,6 +1,6 @@ -#ifndef UWB_SIMULATOR_DDI_CALLBACKS_LRP -#define UWB_SIMULATOR_DDI_CALLBACKS_LRP +#ifndef I_UWB_SIMULATOR_DDI_CALLBACKS_LRP +#define I_UWB_SIMULATOR_DDI_CALLBACKS_LRP #include #include @@ -25,9 +25,9 @@ namespace windows::devices::uwb::simulator /** * @brief */ -struct UwbSimulatorDdiCallbacksLrp +struct IUwbSimulatorDdiCallbacksLrp { - virtual ~UwbSimulatorDdiCallbacksLrp() = default; + virtual ~IUwbSimulatorDdiCallbacksLrp() = default; /** * @brief @@ -181,4 +181,4 @@ struct UwbSimulatorDdiCallbacksLrp }; } // namespace windows::devices::uwb::simulator -#endif // UWB_SIMULATOR_DDI_CALLBACKS_LRP +#endif // I_UWB_SIMULATOR_DDI_CALLBACKS_LRP diff --git a/windows/drivers/uwb/simulator/UwbSimulatorDdiCallbacksSimulator.hxx b/windows/drivers/uwb/simulator/IUwbSimulatorDdiCallbacksSimulator.hxx similarity index 53% rename from windows/drivers/uwb/simulator/UwbSimulatorDdiCallbacksSimulator.hxx rename to windows/drivers/uwb/simulator/IUwbSimulatorDdiCallbacksSimulator.hxx index 3b054996..d9a471c1 100644 --- a/windows/drivers/uwb/simulator/UwbSimulatorDdiCallbacksSimulator.hxx +++ b/windows/drivers/uwb/simulator/IUwbSimulatorDdiCallbacksSimulator.hxx @@ -1,6 +1,6 @@ -#ifndef UWB_SIMULATOR_DDI_CALLBACKS_SIMULATOR -#define UWB_SIMULATOR_DDI_CALLBACKS_SIMULATOR +#ifndef I_UWB_SIMULATOR_DDI_CALLBACKS_SIMULATOR +#define I_UWB_SIMULATOR_DDI_CALLBACKS_SIMULATOR #include @@ -11,17 +11,17 @@ namespace windows::devices::uwb::simulator /** * @brief */ -struct UwbSimulatorDdiCallbacksSimulator +struct IUwbSimulatorDdiCallbacksSimulator { - virtual ~UwbSimulatorDdiCallbacksSimulator() = default; + virtual ~IUwbSimulatorDdiCallbacksSimulator() = default; /** * @brief * * @return UwbStatus */ - virtual void - GetSimulatorCapabilities(UwbSimulatorCapabilities& uwbSimulatorCapabilities) = 0; + virtual UwbSimulatorCapabilities + GetSimulatorCapabilities() = 0; /** * @brief @@ -34,4 +34,4 @@ struct UwbSimulatorDdiCallbacksSimulator }; } // namespace windows::devices::uwb::simulator -#endif // UWB_SIMULATOR_DDI_CALLBACKS_SIMULATOR +#endif // I_UWB_SIMULATOR_DDI_CALLBACKS_SIMULATOR diff --git a/windows/drivers/uwb/simulator/IUwbSimulatorDdiHandler.hxx b/windows/drivers/uwb/simulator/IUwbSimulatorDdiHandler.hxx new file mode 100644 index 00000000..a4149e4b --- /dev/null +++ b/windows/drivers/uwb/simulator/IUwbSimulatorDdiHandler.hxx @@ -0,0 +1,61 @@ + +#ifndef I_UWB_SIMULATOR_DDI_HANDLER_HXX +#define I_UWB_SIMULATOR_DDI_HANDLER_HXX + +#include +#include + +#include + +#include + +namespace windows::devices::uwb::simulator +{ +/** + * @brief Base class which responsible for handling DDI i/o control requests. + */ +struct IUwbSimulatorDdiHandler +{ + virtual ~IUwbSimulatorDdiHandler() = default; + + /** + * @brief Indicates whether the specified i/o control code is handled by + * this handler. + * + * @param ioControlCode The i/o control code to check. + * @return true + * @return false + */ + virtual bool + HandlesIoControlCode(ULONG ioControlCode) = 0; + + /** + * @brief Validates that a given request is valid. + * + * This is responsible for validating that the input and output buffers are + * of sufficient length. + * + * @param request + * @param ioControlCode + * @param inputBufferLength + * @param outputBufferLength + * @return NTSTATUS + */ + virtual NTSTATUS + ValidateRequest(WDFREQUEST request, ULONG ioControlCode, std::size_t inputBufferLength, std::size_t outputBufferLength) = 0; + + /** + * @brief Handles the request. + * + * @param request + * @param ioControlCode + * @param inputBuffer + * @param outputBuffer + * @return NTSTATUS + */ + virtual NTSTATUS + HandleRequest(WDFREQUEST request, ULONG ioControlCode, std::span inputBuffer, std::span outputBuffer) = 0; +}; +} // namespace windows::devices::uwb::simulator + +#endif // I_UWB_SIMULATOR_DDI_HANDLER_HXX diff --git a/windows/drivers/uwb/simulator/IUwbSimulatorSession.hxx b/windows/drivers/uwb/simulator/IUwbSimulatorSession.hxx new file mode 100644 index 00000000..693552a0 --- /dev/null +++ b/windows/drivers/uwb/simulator/IUwbSimulatorSession.hxx @@ -0,0 +1,29 @@ + +#ifndef I_UWB_SIMULATOR_SESSION_HXX +#define I_UWB_SIMULATOR_SESSION_HXX + +#include +#include +#include + +#include +#include +#include + +namespace windows::devices::uwb::simulator +{ +using ::uwb::protocol::fira::UwbSessionState; +using ::uwb::protocol::fira::UwbSessionType; + +struct IUwbSimulatorSession +{ + uint32_t Id; + UwbSessionType Type{ UwbSessionType::RangingSession }; + UwbSessionState State{ UwbSessionState::Deinitialized }; + uint32_t Sequence{ 0 }; + std::unordered_set<::uwb::UwbMacAddress> Controlees; + std::vector> ApplicationConfigurationParameters; +}; +} // namespace windows::devices::uwb::simulator + +#endif // I_UWB_SIMULATOR_SESSION_HXX diff --git a/windows/drivers/uwb/simulator/UwbSimulator.vcxproj b/windows/drivers/uwb/simulator/UwbSimulator.vcxproj index 415ab66a..a50a336f 100644 --- a/windows/drivers/uwb/simulator/UwbSimulator.vcxproj +++ b/windows/drivers/uwb/simulator/UwbSimulator.vcxproj @@ -11,31 +11,30 @@ - - - + + - - + + + - - - - + + + diff --git a/windows/drivers/uwb/simulator/UwbSimulatorDdiCallbacksLrpNoop.cxx b/windows/drivers/uwb/simulator/UwbSimulatorDdiCallbacks.cxx similarity index 60% rename from windows/drivers/uwb/simulator/UwbSimulatorDdiCallbacksLrpNoop.cxx rename to windows/drivers/uwb/simulator/UwbSimulatorDdiCallbacks.cxx index 70db7f01..1dbb8689 100644 --- a/windows/drivers/uwb/simulator/UwbSimulatorDdiCallbacksLrpNoop.cxx +++ b/windows/drivers/uwb/simulator/UwbSimulatorDdiCallbacks.cxx @@ -7,7 +7,8 @@ #include #include -#include "UwbSimulatorDdiCallbacksLrpNoop.hxx" +#include "IUwbSimulator.hxx" +#include "UwbSimulatorDdiCallbacks.hxx" #include "UwbSimulatorTracelogging.hxx" using namespace windows::devices::uwb; @@ -19,8 +20,12 @@ using namespace windows::devices::uwb::simulator; */ namespace UwbCxDdi = windows::devices::uwb::ddi::lrp; +UwbSimulatorDdiCallbacks::UwbSimulatorDdiCallbacks() : + m_simulatorCapabilities({ IUwbSimulator::Version }) +{} + NTSTATUS -UwbSimulatorDdiCallbacksLrpNoop::RaiseUwbNotification(UwbNotificationData uwbNotificationData) +UwbSimulatorDdiCallbacks::RaiseUwbNotification(UwbNotificationData uwbNotificationData) { // Acquire the notification lock to ensure the notification proimise can be safely inspected and updated. std::unique_lock notificationLock{ m_notificationGate }; @@ -45,7 +50,7 @@ UwbSimulatorDdiCallbacksLrpNoop::RaiseUwbNotification(UwbNotificationData uwbNot } void -UwbSimulatorDdiCallbacksLrpNoop::SessionUpdateState(UwbSimulatorSession &session, UwbSessionState sessionState, std::optional reasonCode = std::nullopt) +UwbSimulatorDdiCallbacks::SessionUpdateState(UwbSimulatorSession &session, UwbSessionState sessionState, std::optional reasonCode = std::nullopt) { TraceLoggingWrite( UwbSimulatorTraceloggingProvider, @@ -68,41 +73,41 @@ UwbSimulatorDdiCallbacksLrpNoop::SessionUpdateState(UwbSimulatorSession &session } UwbStatus -UwbSimulatorDdiCallbacksLrpNoop::DeviceReset() +UwbSimulatorDdiCallbacks::DeviceReset() { return UwbStatusOk; } UwbStatus -UwbSimulatorDdiCallbacksLrpNoop::DeviceGetInformation(UwbDeviceInformation &deviceInformation) +UwbSimulatorDdiCallbacks::DeviceGetInformation(UwbDeviceInformation &deviceInformation) { deviceInformation = m_deviceInformation; return UwbStatusOk; } UwbStatus -UwbSimulatorDdiCallbacksLrpNoop::DeviceGetCapabilities(UwbCapability &deviceCapabilities) +UwbSimulatorDdiCallbacks::DeviceGetCapabilities(UwbCapability &deviceCapabilities) { deviceCapabilities = m_deviceCapabilities; return UwbStatusOk; } UwbStatus -UwbSimulatorDdiCallbacksLrpNoop::DeviceGetConfigurationParameters(std::vector & /* deviceConfigurationParameterTypes */, std::vector>> &deviceConfigurationParameterResults) +UwbSimulatorDdiCallbacks::DeviceGetConfigurationParameters(std::vector & /* deviceConfigurationParameterTypes */, std::vector>> &deviceConfigurationParameterResults) { deviceConfigurationParameterResults = {}; return UwbStatusOk; } UwbStatus -UwbSimulatorDdiCallbacksLrpNoop::DeviceSetConfigurationParameters(const std::vector & /* deviceConfigurationParameters */, std::vector> &deviceConfigurationParameterResults) +UwbSimulatorDdiCallbacks::DeviceSetConfigurationParameters(const std::vector & /* deviceConfigurationParameters */, std::vector> &deviceConfigurationParameterResults) { deviceConfigurationParameterResults = {}; return UwbStatusOk; } UwbStatus -UwbSimulatorDdiCallbacksLrpNoop::SessionInitialize(uint32_t sessionId, UwbSessionType sessionType) +UwbSimulatorDdiCallbacks::SessionInitialize(uint32_t sessionId, UwbSessionType sessionType) { std::unique_lock sessionsWriteLock{ m_sessionsGate }; auto [sessionIt, inserted] = m_sessions.try_emplace(sessionId, sessionId, sessionType); @@ -117,7 +122,7 @@ UwbSimulatorDdiCallbacksLrpNoop::SessionInitialize(uint32_t sessionId, UwbSessio } UwbStatus -UwbSimulatorDdiCallbacksLrpNoop::SessionDeninitialize(uint32_t sessionId) +UwbSimulatorDdiCallbacks::SessionDeninitialize(uint32_t sessionId) { decltype(m_sessions)::node_type nodeHandle; { @@ -137,7 +142,7 @@ UwbSimulatorDdiCallbacksLrpNoop::SessionDeninitialize(uint32_t sessionId) } UwbStatus -UwbSimulatorDdiCallbacksLrpNoop::SetApplicationConfigurationParameters(uint32_t /*sessionId*/, const std::vector> & /* applicationConfigurationParameters */, std::vector>> &applicationConfigurationParameterResults) +UwbSimulatorDdiCallbacks::SetApplicationConfigurationParameters(uint32_t /*sessionId*/, const std::vector> & /* applicationConfigurationParameters */, std::vector>> &applicationConfigurationParameterResults) { std::vector>> results{}; applicationConfigurationParameterResults = std::move(results); @@ -145,7 +150,7 @@ UwbSimulatorDdiCallbacksLrpNoop::SetApplicationConfigurationParameters(uint32_t } UwbStatus -UwbSimulatorDdiCallbacksLrpNoop::GetApplicationConfigurationParameters(uint32_t sessionId, std::vector> &applicationConfigurationParameters) +UwbSimulatorDdiCallbacks::GetApplicationConfigurationParameters(uint32_t sessionId, std::vector> &applicationConfigurationParameters) { std::shared_lock sessionsReadLock{ m_sessionsGate }; auto sessionIt = m_sessions.find(sessionId); @@ -160,7 +165,7 @@ UwbSimulatorDdiCallbacksLrpNoop::GetApplicationConfigurationParameters(uint32_t } UwbStatus -UwbSimulatorDdiCallbacksLrpNoop::GetSessionCount(uint32_t &sessionCount) +UwbSimulatorDdiCallbacks::GetSessionCount(uint32_t &sessionCount) { std::shared_lock sessionsReadLock{ m_sessionsGate }; sessionCount = static_cast(std::size(m_sessions)); @@ -168,7 +173,7 @@ UwbSimulatorDdiCallbacksLrpNoop::GetSessionCount(uint32_t &sessionCount) } UwbStatus -UwbSimulatorDdiCallbacksLrpNoop::SessionGetState(uint32_t sessionId, UwbSessionState &sessionState) +UwbSimulatorDdiCallbacks::SessionGetState(uint32_t sessionId, UwbSessionState &sessionState) { std::shared_lock sessionsReadLock{ m_sessionsGate }; auto sessionIt = m_sessions.find(sessionId); @@ -182,7 +187,7 @@ UwbSimulatorDdiCallbacksLrpNoop::SessionGetState(uint32_t sessionId, UwbSessionS } UwbStatus -UwbSimulatorDdiCallbacksLrpNoop::SessionUpdateControllerMulticastList(uint32_t sessionId, std::vector controlees) +UwbSimulatorDdiCallbacks::SessionUpdateControllerMulticastList(uint32_t sessionId, std::vector controlees) { std::unique_lock sessionsWriteLock{ m_sessionsGate }; auto sessionIt = m_sessions.find(sessionId); @@ -196,7 +201,7 @@ UwbSimulatorDdiCallbacksLrpNoop::SessionUpdateControllerMulticastList(uint32_t s } UwbStatus -UwbSimulatorDdiCallbacksLrpNoop::SessionStartRanging(uint32_t sessionId) +UwbSimulatorDdiCallbacks::SessionStartRanging(uint32_t sessionId) { std::unique_lock sessionsWriteLock{ m_sessionsGate }; auto sessionIt = m_sessions.find(sessionId); @@ -210,7 +215,7 @@ UwbSimulatorDdiCallbacksLrpNoop::SessionStartRanging(uint32_t sessionId) } UwbStatus -UwbSimulatorDdiCallbacksLrpNoop::SessionStopRanging(uint32_t sessionId) +UwbSimulatorDdiCallbacks::SessionStopRanging(uint32_t sessionId) { std::unique_lock sessionsWriteLock{ m_sessionsGate }; auto sessionIt = m_sessions.find(sessionId); @@ -224,13 +229,13 @@ UwbSimulatorDdiCallbacksLrpNoop::SessionStopRanging(uint32_t sessionId) } UwbStatus -UwbSimulatorDdiCallbacksLrpNoop::SessionGetRangingCount(uint32_t /* sessionId */, uint32_t & /* rangingCount */) +UwbSimulatorDdiCallbacks::SessionGetRangingCount(uint32_t /* sessionId */, uint32_t & /* rangingCount */) { return UwbStatusOk; } NTSTATUS -UwbSimulatorDdiCallbacksLrpNoop::UwbNotification(UwbNotificationData ¬ificationData) +UwbSimulatorDdiCallbacks::UwbNotification(UwbNotificationData ¬ificationData) { // Acquire the notification lock to ensure the notification proimise can be safely inspected and updated. std::unique_lock notificationLock{ m_notificationGate }; @@ -268,3 +273,52 @@ UwbSimulatorDdiCallbacksLrpNoop::UwbNotification(UwbNotificationData ¬ificati return STATUS_SUCCESS; } + +UwbSimulatorCapabilities +UwbSimulatorDdiCallbacks::GetSimulatorCapabilities() +{ + return m_simulatorCapabilities; +} + +void +UwbSimulatorDdiCallbacks::TriggerSessionEvent(const UwbSimulatorTriggerSessionEventArgs &triggerSessionEventArgs) +{ + switch (triggerSessionEventArgs.Action) { + case UwbSimulatorSessionEventAction::RandomRangingMeasurementGenerationStart: { + SessionRandomMeasurementGenerationConfigure(triggerSessionEventArgs.SessionId, RandomMeasurementGeneration::Enable); + break; + } + case UwbSimulatorSessionEventAction::RandomRangingMeasurementGenerationStop: { + SessionRandomMeasurementGenerationConfigure(triggerSessionEventArgs.SessionId, RandomMeasurementGeneration::Disable); + break; + } + case UwbSimulatorSessionEventAction::None: { + break; + } + default: { + break; + } + } +} + +void +UwbSimulatorDdiCallbacks::SessionRandomMeasurementGenerationConfigure(uint32_t sessionId, RandomMeasurementGeneration action) +{ + std::unique_lock sessionsWriteLock{ m_sessionsGate }; + auto sessionIt = m_sessions.find(sessionId); + if (sessionIt == std::cend(m_sessions)) { + return; + } + + auto &[_, session] = *sessionIt; + + switch (action) { + case RandomMeasurementGeneration::Disable: + session.RandomRangingMeasurementGenerationStop(); + break; + case RandomMeasurementGeneration::Enable: + session.RandomRangingMeasurementGenerationStart([&](UwbRangingData rangingData) { + RaiseUwbNotification(std::move(rangingData)); + }); + } +} diff --git a/windows/drivers/uwb/simulator/UwbSimulatorDdiCallbacksLrpNoop.hxx b/windows/drivers/uwb/simulator/UwbSimulatorDdiCallbacks.hxx similarity index 76% rename from windows/drivers/uwb/simulator/UwbSimulatorDdiCallbacksLrpNoop.hxx rename to windows/drivers/uwb/simulator/UwbSimulatorDdiCallbacks.hxx index a7c0aee6..3c246a46 100644 --- a/windows/drivers/uwb/simulator/UwbSimulatorDdiCallbacksLrpNoop.hxx +++ b/windows/drivers/uwb/simulator/UwbSimulatorDdiCallbacks.hxx @@ -1,6 +1,6 @@ -#ifndef UWB_SIMULATOR_DDI_CALLBACKS_LRP_NOOP -#define UWB_SIMULATOR_DDI_CALLBACKS_LRP_NOOP +#ifndef UWB_SIMULATOR_DDI_CALLBACKS_HXX +#define UWB_SIMULATOR_DDI_CALLBACKS_HXX #include #include @@ -15,7 +15,10 @@ #include -#include "UwbSimulatorDdiCallbacksLrp.hxx" +#include "UwbSimulatorDdi.h" + +#include "IUwbSimulatorDdiCallbacksLrp.hxx" +#include "IUwbSimulatorDdiCallbacksSimulator.hxx" #include "UwbSimulatorSession.hxx" #include @@ -24,9 +27,14 @@ namespace windows::devices::uwb::simulator { -struct UwbSimulatorDdiCallbacksLrpNoop : - public UwbSimulatorDdiCallbacksLrp +struct UwbSimulatorDdiCallbacks : + public IUwbSimulatorDdiCallbacksLrp, + public IUwbSimulatorDdiCallbacksSimulator { + UwbSimulatorDdiCallbacks(); + + // IUwbSimulatorDdiCallbacksLrp + virtual UwbStatus DeviceReset() override; @@ -75,6 +83,14 @@ struct UwbSimulatorDdiCallbacksLrpNoop : virtual NTSTATUS UwbNotification(UwbNotificationData ¬ificationData) override; + // IUwbSimulatorDdiCallbacksSimulator + + virtual UwbSimulatorCapabilities + GetSimulatorCapabilities() override; + + virtual void + TriggerSessionEvent(const UwbSimulatorTriggerSessionEventArgs &triggerSessionEventArgs) override; + protected: /** * @brief Update the state of the specified session. @@ -88,6 +104,15 @@ protected: void SessionUpdateState(UwbSimulatorSession &session, UwbSessionState sessionState, std::optional reasonCode); + /** + * @brief Configure a session for random measurement generation. + * + * @param sessionId The session to configure. + * @param action The action to take. + */ + void + SessionRandomMeasurementGenerationConfigure(uint32_t sessionId, RandomMeasurementGeneration action); + /** * @brief Raise a UWB notification. * @@ -108,7 +133,10 @@ private: // Notification promise and associated lock that protects it. std::mutex m_notificationGate; std::optional> m_notificationPromise; + +private: + UwbSimulatorCapabilities m_simulatorCapabilities{}; }; } // namespace windows::devices::uwb::simulator -#endif // UWB_SIMULATOR_DDI_CALLBACKS_LRP_NOOP +#endif // UWB_SIMULATOR_DDI_CALLBACKS_HXX diff --git a/windows/drivers/uwb/simulator/UwbSimulatorDdiCallbacksSimulatorImpl.cxx b/windows/drivers/uwb/simulator/UwbSimulatorDdiCallbacksSimulatorImpl.cxx deleted file mode 100644 index 46e7f143..00000000 --- a/windows/drivers/uwb/simulator/UwbSimulatorDdiCallbacksSimulatorImpl.cxx +++ /dev/null @@ -1,18 +0,0 @@ - -#include - -#include "UwbSimulatorDdiCallbacksSimulatorImpl.hxx" -#include "UwbSimulatorTracelogging.hxx" - -using namespace windows::devices::uwb; -using namespace windows::devices::uwb::simulator; - -void -UwbSimulatorDdiCallbacksSimulatorImpl::GetSimulatorCapabilities(UwbSimulatorCapabilities & /*uwbSimulatorCapabilities*/) -{ -} - -void -UwbSimulatorDdiCallbacksSimulatorImpl::TriggerSessionEvent(const UwbSimulatorTriggerSessionEventArgs & /*triggerSessionEventArgs*/) -{ -} diff --git a/windows/drivers/uwb/simulator/UwbSimulatorDdiCallbacksSimulatorImpl.hxx b/windows/drivers/uwb/simulator/UwbSimulatorDdiCallbacksSimulatorImpl.hxx deleted file mode 100644 index 0774ba83..00000000 --- a/windows/drivers/uwb/simulator/UwbSimulatorDdiCallbacksSimulatorImpl.hxx +++ /dev/null @@ -1,28 +0,0 @@ - -#ifndef UWB_SIMULATOR_DDI_CALLBACKS_SIMULATOR_IMPL -#define UWB_SIMULATOR_DDI_CALLBACKS_SIMULATOR_IMPL - -#include - -#include "UwbSimulatorDdi.h" -#include "UwbSimulatorDdiCallbacksSimulator.hxx" - -namespace windows::devices::uwb::simulator -{ -/** - * @brief - */ -struct UwbSimulatorDdiCallbacksSimulatorImpl : - public UwbSimulatorDdiCallbacksSimulator -{ - virtual ~UwbSimulatorDdiCallbacksSimulatorImpl() = default; - - virtual void - GetSimulatorCapabilities(UwbSimulatorCapabilities &uwbSimulatorCapabilities) override; - - virtual void - TriggerSessionEvent(const UwbSimulatorTriggerSessionEventArgs &triggerSessionEventArgs) override; -}; -} // namespace windows::devices::uwb::simulator - -#endif // UWB_SIMULATOR_DDI_CALLBACKS_SIMULATOR_IMPL diff --git a/windows/drivers/uwb/simulator/UwbSimulatorDdiHandler.hxx b/windows/drivers/uwb/simulator/UwbSimulatorDdiHandler.hxx index dde04de1..2437213e 100644 --- a/windows/drivers/uwb/simulator/UwbSimulatorDdiHandler.hxx +++ b/windows/drivers/uwb/simulator/UwbSimulatorDdiHandler.hxx @@ -1,22 +1,26 @@ -#ifndef UWB_SIMULATOR_DDI_HANDLER_HXX -#define UWB_SIMULATOR_DDI_HANDLER_HXX +#ifndef UWB_SIMULATOR_DDI_HANDLER +#define UWB_SIMULATOR_DDI_HANDLER -#include -#include +#include +#include +#include #include #include +#include "IUwbSimulatorDdiHandler.hxx" +#include "UwbSimulatorDdiCallbacks.hxx" +#include "UwbSimulatorDispatchEntry.hxx" + namespace windows::devices::uwb::simulator { -/** - * @brief Base class which responsible for handling DDI i/o control requests. - */ -struct UwbSimulatorDdiHandler +class UwbSimulatorDdiHandler : + public IUwbSimulatorDdiHandler { - virtual ~UwbSimulatorDdiHandler() = default; +public: + UwbSimulatorDdiHandler(); /** * @brief Indicates whether the specified i/o control code is handled by @@ -26,14 +30,11 @@ struct UwbSimulatorDdiHandler * @return true * @return false */ - virtual bool - HandlesIoControlCode(ULONG ioControlCode) = 0; + bool + HandlesIoControlCode(ULONG ioControlCode) override; /** - * @brief Validates that a given request is valid. - * - * This is responsible for validating that the input and output buffers are - * of sufficient length. + * @brief * * @param request * @param ioControlCode @@ -41,11 +42,11 @@ struct UwbSimulatorDdiHandler * @param outputBufferLength * @return NTSTATUS */ - virtual NTSTATUS - ValidateRequest(WDFREQUEST request, ULONG ioControlCode, std::size_t inputBufferLength, std::size_t outputBufferLength) = 0; + NTSTATUS + ValidateRequest(WDFREQUEST request, ULONG ioControlCode, std::size_t inputBufferLength, std::size_t outputBufferLength) override; /** - * @brief Handles the request. + * @brief * * @param request * @param ioControlCode @@ -53,9 +54,77 @@ struct UwbSimulatorDdiHandler * @param outputBuffer * @return NTSTATUS */ - virtual NTSTATUS - HandleRequest(WDFREQUEST request, ULONG ioControlCode, std::span inputBuffer, std::span outputBuffer) = 0; + NTSTATUS + HandleRequest(WDFREQUEST request, ULONG ioControlCode, std::span inputBuffer, std::span outputBuffer) override; + +private: + // GUID_UWB_DEVICE_INTERFACE Handlers + NTSTATUS + OnUwbDeviceReset(WDFREQUEST, std::span, std::span); + + NTSTATUS + OnUwbGetDeviceInformation(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); + + NTSTATUS + OnUwbGetDeviceCapabilities(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); + + NTSTATUS + OnUwbGetDeviceConfigurationParameters(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); + + NTSTATUS + OnUwbSetDeviceConfigurationParameters(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); + + NTSTATUS + OnUwbGetApplicationConfigurationParameters(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); + + NTSTATUS + OnUwbSetApplicationConfigurationParameters(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); + + NTSTATUS + OnUwbGetSessionCount(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); + + NTSTATUS + OnUwbSessionInitialize(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); + + NTSTATUS + OnUwbSessionDeinitialize(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); + + NTSTATUS + OnUwbGetSessionState(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); + + NTSTATUS + OnUwbSessionUpdateControllerMulticastList(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); + + NTSTATUS + OnUwbSessionStartRanging(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); + + NTSTATUS + OnUwbSessionStopRanging(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); + + NTSTATUS + OnUwbSessionGetRangingCount(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); + + NTSTATUS + OnUwbNotification(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); + + // GUID_DEVINTERFACE_UWB_SIMULATOR Handlers + + NTSTATUS + OnUwbSimulatorCapabilities(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); + + NTSTATUS + OnUwbSimulatorTriggerSessionEvent(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); + +private: + std::optional> + TryGetDispatchEntry(ULONG ioControlCode); + +private: + static const std::initializer_list> Dispatch; + +private: + std::unique_ptr m_callbacks; }; } // namespace windows::devices::uwb::simulator -#endif // UWB_SIMULATOR_DDI_HANDLER_HXX +#endif // UWB_SIMULATOR_DDI_HANDLER diff --git a/windows/drivers/uwb/simulator/UwbSimulatorDdiHandlerLrp.cxx b/windows/drivers/uwb/simulator/UwbSimulatorDdiHandlerLrp.cxx index 3dd2f8f6..fd15b5db 100644 --- a/windows/drivers/uwb/simulator/UwbSimulatorDdiHandlerLrp.cxx +++ b/windows/drivers/uwb/simulator/UwbSimulatorDdiHandlerLrp.cxx @@ -5,8 +5,8 @@ #include #include -#include "UwbSimulatorDdiCallbacksLrpNoop.hxx" -#include "UwbSimulatorDdiHandlerLrp.hxx" +#include "UwbSimulatorDdiCallbacks.hxx" +#include "UwbSimulatorDdiHandler.hxx" #include #include @@ -21,7 +21,7 @@ namespace UwbCxDdi = windows::devices::uwb::ddi::lrp; /** * @brief Template function alias which partially specializes the - * UwbSimulatorDispatchEntry template with ClassT = UwbSimulatorDdiHandlerLrp. + * UwbSimulatorDispatchEntry template with ClassT = UwbSimulatorDdiHandler. * This reduces some typing. * * It's not possible to create an alias to a templated function, however, it is @@ -35,7 +35,7 @@ namespace UwbCxDdi = windows::devices::uwb::ddi::lrp; template < typename InputT = Unrestricted, typename OutputT = Unrestricted> -UwbSimulatorDispatchEntry (*MakeLrpDispatchEntry)(ULONG, typename UwbSimulatorDispatchEntry::HandlerFuncT) = &MakeDispatchEntry; +UwbSimulatorDispatchEntry (*MakeLrpDispatchEntry)(ULONG, typename UwbSimulatorDispatchEntry::HandlerFuncT) = &MakeDispatchEntry; /** * @brief Dispatch table for the LRP DDI driver IOCTLs. @@ -43,28 +43,32 @@ UwbSimulatorDispatchEntry (*MakeLrpDispatchEntry)(ULO * This defines the expected input and output buffer sizes and the corresponding * member function that will handle the IOCTL. */ -const std::initializer_list> UwbSimulatorDdiHandlerLrp::Dispatch{ - MakeLrpDispatchEntry(IOCTL_UWB_DEVICE_RESET, &UwbSimulatorDdiHandlerLrp::OnUwbDeviceReset), - MakeLrpDispatchEntry(IOCTL_UWB_GET_DEVICE_INFO, &UwbSimulatorDdiHandlerLrp::OnUwbGetDeviceInformation), - MakeLrpDispatchEntry(IOCTL_UWB_GET_DEVICE_CAPABILITIES, &UwbSimulatorDdiHandlerLrp::OnUwbGetDeviceCapabilities), - MakeLrpDispatchEntry(IOCTL_UWB_GET_DEVICE_CONFIG_PARAMS, &UwbSimulatorDdiHandlerLrp::OnUwbGetDeviceConfigurationParameters), - MakeLrpDispatchEntry(IOCTL_UWB_SET_DEVICE_CONFIG_PARAMS, &UwbSimulatorDdiHandlerLrp::OnUwbSetDeviceConfigurationParameters), - MakeLrpDispatchEntry(IOCTL_UWB_GET_APP_CONFIG_PARAMS, &UwbSimulatorDdiHandlerLrp::OnUwbGetApplicationConfigurationParameters), - MakeLrpDispatchEntry(IOCTL_UWB_SET_APP_CONFIG_PARAMS, &UwbSimulatorDdiHandlerLrp::OnUwbSetApplicationConfigurationParameters), - MakeLrpDispatchEntry(IOCTL_UWB_GET_SESSION_COUNT, &UwbSimulatorDdiHandlerLrp::OnUwbGetSessionCount), - MakeLrpDispatchEntry(IOCTL_UWB_SESSION_INIT, &UwbSimulatorDdiHandlerLrp::OnUwbSessionInitialize), - MakeLrpDispatchEntry(IOCTL_UWB_SESSION_DEINIT, &UwbSimulatorDdiHandlerLrp::OnUwbSessionDeinitialize), - MakeLrpDispatchEntry(IOCTL_UWB_GET_SESSION_STATE, &UwbSimulatorDdiHandlerLrp::OnUwbGetSessionState), - MakeLrpDispatchEntry(IOCTL_UWB_SESSION_UPDATE_CONTROLLER_MULTICAST_LIST, &UwbSimulatorDdiHandlerLrp::OnUwbSessionUpdateControllerMulticastList), - MakeLrpDispatchEntry(IOCTL_UWB_START_RANGING_SESSION, &UwbSimulatorDdiHandlerLrp::OnUwbSessionStartRanging), - MakeLrpDispatchEntry(IOCTL_UWB_STOP_RANGING_SESSION, &UwbSimulatorDdiHandlerLrp::OnUwbSessionStopRanging), - MakeLrpDispatchEntry(IOCTL_UWB_GET_RANGING_COUNT, &UwbSimulatorDdiHandlerLrp::OnUwbSessionGetRangingCount), - MakeLrpDispatchEntry(IOCTL_UWB_NOTIFICATION, &UwbSimulatorDdiHandlerLrp::OnUwbNotification), +const std::initializer_list> UwbSimulatorDdiHandler::Dispatch{ + // GUID_UWB_DEVICE_INTERFACE Handlers + MakeLrpDispatchEntry(IOCTL_UWB_DEVICE_RESET, &UwbSimulatorDdiHandler::OnUwbDeviceReset), + MakeLrpDispatchEntry(IOCTL_UWB_GET_DEVICE_INFO, &UwbSimulatorDdiHandler::OnUwbGetDeviceInformation), + MakeLrpDispatchEntry(IOCTL_UWB_GET_DEVICE_CAPABILITIES, &UwbSimulatorDdiHandler::OnUwbGetDeviceCapabilities), + MakeLrpDispatchEntry(IOCTL_UWB_GET_DEVICE_CONFIG_PARAMS, &UwbSimulatorDdiHandler::OnUwbGetDeviceConfigurationParameters), + MakeLrpDispatchEntry(IOCTL_UWB_SET_DEVICE_CONFIG_PARAMS, &UwbSimulatorDdiHandler::OnUwbSetDeviceConfigurationParameters), + MakeLrpDispatchEntry(IOCTL_UWB_GET_APP_CONFIG_PARAMS, &UwbSimulatorDdiHandler::OnUwbGetApplicationConfigurationParameters), + MakeLrpDispatchEntry(IOCTL_UWB_SET_APP_CONFIG_PARAMS, &UwbSimulatorDdiHandler::OnUwbSetApplicationConfigurationParameters), + MakeLrpDispatchEntry(IOCTL_UWB_GET_SESSION_COUNT, &UwbSimulatorDdiHandler::OnUwbGetSessionCount), + MakeLrpDispatchEntry(IOCTL_UWB_SESSION_INIT, &UwbSimulatorDdiHandler::OnUwbSessionInitialize), + MakeLrpDispatchEntry(IOCTL_UWB_SESSION_DEINIT, &UwbSimulatorDdiHandler::OnUwbSessionDeinitialize), + MakeLrpDispatchEntry(IOCTL_UWB_GET_SESSION_STATE, &UwbSimulatorDdiHandler::OnUwbGetSessionState), + MakeLrpDispatchEntry(IOCTL_UWB_SESSION_UPDATE_CONTROLLER_MULTICAST_LIST, &UwbSimulatorDdiHandler::OnUwbSessionUpdateControllerMulticastList), + MakeLrpDispatchEntry(IOCTL_UWB_START_RANGING_SESSION, &UwbSimulatorDdiHandler::OnUwbSessionStartRanging), + MakeLrpDispatchEntry(IOCTL_UWB_STOP_RANGING_SESSION, &UwbSimulatorDdiHandler::OnUwbSessionStopRanging), + MakeLrpDispatchEntry(IOCTL_UWB_GET_RANGING_COUNT, &UwbSimulatorDdiHandler::OnUwbSessionGetRangingCount), + MakeLrpDispatchEntry(IOCTL_UWB_NOTIFICATION, &UwbSimulatorDdiHandler::OnUwbNotification), + // GUID_DEVINTERFACE_UWB_SIMULATOR Handlers + MakeLrpDispatchEntry(IOCTL_UWB_DEVICE_SIM_GET_CAPABILITIES, &UwbSimulatorDdiHandler::OnUwbSimulatorCapabilities), + MakeLrpDispatchEntry(IOCTL_UWB_DEVICE_SIM_TRIGGER_SESSION_EVENT, &UwbSimulatorDdiHandler::OnUwbSimulatorTriggerSessionEvent), }; // IOCTL_UWB_DEVICE_RESET NTSTATUS -UwbSimulatorDdiHandlerLrp::OnUwbDeviceReset(WDFREQUEST request, std::span /*inputBuffer*/, std::span outputBuffer) +UwbSimulatorDdiHandler::OnUwbDeviceReset(WDFREQUEST request, std::span /*inputBuffer*/, std::span outputBuffer) { NTSTATUS status = STATUS_SUCCESS; @@ -83,7 +87,7 @@ UwbSimulatorDdiHandlerLrp::OnUwbDeviceReset(WDFREQUEST request, std::span /*inputBuffer*/, std::span outputBuffer) +UwbSimulatorDdiHandler::OnUwbGetDeviceInformation(WDFREQUEST request, std::span /*inputBuffer*/, std::span outputBuffer) { NTSTATUS status = STATUS_SUCCESS; @@ -103,7 +107,7 @@ UwbSimulatorDdiHandlerLrp::OnUwbGetDeviceInformation(WDFREQUEST request, std::sp // IOCTL_UWB_GET_DEVICE_CAPABILITIES NTSTATUS -UwbSimulatorDdiHandlerLrp::OnUwbGetDeviceCapabilities(WDFREQUEST request, std::span /*inputBuffer*/, std::span outputBuffer) +UwbSimulatorDdiHandler::OnUwbGetDeviceCapabilities(WDFREQUEST request, std::span /*inputBuffer*/, std::span outputBuffer) { NTSTATUS status = STATUS_SUCCESS; @@ -123,21 +127,21 @@ UwbSimulatorDdiHandlerLrp::OnUwbGetDeviceCapabilities(WDFREQUEST request, std::s // IOCTL_UWB_GET_DEVICE_CONFIG_PARAMS NTSTATUS -UwbSimulatorDdiHandlerLrp::OnUwbGetDeviceConfigurationParameters(WDFREQUEST /*request*/, std::span /*inputBuffer*/, std::span /*outputBuffer*/) +UwbSimulatorDdiHandler::OnUwbGetDeviceConfigurationParameters(WDFREQUEST /*request*/, std::span /*inputBuffer*/, std::span /*outputBuffer*/) { return STATUS_NOT_IMPLEMENTED; } // IOCTL_UWB_SET_DEVICE_CONFIG_PARAMS NTSTATUS -UwbSimulatorDdiHandlerLrp::OnUwbSetDeviceConfigurationParameters(WDFREQUEST /*request*/, std::span /*inputBuffer*/, std::span /*outputBuffer*/) +UwbSimulatorDdiHandler::OnUwbSetDeviceConfigurationParameters(WDFREQUEST /*request*/, std::span /*inputBuffer*/, std::span /*outputBuffer*/) { return STATUS_NOT_IMPLEMENTED; } // IOCTL_UWB_GET_APP_CONFIG_PARAMS NTSTATUS -UwbSimulatorDdiHandlerLrp::OnUwbGetApplicationConfigurationParameters(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer) +UwbSimulatorDdiHandler::OnUwbGetApplicationConfigurationParameters(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer) { NTSTATUS status = STATUS_SUCCESS; @@ -162,7 +166,7 @@ UwbSimulatorDdiHandlerLrp::OnUwbGetApplicationConfigurationParameters(WDFREQUEST // IOCTL_UWB_SET_APP_CONFIG_PARAMS NTSTATUS -UwbSimulatorDdiHandlerLrp::OnUwbSetApplicationConfigurationParameters(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer) +UwbSimulatorDdiHandler::OnUwbSetApplicationConfigurationParameters(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer) { NTSTATUS status = STATUS_SUCCESS; @@ -187,28 +191,28 @@ UwbSimulatorDdiHandlerLrp::OnUwbSetApplicationConfigurationParameters(WDFREQUEST // IOCTL_UWB_GET_SESSION_COUNT NTSTATUS -UwbSimulatorDdiHandlerLrp::OnUwbGetSessionCount(WDFREQUEST /*request*/, std::span /*inputBuffer*/, std::span /*outputBuffer*/) +UwbSimulatorDdiHandler::OnUwbGetSessionCount(WDFREQUEST /*request*/, std::span /*inputBuffer*/, std::span /*outputBuffer*/) { return STATUS_NOT_IMPLEMENTED; } // IOCTL_UWB_SESSION_INIT NTSTATUS -UwbSimulatorDdiHandlerLrp::OnUwbSessionInitialize(WDFREQUEST /*request*/, std::span /*inputBuffer*/, std::span /*outputBuffer*/) +UwbSimulatorDdiHandler::OnUwbSessionInitialize(WDFREQUEST /*request*/, std::span /*inputBuffer*/, std::span /*outputBuffer*/) { return STATUS_NOT_IMPLEMENTED; } // IOCTL_UWB_SESSION_DEINIT NTSTATUS -UwbSimulatorDdiHandlerLrp::OnUwbSessionDeinitialize(WDFREQUEST /*request*/, std::span /*inputBuffer*/, std::span /*outputBuffer*/) +UwbSimulatorDdiHandler::OnUwbSessionDeinitialize(WDFREQUEST /*request*/, std::span /*inputBuffer*/, std::span /*outputBuffer*/) { return STATUS_NOT_IMPLEMENTED; } // IOCTL_UWB_GET_SESSION_STATE NTSTATUS -UwbSimulatorDdiHandlerLrp::OnUwbGetSessionState(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer) +UwbSimulatorDdiHandler::OnUwbGetSessionState(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer) { NTSTATUS status = STATUS_SUCCESS; @@ -231,35 +235,35 @@ UwbSimulatorDdiHandlerLrp::OnUwbGetSessionState(WDFREQUEST request, std::span /*inputBuffer*/, std::span /*outputBuffer*/) +UwbSimulatorDdiHandler::OnUwbSessionUpdateControllerMulticastList(WDFREQUEST /*request*/, std::span /*inputBuffer*/, std::span /*outputBuffer*/) { return STATUS_NOT_IMPLEMENTED; } // IOCTL_UWB_START_RANGING_SESSION NTSTATUS -UwbSimulatorDdiHandlerLrp::OnUwbSessionStartRanging(WDFREQUEST /*request*/, std::span /*inputBuffer*/, std::span /*outputBuffer*/) +UwbSimulatorDdiHandler::OnUwbSessionStartRanging(WDFREQUEST /*request*/, std::span /*inputBuffer*/, std::span /*outputBuffer*/) { return STATUS_NOT_IMPLEMENTED; } // IOCTL_UWB_STOP_RANGING_SESSION NTSTATUS -UwbSimulatorDdiHandlerLrp::OnUwbSessionStopRanging(WDFREQUEST /*request*/, std::span /*inputBuffer*/, std::span /*outputBuffer*/) +UwbSimulatorDdiHandler::OnUwbSessionStopRanging(WDFREQUEST /*request*/, std::span /*inputBuffer*/, std::span /*outputBuffer*/) { return STATUS_NOT_IMPLEMENTED; } // IOCTL_UWB_GET_RANGING_COUNT NTSTATUS -UwbSimulatorDdiHandlerLrp::OnUwbSessionGetRangingCount(WDFREQUEST /*request*/, std::span /*inputBuffer*/, std::span /*outputBuffer*/) +UwbSimulatorDdiHandler::OnUwbSessionGetRangingCount(WDFREQUEST /*request*/, std::span /*inputBuffer*/, std::span /*outputBuffer*/) { return STATUS_NOT_IMPLEMENTED; } // IOCTL_UWB_NOTIFICATION NTSTATUS -UwbSimulatorDdiHandlerLrp::OnUwbNotification(WDFREQUEST request, std::span /*inputBuffer*/, std::span outputBuffer) +UwbSimulatorDdiHandler::OnUwbNotification(WDFREQUEST request, std::span /*inputBuffer*/, std::span outputBuffer) { UwbNotificationData uwbNotificationData{}; NTSTATUS status = m_callbacks->UwbNotification(uwbNotificationData); @@ -278,13 +282,49 @@ UwbSimulatorDdiHandlerLrp::OnUwbNotification(WDFREQUEST request, std::span()) +// IOCTL_UWB_DEVICE_SIM_GET_CAPABILITIES +NTSTATUS +UwbSimulatorDdiHandler::OnUwbSimulatorCapabilities(WDFREQUEST request, std::span /*inputBuffer*/, std::span outputBuffer) +{ + NTSTATUS status = STATUS_SUCCESS; + + // Execute callback. + auto uwbSimulatorCapabilities = m_callbacks->GetSimulatorCapabilities(); + + // Copy output value to output buffer. + auto &outputValue = *reinterpret_cast(std::data(outputBuffer)); + outputValue = uwbSimulatorCapabilities; + + // Complete the request. + WdfRequestCompleteWithInformation(request, status, sizeof outputValue); + + return status; +} + +// IOCTL_UWB_DEVICE_SIM_TRIGGER_SESSION_EVENT +NTSTATUS +UwbSimulatorDdiHandler::OnUwbSimulatorTriggerSessionEvent(WDFREQUEST request, std::span inputBuffer, std::span /*outputBuffer*/) +{ + NTSTATUS status = STATUS_SUCCESS; + + auto &triggerSessionEventArgs = *reinterpret_cast(std::data(inputBuffer)); + + // Execute callback. + m_callbacks->TriggerSessionEvent(triggerSessionEventArgs); + + // Complete the request. + WdfRequestComplete(request, STATUS_SUCCESS); + + return status; +} + +UwbSimulatorDdiHandler::UwbSimulatorDdiHandler() : + m_callbacks(std::make_unique()) { } -std::optional> -UwbSimulatorDdiHandlerLrp::TryGetDispatchEntry(ULONG ioControlCode) +std::optional> +UwbSimulatorDdiHandler::TryGetDispatchEntry(ULONG ioControlCode) { const auto dispatchEntryIt = std::ranges::find_if(Dispatch, [&](const auto &dispatchEntry) { return (dispatchEntry.IoControlCode == ioControlCode); @@ -292,11 +332,11 @@ UwbSimulatorDdiHandlerLrp::TryGetDispatchEntry(ULONG ioControlCode) return (dispatchEntryIt != std::end(Dispatch)) ? *dispatchEntryIt - : std::optional>(std::nullopt); + : std::optional>(std::nullopt); } bool -UwbSimulatorDdiHandlerLrp::HandlesIoControlCode(ULONG ioControlCode) +UwbSimulatorDdiHandler::HandlesIoControlCode(ULONG ioControlCode) { return std::ranges::any_of(Dispatch, [&](const auto &dispatchEntry) { return (dispatchEntry.IoControlCode == ioControlCode); @@ -304,7 +344,7 @@ UwbSimulatorDdiHandlerLrp::HandlesIoControlCode(ULONG ioControlCode) } NTSTATUS -UwbSimulatorDdiHandlerLrp::ValidateRequest(WDFREQUEST /* request */, ULONG ioControlCode, std::size_t inputBufferLength, std::size_t outputBufferLength) +UwbSimulatorDdiHandler::ValidateRequest(WDFREQUEST /* request */, ULONG ioControlCode, std::size_t inputBufferLength, std::size_t outputBufferLength) { const auto dispatchEntry = TryGetDispatchEntry(ioControlCode); NTSTATUS status = dispatchEntry.has_value() @@ -314,7 +354,7 @@ UwbSimulatorDdiHandlerLrp::ValidateRequest(WDFREQUEST /* request */, ULONG ioCon } NTSTATUS -UwbSimulatorDdiHandlerLrp::HandleRequest(WDFREQUEST request, ULONG ioControlCode, std::span inputBuffer, std::span outputBuffer) +UwbSimulatorDdiHandler::HandleRequest(WDFREQUEST request, ULONG ioControlCode, std::span inputBuffer, std::span outputBuffer) { auto dispatchEntry = TryGetDispatchEntry(ioControlCode); if (!dispatchEntry.has_value()) { diff --git a/windows/drivers/uwb/simulator/UwbSimulatorDdiHandlerLrp.hxx b/windows/drivers/uwb/simulator/UwbSimulatorDdiHandlerLrp.hxx deleted file mode 100644 index 767b2601..00000000 --- a/windows/drivers/uwb/simulator/UwbSimulatorDdiHandlerLrp.hxx +++ /dev/null @@ -1,120 +0,0 @@ - -#ifndef UWB_SIMULATOR_DDI_HANDLER_LRP_HXX -#define UWB_SIMULATOR_DDI_HANDLER_LRP_HXX - -#include -#include -#include - -#include - -#include - -#include "UwbSimulatorDdiCallbacksLrp.hxx" -#include "UwbSimulatorDdiHandler.hxx" -#include "UwbSimulatorDispatchEntry.hxx" - -namespace windows::devices::uwb::simulator -{ -class UwbSimulatorDdiHandlerLrp : - public UwbSimulatorDdiHandler -{ -public: - UwbSimulatorDdiHandlerLrp(); - - /** - * @brief Indicates whether the specified i/o control code is handled by - * this handler. - * - * @param ioControlCode The i/o control code to check. - * @return true - * @return false - */ - bool - HandlesIoControlCode(ULONG ioControlCode) override; - - /** - * @brief - * - * @param request - * @param ioControlCode - * @param inputBufferLength - * @param outputBufferLength - * @return NTSTATUS - */ - NTSTATUS - ValidateRequest(WDFREQUEST request, ULONG ioControlCode, std::size_t inputBufferLength, std::size_t outputBufferLength) override; - - /** - * @brief - * - * @param request - * @param ioControlCode - * @param inputBuffer - * @param outputBuffer - * @return NTSTATUS - */ - NTSTATUS - HandleRequest(WDFREQUEST request, ULONG ioControlCode, std::span inputBuffer, std::span outputBuffer) override; - -private: - NTSTATUS - OnUwbDeviceReset(WDFREQUEST, std::span, std::span); - - NTSTATUS - OnUwbGetDeviceInformation(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); - - NTSTATUS - OnUwbGetDeviceCapabilities(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); - - NTSTATUS - OnUwbGetDeviceConfigurationParameters(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); - - NTSTATUS - OnUwbSetDeviceConfigurationParameters(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); - - NTSTATUS - OnUwbGetApplicationConfigurationParameters(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); - - NTSTATUS - OnUwbSetApplicationConfigurationParameters(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); - - NTSTATUS - OnUwbGetSessionCount(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); - - NTSTATUS - OnUwbSessionInitialize(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); - - NTSTATUS - OnUwbSessionDeinitialize(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); - - NTSTATUS - OnUwbGetSessionState(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); - - NTSTATUS - OnUwbSessionUpdateControllerMulticastList(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); - - NTSTATUS - OnUwbSessionStartRanging(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); - - NTSTATUS - OnUwbSessionStopRanging(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); - - NTSTATUS - OnUwbSessionGetRangingCount(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); - - NTSTATUS - OnUwbNotification(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); - - std::optional> - TryGetDispatchEntry(ULONG ioControlCode); - -private: - static const std::initializer_list> Dispatch; - -private: - std::unique_ptr m_callbacks; -}; -} // namespace windows::devices::uwb::simulator - -#endif // UWB_SIMULATOR_DDI_HANDLER_LRP_HXX diff --git a/windows/drivers/uwb/simulator/UwbSimulatorDdiHandlerSimulator.cxx b/windows/drivers/uwb/simulator/UwbSimulatorDdiHandlerSimulator.cxx deleted file mode 100644 index 083d15e3..00000000 --- a/windows/drivers/uwb/simulator/UwbSimulatorDdiHandlerSimulator.cxx +++ /dev/null @@ -1,133 +0,0 @@ - -#include -#include -#include -#include -#include - -#include - -#include "UwbSimulatorDdi.h" -#include "UwbSimulatorDdiCallbacksSimulatorImpl.hxx" -#include "UwbSimulatorDdiHandlerSimulator.hxx" - -using namespace windows::devices::uwb::simulator; - -/** - * @brief Template function alias which partially specializes the - * UwbSimulatorDispatchEntry template with ClassT = UwbSimulatorDdiHandlerLrp. - * This reduces some typing. - * - * It's not possible to create an alias to a templated function, however, it is - * posssible to create an alias of a function pointer variable. Hence, this - * template alias is defined with a pointer (`*MakeLrpDispatchEntry') and - * assigned the address of MakeDispatchEntry. - * - * @tparam The type of the IOCTL input that's accepted. - * @tparam The type of the IOCTL ouput that's accepted. - */ -template < - typename InputT = Unrestricted, - typename OutputT = Unrestricted> -UwbSimulatorDispatchEntry (*MakeLrpDispatchEntry)(ULONG, typename UwbSimulatorDispatchEntry::HandlerFuncT) = &MakeDispatchEntry; - -/** - * @brief Dispatch table for the LRP DDI driver IOCTLs. - * - * This defines the expected input and output buffer sizes and the corresponding - * member function that will handle the IOCTL. - */ -const std::initializer_list> UwbSimulatorDdiHandlerSimulator::Dispatch{ - MakeLrpDispatchEntry(IOCTL_UWB_DEVICE_SIM_GET_CAPABILITIES, &UwbSimulatorDdiHandlerSimulator::OnUwbSimulatorCapabilities), - MakeLrpDispatchEntry(IOCTL_UWB_DEVICE_SIM_TRIGGER_SESSION_EVENT, &UwbSimulatorDdiHandlerSimulator::OnUwbSimulatorTriggerSessionEvent), -}; - -// IOCTL_UWB_DEVICE_RESET -NTSTATUS -UwbSimulatorDdiHandlerSimulator::OnUwbSimulatorCapabilities(WDFREQUEST /*request*/, std::span /*inputBuffer*/, std::span /*outputBuffer*/) -{ - 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 -UwbSimulatorDdiHandlerSimulator::OnUwbSimulatorTriggerSessionEvent(WDFREQUEST /*request*/, std::span /*inputBuffer*/, std::span /*outputBuffer*/) -{ - NTSTATUS status = STATUS_SUCCESS; - - //// Execute callback. - // UwbDeviceInformation 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; -} - -UwbSimulatorDdiHandlerSimulator::UwbSimulatorDdiHandlerSimulator() : - m_callbacks(std::make_unique()) -{ -} - -std::optional> -UwbSimulatorDdiHandlerSimulator::TryGetDispatchEntry(ULONG ioControlCode) -{ - const auto dispatchEntryIt = std::ranges::find_if(Dispatch, [&](const auto &dispatchEntry) { - return (dispatchEntry.IoControlCode == ioControlCode); - }); - - return (dispatchEntryIt != std::end(Dispatch)) - ? *dispatchEntryIt - : std::optional>(std::nullopt); -} - -bool -UwbSimulatorDdiHandlerSimulator::HandlesIoControlCode(ULONG ioControlCode) -{ - return std::ranges::any_of(Dispatch, [&](const auto &dispatchEntry) { - return (dispatchEntry.IoControlCode == ioControlCode); - }); -} - -NTSTATUS -UwbSimulatorDdiHandlerSimulator::ValidateRequest(WDFREQUEST /* request */, ULONG ioControlCode, std::size_t inputBufferLength, std::size_t outputBufferLength) -{ - const auto dispatchEntry = TryGetDispatchEntry(ioControlCode); - NTSTATUS status = dispatchEntry.has_value() - ? dispatchEntry->GetRequestValidityStatus(inputBufferLength, outputBufferLength) - : STATUS_NOT_SUPPORTED; - return status; -} - -NTSTATUS -UwbSimulatorDdiHandlerSimulator::HandleRequest(WDFREQUEST request, ULONG ioControlCode, std::span inputBuffer, std::span outputBuffer) -{ - 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/UwbSimulatorDdiHandlerSimulator.hxx b/windows/drivers/uwb/simulator/UwbSimulatorDdiHandlerSimulator.hxx deleted file mode 100644 index d7770e46..00000000 --- a/windows/drivers/uwb/simulator/UwbSimulatorDdiHandlerSimulator.hxx +++ /dev/null @@ -1,78 +0,0 @@ - -#ifndef UWB_SIMULATOR_DDI_HANDLER_SIMULATOR_HXX -#define UWB_SIMULATOR_DDI_HANDLER_SIMULATOR_HXX - -#include -#include -#include - -#include - -#include - -#include "UwbSimulatorDdiCallbacksSimulator.hxx" -#include "UwbSimulatorDdiHandler.hxx" -#include "UwbSimulatorDispatchEntry.hxx" - -namespace windows::devices::uwb::simulator -{ -class UwbSimulatorDdiHandlerSimulator : - public UwbSimulatorDdiHandler -{ -public: - UwbSimulatorDdiHandlerSimulator(); - - /** - * @brief Indicates whether the specified i/o control code is handled by - * this handler. - * - * @param ioControlCode The i/o control code to check. - * @return true - * @return false - */ - bool - HandlesIoControlCode(ULONG ioControlCode) override; - - /** - * @brief - * - * @param request - * @param ioControlCode - * @param inputBufferLength - * @param outputBufferLength - * @return NTSTATUS - */ - NTSTATUS - ValidateRequest(WDFREQUEST request, ULONG ioControlCode, std::size_t inputBufferLength, std::size_t outputBufferLength) override; - - /** - * @brief - * - * @param request - * @param ioControlCode - * @param inputBuffer - * @param outputBuffer - * @return NTSTATUS - */ - NTSTATUS - HandleRequest(WDFREQUEST request, ULONG ioControlCode, std::span inputBuffer, std::span outputBuffer) override; - -private: - NTSTATUS - OnUwbSimulatorCapabilities(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); - - NTSTATUS - OnUwbSimulatorTriggerSessionEvent(WDFREQUEST request, std::span inputBuffer, std::span outputBuffer); - - std::optional> - TryGetDispatchEntry(ULONG ioControlCode); - -private: - static const std::initializer_list> Dispatch; - -private: - std::unique_ptr m_callbacks; -}; -} // namespace windows::devices::uwb::simulator - -#endif // UWB_SIMULATOR_DDI_HANDLER_SIMULATOR_HXX diff --git a/windows/drivers/uwb/simulator/UwbSimulatorDeviceFile.hxx b/windows/drivers/uwb/simulator/UwbSimulatorDeviceFile.hxx index a5b60aa9..5ba0e81c 100644 --- a/windows/drivers/uwb/simulator/UwbSimulatorDeviceFile.hxx +++ b/windows/drivers/uwb/simulator/UwbSimulatorDeviceFile.hxx @@ -9,7 +9,7 @@ #include -#include "UwbSimulatorDdiHandler.hxx" +#include "IUwbSimulatorDdiHandler.hxx" /** * @brief Device driver open file abstraction. @@ -21,10 +21,10 @@ public: /** * @brief Device i/o control handler function. - * + * * This is invoked when the driver receives an i/o control request on the * file handle associated with this instance. - * + * * @param request The WDF driver request. * @param ioControlCode The i/o control code for the request. * @param inputBufferLength The input buffer length. @@ -55,7 +55,7 @@ private: private: WDFFILEOBJECT m_wdfFile; - std::vector> m_ddiHandlers{}; + std::vector> m_ddiHandlers{}; }; WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(UwbSimulatorDeviceFile, GetUwbSimulatorFile); diff --git a/windows/drivers/uwb/simulator/UwbSimulatorIoQueue.hxx b/windows/drivers/uwb/simulator/UwbSimulatorIoQueue.hxx index 5c382dbd..cf9bd11c 100644 --- a/windows/drivers/uwb/simulator/UwbSimulatorIoQueue.hxx +++ b/windows/drivers/uwb/simulator/UwbSimulatorIoQueue.hxx @@ -15,7 +15,7 @@ #include -#include "UwbSimulatorDdiCallbacksLrp.hxx" +#include "IUwbSimulatorDdiCallbacksLrp.hxx" /** * @brief Per-queue context object. @@ -39,9 +39,9 @@ public: Initialize(); /** - * @brief - * - * @return NTSTATUS + * @brief + * + * @return NTSTATUS */ NTSTATUS Uninitialize(); diff --git a/windows/drivers/uwb/simulator/UwbSimulatorSession.cxx b/windows/drivers/uwb/simulator/UwbSimulatorSession.cxx new file mode 100644 index 00000000..9a0116bc --- /dev/null +++ b/windows/drivers/uwb/simulator/UwbSimulatorSession.cxx @@ -0,0 +1,94 @@ + +#include "UwbSimulatorSession.hxx" + +using namespace windows::devices::uwb::simulator; +using namespace uwb::protocol::fira; + +UwbSimulatorSession::UwbSimulatorSession(uint32_t sessionId, UwbSessionType sessionType) : + IUwbSimulatorSession{ + .Id = sessionId, + .Type = sessionType, + } +{} + +void +UwbSimulatorSession::RandomRangingMeasurementGenerationStart(std::function onMeasurementEvent) +{ + if (m_randomRangingMeasurementsEnabled) { + return; + } + + m_randomRangingMeasurementsEnabled = true; + m_randomRangingMeasurementsThread = std::jthread([this, onMeasurementEvent = std::move(onMeasurementEvent)](std::stop_token stopToken) { + RandomRangingMeasurementGenerator(std::move(onMeasurementEvent), stopToken); + }); +} + +void +UwbSimulatorSession::RandomRangingMeasurementGenerationStop() +{ + if (!m_randomRangingMeasurementsEnabled) { + return; + } + + m_randomRangingMeasurementsEnabled = false; + m_randomRangingMeasurementsThread.request_stop(); +} + +UwbRangingMeasurement +UwbSimulatorSession::GenerateRandomRangingMeasurement() +{ + // TODO: some of the below values need to be randomized, others need to be sampled from a fixed set of values + UwbRangingMeasurement rangingMeasurement{ + .SlotIndex = 1, + .Distance = 0x0123, + .Status = UwbStatusGeneric::Ok, + .PeerMacAddress = ::uwb::UwbMacAddress::Random<::uwb::UwbMacAddressType::Short>(), + .LineOfSightIndicator = UwbLineOfSightIndicator::LineOfSight, + .AoAAzimuth = { + .Result = 0xAAAAU, + }, + .AoAElevation = { + .Result = 0xBBBBU, + }, + .AoaDestinationAzimuth = { + .Result = 0xCCCCU, + }, + .AoaDestinationElevation = { + .Result = 0xDDDDU, + }, + }; + + return rangingMeasurement; +} + +UwbRangingData +UwbSimulatorSession::GenerateNextRangingData() +{ + // TODO: number of random ranging measurements need to be bounded by the number of peers involved in the session. + UwbRangingData rangingData{ + .SequenceNumber = m_sequenceNumber++, + .SessionId = Id, + .CurrentRangingInterval = static_cast(m_randomRangingMeasurementsDuration.count()), + .RangingMeasurementType = UwbRangingMeasurementType::TwoWay, + .RangingMeasurements = { + GenerateRandomRangingMeasurement(), + GenerateRandomRangingMeasurement(), + GenerateRandomRangingMeasurement(), + }, + }; + + return rangingData; +} + +void +UwbSimulatorSession::RandomRangingMeasurementGenerator(std::function onMeasurementEvent, std::stop_token stopToken) +{ + while (!stopToken.stop_requested()) { + std::this_thread::sleep_for(m_randomRangingMeasurementsDuration); + auto rangingData = GenerateNextRangingData(); + onMeasurementEvent(std::move(rangingData)); + } + + m_sequenceNumber = 0; +} diff --git a/windows/drivers/uwb/simulator/UwbSimulatorSession.hxx b/windows/drivers/uwb/simulator/UwbSimulatorSession.hxx index 3f85f07e..93feb800 100644 --- a/windows/drivers/uwb/simulator/UwbSimulatorSession.hxx +++ b/windows/drivers/uwb/simulator/UwbSimulatorSession.hxx @@ -2,25 +2,81 @@ #ifndef UWB_SIMULATOR_SESSION_HXX #define UWB_SIMULATOR_SESSION_HXX -#include -#include -#include +#include +#include -#include #include -#include + +#include "IUwbSimulatorSession.hxx" namespace windows::devices::uwb::simulator { -struct UwbSimulatorSession +enum class RandomMeasurementGeneration { + Disable, + Enable, +}; + +using namespace std::chrono_literals; + +using ::uwb::protocol::fira::UwbNotificationData; +using ::uwb::protocol::fira::UwbRangingData; +using ::uwb::protocol::fira::UwbRangingMeasurement; + +struct UwbSimulatorSession : + public IUwbSimulatorSession { - uint32_t Id; - UwbSessionType Type{ UwbSessionType::RangingSession }; - UwbSessionState State{ UwbSessionState::Deinitialized }; - uint32_t Sequence{ 0 }; - std::unordered_set Controlees; - std::vector> ApplicationConfigurationParameters; + UwbSimulatorSession(uint32_t sessionId, UwbSessionType sessionType); + + /** + * @brief Start generation of random uwb ranging data for this session. + * + * @param onMeasurementEvent The callback to invoke with the random uwb ranging data. + */ + void + RandomRangingMeasurementGenerationStart(std::function onMeasurementEvent); + + /** + *@brief Stop generation of random uwb ranging measurements for this session. + */ + void + RandomRangingMeasurementGenerationStop(); + +private: + /** + * @brief Thread function which generates randomg uwb ranging measurements. + * + * The thread generates 1 UwbRangingData (encoded within) + * + * @param onMeasurementEvent The callback to invoke with each ranging data set. + * @param stopToken + */ + void + RandomRangingMeasurementGenerator(std::function onMeasurementEvent, std::stop_token stopToken); + + /** + * @brief Generate a random UwbRangingMeasurement. + * + * @return UwbRangingMeasurement + */ + UwbRangingMeasurement + GenerateRandomRangingMeasurement(); + + /** + * @brief Generate the next set of uwb ranging data. + * + * @return UwbRangingData + */ + UwbRangingData + GenerateNextRangingData(); + +private: + static constexpr auto DefaultRandomRangingMeasurementsDuration = 1000ms; + + bool m_randomRangingMeasurementsEnabled{ false }; + std::jthread m_randomRangingMeasurementsThread; + std::chrono::milliseconds m_randomRangingMeasurementsDuration{ DefaultRandomRangingMeasurementsDuration }; + uint32_t m_sequenceNumber{ 0 }; }; } // namespace windows::devices::uwb::simulator -#endif // UWB_SIMULATOR_SESSION_HXX \ No newline at end of file +#endif // UWB_SIMULATOR_SESSION_HXX diff --git a/windows/drivers/uwb/simulator/include/UwbSimulatorDdi.h b/windows/drivers/uwb/simulator/include/UwbSimulatorDdi.h index ed5170a9..9b85f63c 100644 --- a/windows/drivers/uwb/simulator/include/UwbSimulatorDdi.h +++ b/windows/drivers/uwb/simulator/include/UwbSimulatorDdi.h @@ -54,6 +54,7 @@ enum UwbSimulatorSessionEventAction struct UwbSimulatorTriggerSessionEventArgs { + uint32_t SessionId; UwbSimulatorSessionEventAction Action; };