diff options
| author | Sanjeev Reddy <[email protected]> | 2019-02-06 13:12:11 -0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2019-02-06 13:12:11 -0800 |
| commit | 27302e1d522bc16e1cc18232602f7eca1b79db0f (patch) | |
| tree | 1035100a803e4e52abbda93288091bb50f4f5073 /gnss | |
| parent | 46da8a0d4f0de180dd15b6ca088e095b5e2c0b96 (diff) | |
| parent | 39d39e7485faddf601d51c897863ff2f876e391e (diff) | |
Merge pull request #1 from Microsoft/master
Updating to latest
Diffstat (limited to 'gnss')
| -rw-r--r-- | gnss/GnssUmdfSampleDriver.wprp | 32 | ||||
| -rw-r--r-- | gnss/ReadMe.md | 97 | ||||
| -rw-r--r-- | gnss/gnss.yaml | 10 | ||||
| -rw-r--r-- | gnss/gnssUmdf.sln | 59 | ||||
| -rw-r--r-- | gnss/gnssUmdf/Defaults.h | 59 | ||||
| -rw-r--r-- | gnss/gnssUmdf/Device.cpp | 163 | ||||
| -rw-r--r-- | gnss/gnssUmdf/Device.h | 44 | ||||
| -rw-r--r-- | gnss/gnssUmdf/Driver.cpp | 107 | ||||
| -rw-r--r-- | gnss/gnssUmdf/Driver.h | 22 | ||||
| -rw-r--r-- | gnss/gnssUmdf/FixHandler.cpp | 228 | ||||
| -rw-r--r-- | gnss/gnssUmdf/FixHandler.h | 39 | ||||
| -rw-r--r-- | gnss/gnssUmdf/FixSession.cpp | 512 | ||||
| -rw-r--r-- | gnss/gnssUmdf/FixSession.h | 60 | ||||
| -rw-r--r-- | gnss/gnssUmdf/Queue.cpp | 482 | ||||
| -rw-r--r-- | gnss/gnssUmdf/Queue.h | 78 | ||||
| -rw-r--r-- | gnss/gnssUmdf/Trace.h | 64 | ||||
| -rw-r--r-- | gnss/gnssUmdf/gnssUmdf.inf | bin | 0 -> 3592 bytes | |||
| -rw-r--r-- | gnss/gnssUmdf/gnssUmdf.vcxproj | 301 | ||||
| -rw-r--r-- | gnss/gnssUmdf/gnssUmdf.vcxproj.filters | 69 | ||||
| -rw-r--r-- | gnss/gnssUmdf/precomp.h | 29 |
20 files changed, 2455 insertions, 0 deletions
diff --git a/gnss/GnssUmdfSampleDriver.wprp b/gnss/GnssUmdfSampleDriver.wprp new file mode 100644 index 00000000..7bb78452 --- /dev/null +++ b/gnss/GnssUmdfSampleDriver.wprp @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8" standalone='yes'?> + +<WindowsPerformanceRecorder Version="1.0" Author="Location Dev" Team="Location Dev" Comments="ETW profiles" Company="Microsoft Corporation" Copyright="Microsoft Corporation"> + <Profiles> + <!-- Event Collectors --> + <EventCollector Id="EventCollector_SampleGNSS" Name="SampleGNSS Category Event Collector" Private="false" ProcessPrivate="false" Secure="false" Realtime="false"> + <BufferSize Value="128"/> + <Buffers Value="40"/> + <MaximumFileSize Value="5" FileMode="Circular"/> + <FileMax Value="3"/> + </EventCollector> + + <!-- Umdf Gnss Sample Driver providers --> + <EventProvider Id="GnssUmdfTraceGuid" Name="CEB3BF01-80E4-4DC7-B3BF-F6B5279EB8C4" Level="5"> + <Keywords> + <Keyword Value="0xFFFFFFFF"/> <!-- Provider is enabled with these keywords throughout the tracing session. --> + </Keywords> + </EventProvider> + + <!-- Profiles --> + <Profile Id="SampleGNSSCategory.Verbose.File" LoggingMode="File" Name="SampleGNSSCategory" DetailLevel="Verbose" Description="Sample GNSS category profile"> + <Collectors> + <EventCollectorId Value="EventCollector_SampleGNSS"> + <EventProviders> + <EventProviderId Value="GnssUmdfTraceGuid"/> + </EventProviders> + </EventCollectorId> + </Collectors> + </Profile> + </Profiles> + +</WindowsPerformanceRecorder> diff --git a/gnss/ReadMe.md b/gnss/ReadMe.md new file mode 100644 index 00000000..deaca7a6 --- /dev/null +++ b/gnss/ReadMe.md @@ -0,0 +1,97 @@ +<!--- + name: GPS/GNSS UMDF Sample Driver (UMDF Version 2) + platform: UMDF2 + language: cpp + category: GPS/GNSS + description: Provides base sample driver that IHVs and partners can use to extend to build their custom Windows GPS/GNSS drivers + samplefwlink: https://go.microsoft.com/fwlink/?linkid=2045369 +---> + + +GNSS UMDF Sample Driver (UMDF Version 2) +============================================================================== + +# Overview + +## What is covered? + +* This is a sample that adheres to GNSS driver design for Windows 10 with this MSDN link: https://docs.microsoft.com/en-us/windows-hardware/drivers/gnss/gnss-driver-design-guide-for-windows-10 +* Serves as base sample driver that IHVs and partners can use as a template and guidance to extend to build their custom Windows GNSS drivers. +* Follows the WDF guidelines and best practices around PnP device arrival/removal, power management and driver installation/uninstallation. +* Supports the GNSS DDI mandatory requirements. +* This driver successfully passes HLK tests and WDF tests provided by Visual studio. + +## What is not covered? + +* This sample currently doesn't support Geofence, SUPL, and AGNSS, as this is not mandatory GNSS DDI functionality. +* SUPL and AGNSS are mandatory only if required by mobile operator, and the sample does not support them currently. +* Not a production driver. + +## What Partner needs to do? + +* Customer can install WDK and run Location HLK tests to validate their driver. All test cases should be either pass or skip without failure. +* Partner owns the following: + - Installing the driver. + - Adding certificate and driver signing. + - Updating manufacturer name driver version etc. (the code has comments to update). +* The GNSS sample code has "FIX ME" comments. Partner should update them accordingly. + + +# Design + +* The sample demonstrates a very basic software only driver that meets the minimum requirements from the GNSS DDI. +* The sample currently always returns a fake hardcoded location. Driver developers can extend this to fetch fake positions from a file or inject through a custom IOCTL or instead implement getting real positions from GNSS hardware. +* Driver developer can extend this to pull the fake positions from a file or through custom IOCTLs if needed. + + +# Trace Logging + +* The sample code provides Trace logging WPRP file. +* To capture trace log, copy GnssUmdfSampleDriver.wprp in the solution folder into the device under test. On command line (MyLog.etl is an example file name below): + ```sh + wpr -start GnssUmdfSampleDriver.wprp -filemode + <Reproduce the issue> + wpr -stop MyLog.etl + ``` +* Inspect MyLog.etl with trace file analyzer. Note that corresponding PDB file is needed to decode the logging information. + + +# Test Plan + +Customer should validate their driver after customizing it. + +#### Test method 1 + +* This tests WDF fundamental functionality (PnP etc.), rather than Location-specific features. +* Run Visual studio built-in run-time test for WDF. +* General information: https://docs.microsoft.com/en-us/windows-hardware/drivers/develop/testing-a-driver-at-runtime +* Expected result / Pass criteria: Pass rate 100% + +#### Test method 2 + +* This tests Location-specific functionality (Getting fix etc.). +* Run HLK tests with existing and standard GNSS driver tests. +* General information: https://docs.microsoft.com/en-us/windows-hardware/test/hlk/windows-hardware-lab-kit +* Run "TE.exe GNSSDriverTest.dll". +* Expected result / Pass criteria: Pass rate 100% +* Note that this sample does not support AGNSS, SUPL and Geofencing currently. Based on the capability of driver, HLK skips them automatically. + +#### Test method 3 + +* This tests from Windows Geolocation API (https://docs.microsoft.com/en-us/windows/desktop/locationapi/windows-location-api-portal) layer on real apps. +* Get current location by clicking on "Show my location" from the In-box Windows Maps app. +* Run tracking scenario from Geolocation Sample app (Download from https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/Geolocation). +* Get current location by clicking on "Start" from GPS Satellite app in Windows Store. + + +# Resources + +* GNSS DDI reference + - https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/gnssdriver/index +* Getting started with Windows drivers + - https://docs.microsoft.com/en-us/windows-hardware/drivers/gettingstarted/ +* Windows Driver Kit documentation + - https://docs.microsoft.com/en-us/windows-hardware/drivers/ +* NMEA format documentation + - http://navspark.mybigcommerce.com/content/NMEA_Format_v0.1.pdf +
\ No newline at end of file diff --git a/gnss/gnss.yaml b/gnss/gnss.yaml new file mode 100644 index 00000000..e53b2045 --- /dev/null +++ b/gnss/gnss.yaml @@ -0,0 +1,10 @@ +### YamlMime:Sample +sample: +- name: GPS/GNSS UMDF V2 Device Driver Sample + description: Demonstrates how to write a device driver that IHVs and partners can use to extend to build their custom drivers + generateZip: true + author: windows-driver-samples + languages: + - cpp + technologies: + - windows diff --git a/gnss/gnssUmdf.sln b/gnss/gnssUmdf.sln new file mode 100644 index 00000000..46b81091 --- /dev/null +++ b/gnss/gnssUmdf.sln @@ -0,0 +1,59 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27703.2042 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gnssUmdf", "gnssUmdf\gnssUmdf.vcxproj", "{AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{79D3FD2A-EEAE-4C86-90AF-39B7FFD6D27D}" + ProjectSection(SolutionItems) = preProject + gnss.yaml = gnss.yaml + GnssUmdfSampleDriver.wprp = GnssUmdfSampleDriver.wprp + ReadMe.md = ReadMe.md + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM = Debug|ARM + Debug|ARM64 = Debug|ARM64 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|ARM = Release|ARM + Release|ARM64 = Release|ARM64 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Debug|ARM.ActiveCfg = Debug|ARM + {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Debug|ARM.Build.0 = Debug|ARM + {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Debug|ARM.Deploy.0 = Debug|ARM + {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Debug|ARM64.Build.0 = Debug|ARM64 + {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Debug|x64.ActiveCfg = Debug|x64 + {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Debug|x64.Build.0 = Debug|x64 + {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Debug|x64.Deploy.0 = Debug|x64 + {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Debug|x86.ActiveCfg = Debug|Win32 + {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Debug|x86.Build.0 = Debug|Win32 + {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Debug|x86.Deploy.0 = Debug|Win32 + {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Release|ARM.ActiveCfg = Release|ARM + {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Release|ARM.Build.0 = Release|ARM + {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Release|ARM.Deploy.0 = Release|ARM + {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Release|ARM64.ActiveCfg = Release|ARM64 + {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Release|ARM64.Build.0 = Release|ARM64 + {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Release|ARM64.Deploy.0 = Release|ARM64 + {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Release|x64.ActiveCfg = Release|x64 + {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Release|x64.Build.0 = Release|x64 + {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Release|x64.Deploy.0 = Release|x64 + {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Release|x86.ActiveCfg = Release|Win32 + {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Release|x86.Build.0 = Release|Win32 + {AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}.Release|x86.Deploy.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C0D84930-F293-4CFC-ACFB-2A71C4CADDFD} + SolutionGuid = {E7531486-DB0B-43B1-AC4A-AFDE26BDED47} + EndGlobalSection +EndGlobal diff --git a/gnss/gnssUmdf/Defaults.h b/gnss/gnssUmdf/Defaults.h new file mode 100644 index 00000000..bf78238e --- /dev/null +++ b/gnss/gnssUmdf/Defaults.h @@ -0,0 +1,59 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + defaults.h + +Abstract: + + This module contains the defaults used within the Umdf Gnss Driver. + +Environment: + + driver and application + +--*/ + +#pragma once + +#define GNSS_DRIVER_DDK_VERSION GNSS_DRIVER_VERSION_4 +#define INVALID_SESSION_ID (0xFFFFFFFF) +#define DEFAULT_FIX_INTERVAL_SECONDS 1 + +static const double c_MaximumLatitude = 90.0; +static const double c_MinimumLatitude = -90.0; +static const double c_MaximumLongitude = 180.0; +static const double c_MinimumLongitude = -180.0; + +#define INIT_POD_GNSS_STRUCT(pName) \ + memset((pName), 0, sizeof(*(pName))); \ + (pName)->Size = sizeof(*(pName)); \ + (pName)->Version = GNSS_DRIVER_DDK_VERSION + +const GNSS_FIXDATA g_DefaultGnssFixData = +{ + sizeof(GNSS_FIXDATA), + GNSS_DRIVER_DDK_VERSION, + INVALID_SESSION_ID, + { 0xCD700000, 0x1D48908 }, // an example date/time, Dec/01/2018 + TRUE, + STATUS_SUCCESS, + GNSS_FIXDETAIL_BASIC | GNSS_FIXDETAIL_ACCURACY, + { + sizeof(GNSS_FIXDATA_BASIC), + GNSS_DRIVER_DDK_VERSION, + // Location: Mount Rainier National Park + 46.852273, + -121.757468, + 0.0, + 0.0, + 0.0 + }, + { + sizeof(GNSS_FIXDATA_ACCURACY), + GNSS_DRIVER_DDK_VERSION, + 10 // Meters accuracy + } +}; diff --git a/gnss/gnssUmdf/Device.cpp b/gnss/gnssUmdf/Device.cpp new file mode 100644 index 00000000..905b3e94 --- /dev/null +++ b/gnss/gnssUmdf/Device.cpp @@ -0,0 +1,163 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + device.c + +Abstract: + + This file contains the device entry points and callbacks. + +Environment: + + Windows User-Mode Driver Framework + +--*/ + +#include "precomp.h" +#include "Trace.h" +#include "Defaults.h" +#include "Device.h" +#include "FixSession.h" +#include "FixHandler.h" +#include "Queue.h" + +#include "Device.tmh" + + +CDevice::CDevice( + _In_ WDFDEVICE Device +) : + _Device(Device), + _Queue(nullptr) +{ +} + +CDevice::~CDevice() +{ + if (_Queue != nullptr) + { + _Queue = nullptr; + } +} + +CQueue* +CDevice::GetQueue() +{ + return _Queue; +} + +NTSTATUS +CDevice::OnDeviceAdd( + _In_ WDFDRIVER /*Driver*/, + _Inout_ PWDFDEVICE_INIT DeviceInit +) +{ + NTSTATUS status = STATUS_SUCCESS; + + WDF_PNPPOWER_EVENT_CALLBACKS powerCallbacks; + WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&powerCallbacks); + + powerCallbacks.EvtDeviceD0Entry = CDevice::OnD0Entry; + powerCallbacks.EvtDeviceD0Exit = CDevice::OnD0Exit; + + WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &powerCallbacks); + + WDF_OBJECT_ATTRIBUTES deviceAttributes; + WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, + CDevice); + + deviceAttributes.EvtCleanupCallback = CDevice::OnCleanup; + deviceAttributes.SynchronizationScope = WdfSynchronizationScopeNone; + deviceAttributes.ExecutionLevel = WdfExecutionLevelPassive; + + WDFDEVICE device; + status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &device); + + if (!NT_SUCCESS(status)) + { + TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, "WdfDeviceCreate failed with Status %!STATUS!", status); + goto Exit; + } + + // Construct device object on the preallocated buffer using placement 'new' + CDevice* pDevice = new (GetDeviceObject(device)) CDevice(device); + + status = pDevice->Initialize(); + +Exit: + return status; +} + +NTSTATUS +CDevice::Initialize() +{ + NTSTATUS status = STATUS_SUCCESS; + + status = CQueue::AddQueueToDevice(_Device, &_Queue); + + // Register GNSS Device interface. Note that this sample is not publishing a symbolic link. + status = WdfDeviceCreateDeviceInterface(_Device, + (LPGUID)&GUID_DEVINTERFACE_GNSS, + nullptr); + + if (!NT_SUCCESS(status)) + { + TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, "WdfDeviceCreateDeviceInterface failed with %!STATUS!", status); + goto Exit; + } + +Exit: + return status; +} + +void +CDevice::OnCleanup( + _In_ WDFOBJECT Object +) +{ + CDevice *pDevice = GetDeviceObject(Object); + + // Device object constructed using placement 'new' so explicitly invoke destructor + pDevice->~CDevice(); +} + +NTSTATUS +CDevice::OnD0Entry( + _In_ WDFDEVICE /*Device*/, + _In_ WDF_POWER_DEVICE_STATE /*PreviousState*/ +) +{ + NTSTATUS status; + + // + // FIX ME: + // Add further functionality. + // Refer to power consideration from MSDN document: https://docs.microsoft.com/en-us/windows-hardware/drivers/gnss/gnss-driver-requirements + // + + status = STATUS_SUCCESS; + + return status; +} + +NTSTATUS +CDevice::OnD0Exit( + _In_ WDFDEVICE /*Device*/, + _In_ WDF_POWER_DEVICE_STATE /*TargetState*/ +) +{ + NTSTATUS status; + + // + // FIX ME: + // Add further functionality. + // Refer to power consideration from MSDN document: https://docs.microsoft.com/en-us/windows-hardware/drivers/gnss/gnss-driver-requirements + // + + status = STATUS_SUCCESS; + + return status; +} diff --git a/gnss/gnssUmdf/Device.h b/gnss/gnssUmdf/Device.h new file mode 100644 index 00000000..35072bfc --- /dev/null +++ b/gnss/gnssUmdf/Device.h @@ -0,0 +1,44 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + device.h + +Abstract: + + This file contains the device definitions. + +Environment: + + Windows User-Mode Driver Framework + +--*/ + +#pragma once + +class CQueue; + +class CDevice +{ +public: + // This is called from PnP manager in response to AddDevice call + static EVT_WDF_DRIVER_DEVICE_ADD OnDeviceAdd; + +private: + CDevice(_In_ WDFDEVICE Device); + ~CDevice(); + + static EVT_WDF_OBJECT_CONTEXT_CLEANUP OnCleanup; + static EVT_WDF_DEVICE_D0_ENTRY OnD0Entry; + static EVT_WDF_DEVICE_D0_EXIT OnD0Exit; + + NTSTATUS Initialize(); + CQueue* GetQueue(); + + WDFDEVICE _Device = nullptr; + CQueue* _Queue = nullptr; +}; + +WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(CDevice, GetDeviceObject); diff --git a/gnss/gnssUmdf/Driver.cpp b/gnss/gnssUmdf/Driver.cpp new file mode 100644 index 00000000..af443b12 --- /dev/null +++ b/gnss/gnssUmdf/Driver.cpp @@ -0,0 +1,107 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + driver.cpp + +Abstract: + + This file contains the driver entry points and callbacks. + +Environment: + + Windows User-Mode Driver Framework + +--*/ + +#include "precomp.h" +#include "Trace.h" +#include "Defaults.h" +#include "Driver.h" +#include "Device.h" + +#include "Driver.tmh" + + +extern "C" +NTSTATUS +DriverEntry( + _In_ PDRIVER_OBJECT DriverObject, + _In_ PUNICODE_STRING RegistryPath +) +{ + NTSTATUS status = STATUS_SUCCESS; + + // Initialize WPP Tracing + WPP_INIT_TRACING(DriverObject, RegistryPath); + + TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry"); + + // Register a cleanup callback so that we can call WPP_CLEANUP when + // the framework driver object is deleted during driver unload. + WDF_OBJECT_ATTRIBUTES attributes; + WDF_OBJECT_ATTRIBUTES_INIT(&attributes); + attributes.EvtCleanupCallback = GnssUmdfEvtDriverContextCleanup; + + WDF_DRIVER_CONFIG config; + WDF_DRIVER_CONFIG_INIT(&config, + CDevice::OnDeviceAdd); + + config.EvtDriverUnload = OnDriverUnload; + + status = WdfDriverCreate(DriverObject, + RegistryPath, + &attributes, + &config, + WDF_NO_HANDLE); + + if (!NT_SUCCESS(status)) + { + TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "WdfDriverCreate failed %!STATUS!", status); + + WPP_CLEANUP(DriverObject); + + return status; + } + + TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Exit"); + + return status; +} + +void +GnssUmdfEvtDriverContextCleanup( + _In_ WDFOBJECT DriverObject +) +/*++ +Routine Description: + + Free all the resources allocated in DriverEntry. + +Arguments: + + DriverObject - handle to a WDF Driver object. + +Return Value: + + void. + +--*/ +{ + UNREFERENCED_PARAMETER(DriverObject); + + TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry"); + + // Stop WPP Tracing + WPP_CLEANUP(WdfDriverWdmGetDriverObject((WDFDRIVER)DriverObject)); +} + +void +OnDriverUnload( + _In_ WDFDRIVER /* Driver */ +) +{ + WPP_CLEANUP(Driver); +} diff --git a/gnss/gnssUmdf/Driver.h b/gnss/gnssUmdf/Driver.h new file mode 100644 index 00000000..5de6d35e --- /dev/null +++ b/gnss/gnssUmdf/Driver.h @@ -0,0 +1,22 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + driver.h + +Abstract: + + This file contains the driver definitions. + +Environment: + + Windows User-Mode Driver Framework + +--*/ + +#pragma once + +EVT_WDF_DRIVER_UNLOAD OnDriverUnload; +EVT_WDF_OBJECT_CONTEXT_CLEANUP GnssUmdfEvtDriverContextCleanup; diff --git a/gnss/gnssUmdf/FixHandler.cpp b/gnss/gnssUmdf/FixHandler.cpp new file mode 100644 index 00000000..52b09a82 --- /dev/null +++ b/gnss/gnssUmdf/FixHandler.cpp @@ -0,0 +1,228 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + fixhandler.cpp + +Abstract: + + This file contains the Fix handler and contains logic to provide position. + +Environment: + + Windows User-Mode Driver Framework + +--*/ + +#include "precomp.h" +#include "Trace.h" +#include "Defaults.h" +#include "FixSession.h" +#include "FixHandler.h" + +#include "FixHandler.tmh" + + +NTSTATUS +CFixHandler::Initialize( + _In_ WDFQUEUE Queue +) +{ + NTSTATUS status = STATUS_SUCCESS; + + status = _SingleShotSession.Initialize(Queue); + + return status; +} + +NTSTATUS +CFixHandler::StartFix( + _In_ WDFREQUEST Request, + _In_ BOOL LocationServiceEnabled +) +{ + NTSTATUS status = STATUS_SUCCESS; + PGNSS_FIXSESSION_PARAM fixSessionParameters = nullptr; + + // For privacy reasons, the location stack notifies the driver when user toggles the location device controls. + // When set to off, the driver must not entertain any new location sessions. + if (!LocationServiceEnabled) + { + status = STATUS_UNSUCCESSFUL; + TraceEvents(TRACE_LEVEL_ERROR, TRACE_FIX, "Location master switch is off, we do not start a fix session"); + goto Exit; + } + + status = WdfRequestRetrieveInputBuffer(Request, sizeof(GNSS_FIXSESSION_PARAM), (void**)&fixSessionParameters, nullptr); + if (!NT_SUCCESS(status)) + { + TraceEvents(TRACE_LEVEL_ERROR, TRACE_FIX, "WdfRequestRetrieveInputBuffer failed with %!STATUS!", status); + goto Exit; + } + + // + // FIX ME: + // This sample currently supports only single shot session fix. + // If you support another session type, e.g., distance tracking, update the logic below accordingly. + // + if (fixSessionParameters->SessionType != GNSS_FixSession_SingleShot) + { + status = STATUS_UNSUCCESSFUL; + TraceEvents(TRACE_LEVEL_ERROR, TRACE_FIX, "Session type is not GNSS_FixSession_SingleShot"); + goto Exit; + } + + _CurrentSinglsShotSessionId = fixSessionParameters->FixSessionID; + + status = _SingleShotSession.StartAcquiringFix(fixSessionParameters); + if (!NT_SUCCESS(status)) + { + TraceEvents(TRACE_LEVEL_ERROR, TRACE_FIX, "StartFix failed with %!STATUS!", status); + goto Exit; + } + +Exit: + return status; +} + +NTSTATUS +CFixHandler::StopFix( + _In_ WDFREQUEST Request +) +{ + NTSTATUS status = STATUS_SUCCESS; + PGNSS_STOPFIXSESSION_PARAM stopFixSessionParam = nullptr; + + status = WdfRequestRetrieveInputBuffer(Request, sizeof(GNSS_STOPFIXSESSION_PARAM), (void**)&stopFixSessionParam, nullptr); + if (!NT_SUCCESS(status)) + { + TraceEvents(TRACE_LEVEL_ERROR, TRACE_FIX, "WdfRequestRetrieveInputBuffer failed with %!STATUS!", status); + goto Exit; + } + + // Send the session parameters to the right session based on the ID + if (stopFixSessionParam->FixSessionID != _CurrentSinglsShotSessionId) + { + status = STATUS_UNSUCCESSFUL; + TraceEvents(TRACE_LEVEL_ERROR, TRACE_FIX, "Session type is not GNSS_FixSession_SingleShot"); + goto Exit; + } + + _CurrentSinglsShotSessionId = INVALID_SESSION_ID; + + status = _SingleShotSession.StopAcquiringFix(stopFixSessionParam); + if (!NT_SUCCESS(status)) + { + TraceEvents(TRACE_LEVEL_ERROR, TRACE_FIX, "StopFix failed with %!STATUS!", status); + goto Exit; + } + +Exit: + return status; +} + +NTSTATUS +CFixHandler::StopExistingSinglsShotFix() +{ + NTSTATUS status = STATUS_SUCCESS; + PGNSS_STOPFIXSESSION_PARAM stopFixSessionParam = nullptr; + + if (_CurrentSinglsShotSessionId == INVALID_SESSION_ID) + { + TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_FIX, "There is no single shot session to stop"); + goto Exit; + } + + _CurrentSinglsShotSessionId = INVALID_SESSION_ID; + + INIT_POD_GNSS_STRUCT(stopFixSessionParam); + status = _SingleShotSession.StopAcquiringFix(stopFixSessionParam); + if (!NT_SUCCESS(status)) + { + TraceEvents(TRACE_LEVEL_ERROR, TRACE_FIX, "StopFix failed with %!STATUS!", status); + goto Exit; + } + +Exit: + return status; +} + +NTSTATUS +CFixHandler::ModifyFix( + _In_ WDFREQUEST Request +) +{ + NTSTATUS status = STATUS_SUCCESS; + PGNSS_FIXSESSION_PARAM fixSessionParameters = nullptr; + + status = WdfRequestRetrieveInputBuffer(Request, sizeof(GNSS_FIXSESSION_PARAM), (void**)&fixSessionParameters, nullptr); + if (!NT_SUCCESS(status)) + { + TraceEvents(TRACE_LEVEL_ERROR, TRACE_FIX, "WdfRequestRetrieveInputBuffer failed with %!STATUS!", status); + goto Exit; + } + + // + // FIX ME: + // We currently support only single shot session fix. + // If you support another session type, e.g., distance tracking, update the logic below accordingly. + // + if (fixSessionParameters->SessionType != GNSS_FixSession_SingleShot) + { + status = STATUS_UNSUCCESSFUL; + TraceEvents(TRACE_LEVEL_ERROR, TRACE_FIX, "Session type is not GNSS_FixSession_SingleShot"); + goto Exit; + } + + // + // FIX ME: + // Since only single session is supported, use _SingleShotSession instance. + // If multiple sessions, get the right session pointer searched by the session ID. + // + _SingleShotSession.ModifyAcquiringFix(fixSessionParameters); + + if (!NT_SUCCESS(status)) + { + TraceEvents(TRACE_LEVEL_ERROR, TRACE_FIX, "ModifyFix failed with %!STATUS!", status); + goto Exit; + } + +Exit: + return status; +} + +NTSTATUS +CFixHandler::GetFixRequest( + _In_ WDFREQUEST Request +) +{ + NTSTATUS status = STATUS_SUCCESS; + ULONG sessionId = INVALID_SESSION_ID; + ULONG *pSessionId = nullptr; + + // Get the session ID this get fix is for + status = WdfRequestRetrieveInputBuffer(Request, sizeof(sessionId), (void**)&pSessionId, nullptr); + if (!NT_SUCCESS(status)) + { + TraceEvents(TRACE_LEVEL_ERROR, TRACE_FIX, "Could not retrieve input sessionID for request"); + goto Exit; + } + + // + // FIX ME: + // Single session is only option now, but if multiple sessions, this sample should do this check at the FixHandler Level. + // + sessionId = *pSessionId; + + status = _SingleShotSession.GetFix(Request); + if (!NT_SUCCESS(status)) + { + TraceEvents(TRACE_LEVEL_ERROR, TRACE_FIX, "SinglShotSession.GetFix failed with %!STATUS!", status); + goto Exit; + } + +Exit: + return status; +} diff --git a/gnss/gnssUmdf/FixHandler.h b/gnss/gnssUmdf/FixHandler.h new file mode 100644 index 00000000..6ade10a7 --- /dev/null +++ b/gnss/gnssUmdf/FixHandler.h @@ -0,0 +1,39 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + Fixhandler.h + +Abstract: + + This module contains the type definitions of the fix logic of the Umdf Gnss Driver. + +Environment: + + Windows User-Mode Driver Framework + +--*/ + +#pragma once + +class CFixSession; + +class CFixHandler +{ +public: + NTSTATUS Initialize(_In_ WDFQUEUE Queue); + + NTSTATUS StartFix(_In_ WDFREQUEST Request, _In_ BOOL LocationServiceEnabled); + NTSTATUS StopFix(_In_ WDFREQUEST Request); + NTSTATUS GetFixRequest(_In_ WDFREQUEST Request); + NTSTATUS ModifyFix(_In_ WDFREQUEST Request); + NTSTATUS StopExistingSinglsShotFix(); + +private: + // Session objects (single shot, distance tracking etc.) + CFixSession _SingleShotSession; + + ULONG _CurrentSinglsShotSessionId = INVALID_SESSION_ID; +}; diff --git a/gnss/gnssUmdf/FixSession.cpp b/gnss/gnssUmdf/FixSession.cpp new file mode 100644 index 00000000..14418a8f --- /dev/null +++ b/gnss/gnssUmdf/FixSession.cpp @@ -0,0 +1,512 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + fixsession.cpp + +Abstract: + + This file contains the Fix sessions and contains logic to provide position. + +Environment: + + Windows User-Mode Driver Framework + +--*/ + +#include "precomp.h" +#include "Trace.h" +#include "Defaults.h" +#include "FixSession.h" +#include "FixHandler.h" + +#include "FixSession.tmh" + + +static void CALLBACK +s_FixThreadStub( + _Inout_ PTP_CALLBACK_INSTANCE Instance, + _Inout_opt_ PVOID Context, + _Inout_ PTP_WORK Work +); + +CFixSession::CFixSession() : + _Id(INVALID_SESSION_ID), + _State(STOPPED), + _HasCachedFix(false), + _StopFixEvent(nullptr), + _ThreadpoolWork(nullptr) +{ + InitializeCriticalSection(&_Lock); + _GnssPosition = g_DefaultGnssFixData; +} + +CFixSession::~CFixSession() +{ + if (_StopFixEvent != nullptr && _ThreadpoolWork != nullptr) + { + SetEvent(_StopFixEvent); + WaitForThreadpoolWorkCallbacks(_ThreadpoolWork, TRUE); + } + + if (_StopFixEvent != nullptr) + { + CloseHandle(_StopFixEvent); + _StopFixEvent = nullptr; + } + + if (_ThreadpoolWork != nullptr) + { + CloseThreadpoolWork(_ThreadpoolWork); + _ThreadpoolWork = nullptr; + } + + DeleteCriticalSection(&_Lock); +} + +NTSTATUS +CFixSession::Initialize( + _In_ WDFQUEUE Queue +) +{ + EnterCriticalSection(&_Lock); + + NTSTATUS status = STATUS_SUCCESS; + + // set the state + _State = STOPPED; + + // Create the TP work + _ThreadpoolWork = CreateThreadpoolWork( + (PTP_WORK_CALLBACK)s_FixThreadStub, + (PVOID)this, + nullptr + ); + + if (_ThreadpoolWork == nullptr) + { + status = STATUS_UNSUCCESSFUL; + goto Exit; + } + + // Create the stop fix Event + _StopFixEvent = CreateEvent(/* lpEventAttributes */ nullptr, /* bManualReset */ FALSE, /* bInitialState */ FALSE, /* lpName */ nullptr); + if (_StopFixEvent == nullptr) + { + status = STATUS_UNSUCCESSFUL; + goto Exit; + } + + // Create the manual dispatch queue + WDF_IO_QUEUE_CONFIG queueConfiguration; + WDF_IO_QUEUE_CONFIG_INIT(&queueConfiguration, WdfIoQueueDispatchManual); + + // Initialize the attributes of the queue. Set the execution level to + // passive to force all IRPs to be sent to the driver at passive IRQL. + WDF_OBJECT_ATTRIBUTES ioQueueAttributes; + WDF_OBJECT_ATTRIBUTES_INIT(&ioQueueAttributes); + ioQueueAttributes.SynchronizationScope = WdfSynchronizationScopeQueue; + ioQueueAttributes.ExecutionLevel = WdfExecutionLevelPassive; + status = WdfIoQueueCreate(WdfIoQueueGetDevice(Queue), + &queueConfiguration, + &ioQueueAttributes, + &_FixAcquisitionRequestQueue); + +Exit: + LeaveCriticalSection(&_Lock); + return status; +} + +NTSTATUS +CFixSession::StartAcquiringFix( + _In_ PGNSS_FIXSESSION_PARAM FixSessionParameters +) +{ + NTSTATUS status = STATUS_SUCCESS; + + EnterCriticalSection(&_Lock); + + // Check the state of the thread. + // If already running we should not get this request + // as multiplexing is not supported for Singleshot + if (_State == ACQUIRING) + { + status = STATUS_UNSUCCESSFUL; + goto Exit; + } + + // Create PTP_WORK only when first start fix is called. + if (_ThreadpoolWork == nullptr) + { + // Not initialized. Error out + status = STATUS_UNSUCCESSFUL; + goto Exit; + } + + _Id = FixSessionParameters->FixSessionID; + _State = ACQUIRING; + _FixParameter = *FixSessionParameters; + + ResetEvent(_StopFixEvent); + + // Post a work object to the thread + SubmitThreadpoolWork(_ThreadpoolWork); + + // Initialize the GetFix Queue + WdfIoQueueStart(_FixAcquisitionRequestQueue); + +Exit: + LeaveCriticalSection(&_Lock); + + return status; +} + +NTSTATUS +CFixSession::StopAcquiringFix( + _In_ PGNSS_STOPFIXSESSION_PARAM StopFixSessionParam +) +{ + NTSTATUS status = STATUS_SUCCESS; + + { + EnterCriticalSection(&_Lock); + + // If Ids don't Match return Error + if (StopFixSessionParam->FixSessionID != _Id) + { + status = STATUS_UNSUCCESSFUL; + TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_FIX, "Id mismatch in Stop Fix Session call"); + goto Exit; + } + + // Check the state of the session + if (_State != ACQUIRING) + { + TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_FIX, "Can't stop an inactive session."); + goto Exit; + } + + // Stop the current processing of the fix session + if (_StopFixEvent != nullptr) + { + SetEvent(_StopFixEvent); + } + + LeaveCriticalSection(&_Lock); + } + + // Wait for any threadpool work to finish. + if (_ThreadpoolWork != nullptr) + { + WaitForThreadpoolWorkCallbacks(_ThreadpoolWork, TRUE); + } + + EnterCriticalSection(&_Lock); + _State = STOPPED; + + // Drain the GetFix Queue + WdfIoQueuePurgeSynchronously(_FixAcquisitionRequestQueue); + +Exit: + LeaveCriticalSection(&_Lock); + + return status; +} + +NTSTATUS +CFixSession::ModifyAcquiringFix( + _In_ PGNSS_FIXSESSION_PARAM ModifyFixSessionParam +) +{ + NTSTATUS status = STATUS_SUCCESS; + + EnterCriticalSection(&_Lock); + + memcpy_s(&_FixParameter, sizeof(GNSS_FIXSESSION_PARAM), ModifyFixSessionParam, sizeof(*ModifyFixSessionParam)); + + LeaveCriticalSection(&_Lock); + + return status; +} + +NTSTATUS +CFixSession::ReportGnssFix( + _In_ PGNSS_FIXDATA GnssFix +) +{ + EnterCriticalSection(&_Lock); + + NTSTATUS status = STATUS_SUCCESS; + WDFREQUEST Request; + WDF_IO_QUEUE_STATE QueueStatus; + ULONG uRequest; + + QueueStatus = WdfIoQueueGetState(_FixAcquisitionRequestQueue, &uRequest, nullptr); + if (!WDF_IO_QUEUE_READY(QueueStatus) || (uRequest == 0)) + { + status = STATUS_UNSUCCESSFUL; + goto Exit; + } + + if (STATUS_SUCCESS == WdfIoQueueRetrieveNextRequest(_FixAcquisitionRequestQueue, &Request)) + { + status = CompleteRequestWithGnssFix(Request, GnssFix); + if (!NT_SUCCESS(status)) + { + TraceEvents(TRACE_LEVEL_ERROR, TRACE_FIX, "Could not respond with fix data with %!STATUS!", status); + goto Exit; + } + } + else + { + TraceEvents(TRACE_LEVEL_ERROR, TRACE_FIX, "Couldn't retrieve the next request with %!STATUS!", status); + goto Exit; + } + +Exit: + LeaveCriticalSection(&_Lock); + + return status; +} + +NTSTATUS +CFixSession::CompleteRequestWithGnssFix( + _In_ WDFREQUEST Request, + PGNSS_FIXDATA GnssFix +) +{ + NTSTATUS status = STATUS_SUCCESS; + PVOID outputBuffer; + size_t outputBufferLength; + PGNSS_EVENT gnssEvent; + size_t size = FIELD_OFFSET(GNSS_EVENT, FixData) + sizeof(GNSS_FIXDATA); + + status = WdfRequestRetrieveOutputBuffer(Request, + size, + &outputBuffer, + &outputBufferLength); + + if (!NT_SUCCESS(status)) + { + TraceEvents(TRACE_LEVEL_ERROR, TRACE_FIX, "WdfRequestRetrieveOutputBuffer() failed with %!STATUS!", status); + goto Exit; + } + + gnssEvent = ((GNSS_EVENT *)outputBuffer); + memset(outputBuffer, 0, size); + gnssEvent->Version = GNSS_DRIVER_VERSION_2; + gnssEvent->EventType = GNSS_Event_FixAvailable; + gnssEvent->EventDataSize = sizeof(GNSS_FIXDATA); + gnssEvent->Size = (ULONG)size; + memcpy_s(&gnssEvent->FixData, sizeof(GNSS_FIXDATA), GnssFix, sizeof(GNSS_FIXDATA)); + gnssEvent->FixData.FixSessionID = _Id; + + WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, outputBufferLength); + status = STATUS_PENDING; +Exit: + return status; +} + +NTSTATUS +CFixSession::UpdateCurrentPosition( + _In_ PGNSS_FIXDATA GnssFix +) +{ + NTSTATUS status = STATUS_SUCCESS; + + EnterCriticalSection(&_Lock); + + memcpy_s(&_GnssPosition, sizeof(GNSS_FIXDATA), GnssFix, sizeof(*GnssFix)); + + LeaveCriticalSection(&_Lock); + + return status; +} + +NTSTATUS +CFixSession::GetFix( + _In_ WDFREQUEST Request +) +{ + NTSTATUS status = STATUS_SUCCESS; + ULONG sessionId = INVALID_SESSION_ID; + PGNSS_EVENT outputEvent = nullptr; + ULONG *pSessionId = nullptr; + + EnterCriticalSection(&_Lock); + + // Verify the size of where output goes eventually, when this IRP is serviced + status = WdfRequestRetrieveOutputBuffer(Request, sizeof(GNSS_EVENT), (void**)&outputEvent, nullptr); + if (!NT_SUCCESS(status)) + { + TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_FIX, "Could not retrieve output buffer for request with %!STATUS!", status); + goto Exit; + } + + // Get the session ID this get fix is for + status = WdfRequestRetrieveInputBuffer(Request, sizeof(sessionId), (void**)&pSessionId, nullptr); + if (!NT_SUCCESS(status)) + { + TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_FIX, "Could not retrieve input sessionID for request"); + goto Exit; + } + + sessionId = *pSessionId; + + // Check if the Ids match + if (_Id != sessionId) + { + status = STATUS_UNSUCCESSFUL; + goto Exit; + } + // If we have a cached fix around because we tried to respond while there + // weren't any getfixes around, answer immediately with it + if (_HasCachedFix) + { + status = CompleteRequestWithGnssFix(Request, &_GnssPosition); + + _HasCachedFix = !(NT_SUCCESS(status)); + } + // Otherwise, we push the request into a queue + else + { + status = WdfRequestForwardToIoQueue(Request, _FixAcquisitionRequestQueue); + if (!NT_SUCCESS(status)) + { + TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_FIX, "WdfRequestForwardToIoQueue failed with %!STATUS!", status); + goto Exit; + } + + status = STATUS_PENDING; + } + +Exit: + LeaveCriticalSection(&_Lock); + + return status; +} + +static void CALLBACK +s_FixThreadStub( + _Inout_ PTP_CALLBACK_INSTANCE /*Instance*/, + _Inout_opt_ PVOID Context, + _Inout_ PTP_WORK /*Work*/ +) +{ + CFixSession *pFixSession = static_cast<CFixSession *>(Context); + + pFixSession->AcquireSingleFix(); +} + +void +CFixSession::AcquireSingleFix() +{ + NTSTATUS status = STATUS_SUCCESS; + + while (true) + { + // Wait stop fix event for 1 second and then retrieve position + DWORD WaitCode = WaitForSingleObject(_StopFixEvent, DEFAULT_FIX_INTERVAL_SECONDS * 1000); + if (WaitCode == WAIT_TIMEOUT) + { + status = RetrievePosition(&_GnssPosition); + if (!NT_SUCCESS(status)) + { + TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_FIX, "Fail to retrieve fix data from position source"); + } + + // Send the default fix to the session + status = ReportGnssFix(&_GnssPosition); + if (!NT_SUCCESS(status)) + { + // We were not able to send the fix so cache it + _HasCachedFix = true; + } + else + { + if (_GnssPosition.IsFinalFix != FALSE) + { + break; + } + } + } + else if (WaitCode == WAIT_OBJECT_0) + { + // Stop session signalled + break; + } + } + + EnterCriticalSection(&_Lock); + + // Reset the StopFix Event if it is set + ResetEvent(_StopFixEvent); + + // Update the state of the session + _State = STOPPED; + + LeaveCriticalSection(&_Lock); +} + + +NTSTATUS +CFixSession::RetrievePosition( + _Inout_ PGNSS_FIXDATA GnssFixData +) +{ + NTSTATUS status = STATUS_SUCCESS; + + // + // FIX ME: + // You can retrieve a position from a predefined position or GPS HW. + // This sample code calls RetrievePositionFromPredefinedValue to give fake location. + // To give a real location from GPS HW, replace this function with new function that defines + // (1) establishing and enumerating HW interface such as Serial or Bluetooth, and + // (2) reading and parsing NMEA messages from the interface. + // You can also define a custom IOCTL instead, updating _GnssPosition directly in CQueue and skip the call below as no-op. + // + status = RetrievePositionFromPredefinedValue(GnssFixData); + + return status; +} + +NTSTATUS +CFixSession::RetrievePositionFromPredefinedValue( + _Out_ PGNSS_FIXDATA GnssFixData +) +{ + NTSTATUS status = STATUS_SUCCESS; + + // + // FIX ME: + // Specify user-defined GNSS_FIXDATA output based off the DDI format. The following is just an example. + // + *GnssFixData = + { + sizeof(GNSS_FIXDATA), + GNSS_DRIVER_DDK_VERSION, + INVALID_SESSION_ID, + { 0xCD700000, 0x1D48908 }, // an example date/time, Dec/01/2018 + TRUE, + STATUS_SUCCESS, + GNSS_FIXDETAIL_BASIC | GNSS_FIXDETAIL_ACCURACY, + { + sizeof(GNSS_FIXDATA_BASIC), + GNSS_DRIVER_DDK_VERSION, + // Location: Mount Rainier National Park + 46.852273, + -121.757468, + 0.0, + 0.0, + 0.0 + }, + { + sizeof(GNSS_FIXDATA_ACCURACY), + GNSS_DRIVER_DDK_VERSION, + 10 // Meters accuracy + } + }; + return status; +} diff --git a/gnss/gnssUmdf/FixSession.h b/gnss/gnssUmdf/FixSession.h new file mode 100644 index 00000000..f8298306 --- /dev/null +++ b/gnss/gnssUmdf/FixSession.h @@ -0,0 +1,60 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + Fixsession.h + +Abstract: + + This module contains the type definitions of the fix logic of the Umdf Gnss Driver. + +Environment: + + Windows User-Mode Driver Framework + +--*/ + +#pragma once + +// +// This class implements the Fix sessions and contains logic to provide position within GNSS driver. +// +class CFixSession +{ +public: + CFixSession(); + ~CFixSession(); + + void AcquireSingleFix(); + NTSTATUS Initialize(_In_ WDFQUEUE Queue); + NTSTATUS StartAcquiringFix(_In_ PGNSS_FIXSESSION_PARAM FixSessionParameters); + NTSTATUS StopAcquiringFix(_In_ PGNSS_STOPFIXSESSION_PARAM StopFixSessionParam); + NTSTATUS ModifyAcquiringFix(_In_ PGNSS_FIXSESSION_PARAM ModifyFixSessionParam); + NTSTATUS GetFix(_In_ WDFREQUEST Request); + NTSTATUS UpdateCurrentPosition(_In_ PGNSS_FIXDATA GnssFix); + + NTSTATUS RetrievePosition(_Inout_ PGNSS_FIXDATA GnssFixData); + NTSTATUS RetrievePositionFromPredefinedValue(_Out_ PGNSS_FIXDATA GnssFixData); + +private: + enum STATE + { + ACQUIRING = 0, + STOPPED + }; + + ULONG _Id = INVALID_SESSION_ID; + STATE _State = STOPPED; + GNSS_FIXSESSION_PARAM _FixParameter = {}; + WDFQUEUE _FixAcquisitionRequestQueue = nullptr; + bool _HasCachedFix = false; + GNSS_FIXDATA _GnssPosition = {}; + HANDLE _StopFixEvent = nullptr; + PTP_WORK _ThreadpoolWork = nullptr; + CRITICAL_SECTION _Lock; + + NTSTATUS CompleteRequestWithGnssFix(_In_ WDFREQUEST Request, PGNSS_FIXDATA GnssFix); + NTSTATUS ReportGnssFix(_In_ PGNSS_FIXDATA GnssFix); +}; diff --git a/gnss/gnssUmdf/Queue.cpp b/gnss/gnssUmdf/Queue.cpp new file mode 100644 index 00000000..fdf23ab2 --- /dev/null +++ b/gnss/gnssUmdf/Queue.cpp @@ -0,0 +1,482 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + queue.cpp + +Abstract: + + This file contains the queue entry points and callbacks. + +Environment: + + Windows User-Mode Driver Framework + +--*/ + +#include "precomp.h" +#include "Trace.h" +#include "Defaults.h" +#include "Device.h" +#include "FixSession.h" +#include "FixHandler.h" +#include "Queue.h" + +#include "Queue.tmh" + + +CQueue::CQueue( + WDFQUEUE Queue +) : + _Queue(Queue), + _ForcedDriverVersion(GNSS_DRIVER_DDK_VERSION) +{ + InitializeCriticalSection(&_Lock); +} + +CQueue::~CQueue() +{ + DeleteCriticalSection(&_Lock); + _Queue = nullptr; +} + + +void +CQueue::OnCleanup( + _In_ WDFOBJECT Object +) +{ + CQueue *pQueue = GetQueueObject(Object); + + // Queue object constructed using placement 'new' so explicitly invoke destructor + pQueue->~CQueue(); +} + +NTSTATUS +CQueue::Initialize() +{ + NTSTATUS status = STATUS_SUCCESS; + + // Initialize the Fix Handler + status = _FixHandler.Initialize(_Queue); + if (!NT_SUCCESS(status)) + { + TraceEvents(TRACE_LEVEL_ERROR, TRACE_QUEUE, "_FixHandler->Initialize failed with %!STATUS!", status); + goto Exit; + } + +Exit: + return status; +} + +void +CQueue::OnIoDeviceControl( + _In_ WDFQUEUE Queue, + _In_ WDFREQUEST Request, + _In_ size_t OutputBufferLength, + _In_ size_t InputBufferLength, + _In_ ULONG IoControlCode +) +{ + CQueue *pQueue = GetQueueObject(Queue); + + pQueue->OnIoDeviceControl(Request, IoControlCode, InputBufferLength, OutputBufferLength); +} + +NTSTATUS +CQueue::AddQueueToDevice( + _In_ WDFDEVICE Device, + _Outptr_ CQueue** Queue +) +{ + NTSTATUS status = STATUS_SUCCESS; + + // Create a sequential IO Queue for serial operation and supply all the callbacks. + // A sequential queue will cause all IO requests to be serialized to the device (i.e., only one request will sent at a time). + WDF_IO_QUEUE_CONFIG queueConfig; + WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&queueConfig, + WdfIoQueueDispatchSequential); + + queueConfig.PowerManaged = WdfFalse; + queueConfig.EvtIoDeviceControl = CQueue::OnIoDeviceControl; + + WDF_OBJECT_ATTRIBUTES queueAttributes; + WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&queueAttributes, + CQueue); + + queueAttributes.EvtCleanupCallback = CQueue::OnCleanup; + + WDFQUEUE queue = nullptr; + status = WdfIoQueueCreate(Device, + &queueConfig, + &queueAttributes, + &queue); + + if (!NT_SUCCESS(status)) + { + TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, "WdfIoQueueCreate failed with Status %!STATUS!", status); + goto Exit; + } + + // Construct a queue object on the preallocated buffer using placement new operation + *Queue = new (GetQueueObject(queue)) CQueue(queue); + + status = (*Queue)->Initialize(); + if (!NT_SUCCESS(status)) + { + TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DEVICE, "CQueue::Initialize failed with %!STATUS!", status); + goto Exit; + } + +Exit: + return status; +} + +void +CQueue::OnIoDeviceControl( + _In_ WDFREQUEST Request, + _In_ ULONG IoControlCode, + _In_ size_t InputBufferLength, + _In_ size_t OutputBufferLength) +{ + TraceEvents(TRACE_LEVEL_INFORMATION, + TRACE_QUEUE, + "Request = %p, IoControlCode = 0x%x InputBufferLength=%d OutputBufferLength=%d", + Request, IoControlCode, (int)InputBufferLength, (int)OutputBufferLength); + + NTSTATUS status = STATUS_SUCCESS; + + switch (IoControlCode) + { + // Capability Exchange + case IOCTL_GNSS_SEND_PLATFORM_CAPABILITY: + break; + case IOCTL_GNSS_GET_DEVICE_CAPABILITY: + status = GetDeviceCapability(Request); + break; + + case IOCTL_GNSS_GET_CHIPSETINFO: + status = GetChipsetInfo(Request); + break; + + // Fix + case IOCTL_GNSS_START_FIXSESSION: + status = _FixHandler.StartFix(Request, _InternalState.SetLocationServiceEnabled); + break; + case IOCTL_GNSS_STOP_FIXSESSION: + status = _FixHandler.StopFix(Request); + break; + case IOCTL_GNSS_MODIFY_FIXSESSION: + status = _FixHandler.ModifyFix(Request); + break; + case IOCTL_GNSS_GET_FIXDATA: + status = _FixHandler.GetFixRequest(Request); + break; + + // Driver Command + case IOCTL_GNSS_SEND_DRIVERCOMMAND: + status = HandleDriverCommand(Request); + break; + + // + // FIX ME: + // The below is optional IOCTLs. Driver developer may choose to implement for advanced functionality. + // + + // Agnss + case IOCTL_GNSS_INJECT_AGNSS: + case IOCTL_GNSS_LISTEN_AGNSS: + // Supl + case IOCTL_GNSS_SET_SUPL_HSLP: + case IOCTL_GNSS_CONFIG_SUPL_CERT: + case IOCTL_GNSS_SET_V2UPL_CONFIG: + //Ni + case IOCTL_GNSS_LISTEN_DRIVER_REQUEST: + case IOCTL_GNSS_RESPOND_NI: + case IOCTL_GNSS_LISTEN_NI: + //Geofence + case IOCTL_GNSS_LISTEN_GEOFENCE_ALERT: + case IOCTL_GNSS_LISTEN_GEOFENCES_TRACKINGSTATUS: + case IOCTL_GNSS_CREATE_GEOFENCE: + case IOCTL_GNSS_DELETE_GEOFENCE: + // Breadcrumbing + case IOCTL_GNSS_START_BREADCRUMBING: + case IOCTL_GNSS_STOP_BREADCRUMBING: + case IOCTL_GNSS_LISTEN_BREADCRUMBING_ALERT: + case IOCTL_GNSS_POP_BREADCRUMBS: + // Ioctls that are not implemented + case IOCTL_GNSS_LISTEN_ERROR: + case IOCTL_GNSS_EXECUTE_CWTEST: + case IOCTL_GNSS_EXECUTE_SELFTEST: + case IOCTL_GNSS_LISTEN_NMEA: + status = STATUS_NOT_IMPLEMENTED; + break; + + default: + status = STATUS_INVALID_DEVICE_REQUEST; + break; + } + + if (status != STATUS_PENDING) + { + TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_QUEUE, "%!FUNC! Completing Request with status %!STATUS!", status); + WdfRequestComplete(Request, status); + } +} + +NTSTATUS +CQueue::GetDeviceCapability( + _In_ WDFREQUEST Request +) +{ + NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST; + PGNSS_DEVICE_CAPABILITY outputParam; + + status = WdfRequestRetrieveOutputBuffer(Request, sizeof(*outputParam), (void**)&outputParam, nullptr); + if (!NT_SUCCESS(status)) + { + TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_QUEUE, "%!FUNC! Could not retrieve output buffer for request with status = %!STATUS!", status); + goto Exit; + } + + INIT_POD_GNSS_STRUCT(outputParam); + + // + // FIX ME: + // The functionality below is optional. Driver developer may choose to implement for advanced functionality/better performance. + // + { + outputParam->SupportContinuousTracking = FALSE; + + outputParam->SupportDistanceTracking = FALSE; + + outputParam->GeofencingSupport = FALSE; + outputParam->MaxGeofencesSupported = 0; + + outputParam->RequireAGnssInjection = FALSE; + outputParam->AgnssFormatSupported = FALSE; + outputParam->AgnssFormatPreferred = FALSE; + + outputParam->SupportCpLocation = FALSE; + outputParam->SupportSuplV2 = FALSE; + outputParam->SupportSuplV1 = FALSE; + outputParam->SupportUplV2 = FALSE; + outputParam->SupportedSuplVersion.MajorVersion = 0; + outputParam->SupportedSuplVersion.MinorVersion = 0; + + outputParam->MaxGnssBreadCrumbFixes = 0; + outputParam->GnssBreadCrumbPayloadVersion = BREADCRUMBING_UNSUPPORTED; + + // Update the Driver version if forced through IOCTL + outputParam->Version = _ForcedDriverVersion; + } + + WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, sizeof(*outputParam)); + status = STATUS_PENDING; + +Exit: + return status; +} + +NTSTATUS +CQueue::GetChipsetInfo( + _In_ WDFREQUEST Request +) +{ + // + // FIX ME: + // The following is an example. Replace the values accordingly + // + static const wchar_t s_ManufacturerID[] = L"Microsoft Test"; + static const wchar_t s_HardwareID[] = L"UMDF Gnss"; + static const wchar_t s_FirmwareVersion[] = L"1.0.0.0"; + + NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST; + PGNSS_CHIPSETINFO outputParam; + + status = WdfRequestRetrieveOutputBuffer(Request, sizeof(*outputParam), (void**)&outputParam, nullptr); + if (!NT_SUCCESS(status)) + { + TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_QUEUE, "%!FUNC! Could not retrieve output buffer for request with status = %!STATUS!", status); + goto Exit; + } + + INIT_POD_GNSS_STRUCT(outputParam); + + memset(&(outputParam->ManufacturerID), 0, sizeof(outputParam->ManufacturerID)); + memset(&(outputParam->HardwareID), 0, sizeof(outputParam->HardwareID)); + memset(&(outputParam->FirmwareVersion), 0, sizeof(outputParam->FirmwareVersion)); + + memcpy_s(&(outputParam->ManufacturerID), sizeof(outputParam->ManufacturerID), &s_ManufacturerID, sizeof(s_ManufacturerID)); + memcpy_s(&(outputParam->HardwareID), sizeof(outputParam->HardwareID), &s_HardwareID, sizeof(s_HardwareID)); + memcpy_s(&(outputParam->FirmwareVersion), sizeof(outputParam->FirmwareVersion), &s_FirmwareVersion, sizeof(s_FirmwareVersion)); + + WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, sizeof(*outputParam)); + status = STATUS_PENDING; + +Exit: + return status; +} + +NTSTATUS +CQueue::HandleDriverCommand( + _In_ WDFREQUEST Request +) +{ + NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST; + PGNSS_DRIVERCOMMAND_PARAM command = nullptr; + + // Check that there is enough room to output the returned GNSS_DEVICE_CAPABILITY + status = WdfRequestRetrieveInputBuffer(Request, sizeof(*command), (void**)&command, nullptr); + + if (!NT_SUCCESS(status)) + { + TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_QUEUE, "%!FUNC! Could not retrieve input buffer for DriverCommand request with status = %!STATUS!", status); + goto Exit; + } + + // Check that the sizes are well-formed + if ((command->Size < (ULONG)FIELD_OFFSET(GNSS_DRIVERCOMMAND_PARAM, CommandData[command->CommandDataSize]))) + { + TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_QUEUE, "Command is not formatted correctly : unexpected sizes specified"); + goto Exit; + } + + switch (command->CommandType) + { + case GNSS_ClearAgnssData: + status = ClearAgnssData(command); + break; + case GNSS_ResetEngine: + status = ResetEngine(command); + break; + case GNSS_SetLocationServiceEnabled: + status = SetLocationServiceStatus(command); + break; + case GNSS_ForceOperationMode: + status = SetOperationMode(command); + break; + + // + // FIX ME: + // Below are optional driver commands. Driver developer may choose to implement for advanced functionality. + // + case GNSS_SetLocationNIRequestAllowed: + case GNSS_ResetGeofencesTracking: + case GNSS_SetNiTimeoutInterval: + case GNSS_SetSuplVersion: + case GNSS_SetUplServerAccessInterval: + status = STATUS_NOT_IMPLEMENTED; + break; + default: + status = STATUS_INVALID_DEVICE_REQUEST; + break; + } + +Exit: + return status; +} + +NTSTATUS +CQueue::SetLocationServiceStatus( + _In_ PGNSS_DRIVERCOMMAND_PARAM CommandParam +) +{ + NTSTATUS status = STATUS_SUCCESS; + + status = GetDataFromCommand(CommandParam, &_InternalState.SetLocationServiceEnabled) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL; + + if (!_InternalState.SetLocationServiceEnabled) + { + // + // FIX ME: + // We must stop any ongoing location sessions of any kind (geofence tracking, assistance data refresh, etc. if any). + // For example, if you have distance tracking fix session, stop the session as well. + // + status = _FixHandler.StopExistingSinglsShotFix(); + } + + return status; +} + +NTSTATUS +CQueue::ResetEngine( + _In_ PGNSS_DRIVERCOMMAND_PARAM /*CommandParam*/ +) +{ + NTSTATUS status = STATUS_SUCCESS; + + // + // FIX ME: + // This is mandatory command, but sample driver cannot support Reset engine command because this is vendor/HW-specific feature. + // You must customize this accordingly. The sample below demonstrates how it might work by resetting internal structure. + // + _AgnssNeeded[AGNSS_TIME_IDX] = TRUE; + _AgnssNeeded[AGNSS_POS_IDX] = TRUE; + _AgnssNeeded[AGNSS_BLOB_IDX] = TRUE; + + return status; +} + +NTSTATUS +CQueue::ClearAgnssData( + _In_ PGNSS_DRIVERCOMMAND_PARAM CommandParam +) +{ + NTSTATUS status = STATUS_SUCCESS; + DWORD data = 0; + + // + // FIX ME: + // This is mandatory command, but sample driver cannot support Clear AGNSS data because this is vendor/HW-specific feature. + // You must customize this accordingly. The sample below demonstrates how it might work by resetting internal structure. + // + if (GetDataFromCommand(CommandParam, &data)) + { + GNSS_AGNSS_REQUEST_TYPE reqType = (GNSS_AGNSS_REQUEST_TYPE)data; + _AgnssNeeded[reqType] = TRUE; + } + else + { + status = STATUS_UNSUCCESSFUL; + } + + return status; +} + +NTSTATUS +CQueue::SetOperationMode( + _In_ PGNSS_DRIVERCOMMAND_PARAM CommandParam +) +{ + NTSTATUS status = STATUS_SUCCESS; + + // + // FIX ME: + // This is mandatory only if SUPL is supported. SUPL is not mandatory unless it is required by mobile operator. + // You must customize this code accordingly, depending on the requirement. + // + status = GetDataFromCommand(CommandParam, &_InternalState.OperationMode) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL; + + return status; +} + +template <class DataT> +BOOL CQueue::GetDataFromCommand( + _In_ PGNSS_DRIVERCOMMAND_PARAM Command, + _Out_ DataT* Data) +{ + size_t dataLen = sizeof(*Data); + + memset(Data, 0, dataLen); + + if (!Command || (Command->CommandDataSize != dataLen)) + { + return FALSE; + } + + memcpy_s(Data, dataLen, Command->CommandData, dataLen); + return TRUE; +} diff --git a/gnss/gnssUmdf/Queue.h b/gnss/gnssUmdf/Queue.h new file mode 100644 index 00000000..89a105ac --- /dev/null +++ b/gnss/gnssUmdf/Queue.h @@ -0,0 +1,78 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + queue.h + +Abstract: + + This file contains the queue definitions for the Umdf Gnss Driver. + +Environment: + + Windows User-Mode Driver Framework + +--*/ + +#pragma once + +class CFixHandler; + +// +//This class sets up IO queue, performs the IOCTL operations, and implements the type definitions for the driver's device callback. +// +class CQueue +{ +public: + static NTSTATUS AddQueueToDevice(_In_ WDFDEVICE device, _Outptr_ CQueue** queue); + +private: + enum + { + AGNSS_TIME_IDX = GNSS_AGNSS_TimeInjection, + AGNSS_POS_IDX = GNSS_AGNSS_PositionInjection, + AGNSS_BLOB_IDX = GNSS_AGNSS_BlobInjection, + AGNSS_MAX_IDX + }; + + typedef struct { + DWORD OperationMode; + BOOL SetLocationNiRequestAllowed; + BOOL SetLocationServiceEnabled; + } GnssInternalState; + + WDFQUEUE _Queue; + CRITICAL_SECTION _Lock; + CFixHandler _FixHandler; + ULONG _ForcedDriverVersion = GNSS_DRIVER_DDK_VERSION; + GnssInternalState _InternalState = {}; + BOOL _AgnssNeeded[AGNSS_MAX_IDX]; + + CQueue(WDFQUEUE Queue); + ~CQueue(); + + static EVT_WDF_OBJECT_CONTEXT_CLEANUP OnCleanup; + static EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL OnIoDeviceControl; + + template <class DataT> + BOOL GetDataFromCommand(_In_ PGNSS_DRIVERCOMMAND_PARAM Command, + _Out_ DataT* Data); + + NTSTATUS Initialize(); + void OnIoDeviceControl(_In_ WDFREQUEST Request, + _In_ ULONG IoControlCode, + _In_ size_t InputBufferLength, + _In_ size_t OutputBufferLength); + NTSTATUS GetDeviceCapability(_In_ WDFREQUEST Request); + NTSTATUS GetChipsetInfo(_In_ WDFREQUEST Request); + NTSTATUS HandleDriverCommand(_In_ WDFREQUEST Request); + + NTSTATUS ResetEngine(_In_ PGNSS_DRIVERCOMMAND_PARAM CommandParam); + NTSTATUS ClearAgnssData(_In_ PGNSS_DRIVERCOMMAND_PARAM CommandParam); + NTSTATUS SetLocationServiceStatus(_In_ PGNSS_DRIVERCOMMAND_PARAM CommandParam); + NTSTATUS SetOperationMode(_In_ PGNSS_DRIVERCOMMAND_PARAM CommandParam); +}; + +WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(CQueue, GetQueueObject); diff --git a/gnss/gnssUmdf/Trace.h b/gnss/gnssUmdf/Trace.h new file mode 100644 index 00000000..6b6af60b --- /dev/null +++ b/gnss/gnssUmdf/Trace.h @@ -0,0 +1,64 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + Trace.h + +Abstract: + + This module contains the local type definitions for the Umdf Gnss Driver. + +Environment: + + Windows User-Mode Driver Framework + +--*/ + +#pragma once + +// +// Define the tracing flags. +// + +#define WPP_CONTROL_GUIDS \ + WPP_DEFINE_CONTROL_GUID( \ + GnssUmdfTraceGuid, (ceb3bf01,80e4,4dc7,b3bf,f6b5279eb8c4), \ + \ + WPP_DEFINE_BIT(MYDRIVER_ALL_INFO) \ + WPP_DEFINE_BIT(TRACE_DRIVER) \ + WPP_DEFINE_BIT(TRACE_DEVICE) \ + WPP_DEFINE_BIT(TRACE_QUEUE) \ + WPP_DEFINE_BIT(TRACE_FIX) \ + ) + +#define WPP_FLAG_LEVEL_LOGGER(flag, level) \ + WPP_LEVEL_LOGGER(flag) + +#define WPP_FLAG_LEVEL_ENABLED(flag, level) \ + (WPP_LEVEL_ENABLED(flag) && \ + WPP_CONTROL(WPP_BIT_ ## flag).Level >= level) + +#define WPP_LEVEL_FLAGS_LOGGER(lvl,flags) \ + WPP_LEVEL_LOGGER(flags) + +#define WPP_LEVEL_FLAGS_ENABLED(lvl, flags) \ + (WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_ ## flags).Level >= lvl) + +// +// This comment block is scanned by the trace preprocessor to define our +// Trace function. +// +// begin_wpp config +// FUNC Trace{FLAG=MYDRIVER_ALL_INFO}(LEVEL, MSG, ...); +// FUNC TraceEvents(LEVEL, FLAGS, MSG, ...); +// end_wpp + +// +// +// Driver specific #defines +// +#if UMDF_VERSION_MAJOR == 2 && UMDF_VERSION_MINOR == 0 + #define MYDRIVER_TRACING_ID L"Microsoft\\UMDF2.0\\gnssUmdf V1.0" +#endif diff --git a/gnss/gnssUmdf/gnssUmdf.inf b/gnss/gnssUmdf/gnssUmdf.inf Binary files differnew file mode 100644 index 00000000..65dd5e59 --- /dev/null +++ b/gnss/gnssUmdf/gnssUmdf.inf diff --git a/gnss/gnssUmdf/gnssUmdf.vcxproj b/gnss/gnssUmdf/gnssUmdf.vcxproj new file mode 100644 index 00000000..bcfd27ae --- /dev/null +++ b/gnss/gnssUmdf/gnssUmdf.vcxproj @@ -0,0 +1,301 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + </ItemGroup> + <ItemGroup> + <ClCompile Include="Device.cpp" /> + <ClCompile Include="Driver.cpp" /> + <ClCompile Include="FixHandler.cpp" /> + <ClCompile Include="FixSession.cpp" /> + <ClCompile Include="Queue.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="precomp.h" /> + <ClInclude Include="Device.h" /> + <ClInclude Include="Driver.h" /> + <ClInclude Include="FixHandler.h" /> + <ClInclude Include="FixSession.h" /> + <ClInclude Include="Defaults.h" /> + <ClInclude Include="Queue.h" /> + <ClInclude Include="Trace.h" /> + </ItemGroup> + <ItemGroup> + <Inf Include="gnssUmdf.inf" /> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{AC97DD9E-781F-4FCE-8AC7-ADE57C633A13}</ProjectGuid> + <TemplateGuid>{32909489-7be5-497b-aafa-db6669d9b44b}</TemplateGuid> + <MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion> + <Configuration>Debug</Configuration> + <Platform Condition="'$(Platform)' == ''">Win32</Platform> + <RootNamespace>gnssUmdf</RootNamespace> + <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion> + </PropertyGroup> + <PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + </PropertyGroup> + <PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + </PropertyGroup> + <PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + </PropertyGroup> + <PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + </PropertyGroup> + <PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + </PropertyGroup> + <PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + </PropertyGroup> + <PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'"> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + </PropertyGroup> + <PropertyGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'"> + <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <DriverTargetPlatform>Universal</DriverTargetPlatform> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>true</UseDebugLibraries> + <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>false</UseDebugLibraries> + <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>true</UseDebugLibraries> + <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>false</UseDebugLibraries> + <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>true</UseDebugLibraries> + <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>false</UseDebugLibraries> + <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>true</UseDebugLibraries> + <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>false</UseDebugLibraries> + <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor> + <OutDir>$(ProjectDir)bin\$(Platform)\$(ConfigurationName)\</OutDir> + <IntDir>$(ProjectDir)obj\$(Platform)\$(ConfigurationName)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor> + <OutDir>$(ProjectDir)bin\$(Platform)\$(ConfigurationName)\</OutDir> + <IntDir>$(ProjectDir)obj\$(Platform)\$(ConfigurationName)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor> + <OutDir>$(ProjectDir)bin\$(Platform)\$(ConfigurationName)\</OutDir> + <IntDir>$(ProjectDir)obj\$(Platform)\$(ConfigurationName)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor> + <OutDir>$(ProjectDir)bin\$(Platform)\$(ConfigurationName)\</OutDir> + <IntDir>$(ProjectDir)obj\$(Platform)\$(ConfigurationName)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> + <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor> + <OutDir>$(ProjectDir)bin\$(Platform)\$(ConfigurationName)\</OutDir> + <IntDir>$(ProjectDir)obj\$(Platform)\$(ConfigurationName)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> + <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor> + <OutDir>$(ProjectDir)bin\$(Platform)\$(ConfigurationName)\</OutDir> + <IntDir>$(ProjectDir)obj\$(Platform)\$(ConfigurationName)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'"> + <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor> + <OutDir>$(ProjectDir)bin\$(Platform)\$(ConfigurationName)\</OutDir> + <IntDir>$(ProjectDir)obj\$(Platform)\$(ConfigurationName)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'"> + <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor> + <OutDir>$(ProjectDir)bin\$(Platform)\$(ConfigurationName)\</OutDir> + <IntDir>$(ProjectDir)obj\$(Platform)\$(ConfigurationName)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WppEnabled>true</WppEnabled> + <WppRecorderEnabled>true</WppRecorderEnabled> + <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData> + <WarningLevel>Level4</WarningLevel> + <TreatWarningAsError>true</TreatWarningAsError> + <ExceptionHandling>Sync</ExceptionHandling> + <PrecompiledHeader>Create</PrecompiledHeader> + <PrecompiledHeaderFile>precomp.h</PrecompiledHeaderFile> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WppEnabled>true</WppEnabled> + <WppRecorderEnabled>true</WppRecorderEnabled> + <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData> + <WarningLevel>Level4</WarningLevel> + <TreatWarningAsError>true</TreatWarningAsError> + <ExceptionHandling>Sync</ExceptionHandling> + <PrecompiledHeader>Create</PrecompiledHeader> + <PrecompiledHeaderFile>precomp.h</PrecompiledHeaderFile> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <WppEnabled>true</WppEnabled> + <WppRecorderEnabled>true</WppRecorderEnabled> + <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData> + <WarningLevel>Level4</WarningLevel> + <TreatWarningAsError>true</TreatWarningAsError> + <ExceptionHandling>Sync</ExceptionHandling> + <PrecompiledHeader>Create</PrecompiledHeader> + <PrecompiledHeaderFile>precomp.h</PrecompiledHeaderFile> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WppEnabled>true</WppEnabled> + <WppRecorderEnabled>true</WppRecorderEnabled> + <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData> + <WarningLevel>Level4</WarningLevel> + <TreatWarningAsError>true</TreatWarningAsError> + <ExceptionHandling>Sync</ExceptionHandling> + <PrecompiledHeader>Create</PrecompiledHeader> + <PrecompiledHeaderFile>precomp.h</PrecompiledHeaderFile> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'"> + <ClCompile> + <WppEnabled>true</WppEnabled> + <WppRecorderEnabled>true</WppRecorderEnabled> + <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData> + <WarningLevel>Level4</WarningLevel> + <TreatWarningAsError>true</TreatWarningAsError> + <ExceptionHandling>Sync</ExceptionHandling> + <PrecompiledHeader>Create</PrecompiledHeader> + <PrecompiledHeaderFile>precomp.h</PrecompiledHeaderFile> + <WholeProgramOptimization>false</WholeProgramOptimization> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'"> + <ClCompile> + <WppEnabled>true</WppEnabled> + <WppRecorderEnabled>true</WppRecorderEnabled> + <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData> + <WarningLevel>Level4</WarningLevel> + <TreatWarningAsError>true</TreatWarningAsError> + <ExceptionHandling>Sync</ExceptionHandling> + <PrecompiledHeader>Create</PrecompiledHeader> + <PrecompiledHeaderFile>precomp.h</PrecompiledHeaderFile> + <WholeProgramOptimization>false</WholeProgramOptimization> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'"> + <ClCompile> + <WppEnabled>true</WppEnabled> + <WppRecorderEnabled>true</WppRecorderEnabled> + <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData> + <WarningLevel>Level4</WarningLevel> + <TreatWarningAsError>true</TreatWarningAsError> + <ExceptionHandling>Sync</ExceptionHandling> + <PrecompiledHeader>Create</PrecompiledHeader> + <PrecompiledHeaderFile>precomp.h</PrecompiledHeaderFile> + <WholeProgramOptimization>false</WholeProgramOptimization> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'"> + <ClCompile> + <WppEnabled>true</WppEnabled> + <WppRecorderEnabled>true</WppRecorderEnabled> + <WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData> + <WarningLevel>Level4</WarningLevel> + <TreatWarningAsError>true</TreatWarningAsError> + <ExceptionHandling>Sync</ExceptionHandling> + <PrecompiledHeader>Create</PrecompiledHeader> + <PrecompiledHeaderFile>precomp.h</PrecompiledHeaderFile> + <WholeProgramOptimization>false</WholeProgramOptimization> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <FilesToPackage Include="$(TargetPath)" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/gnss/gnssUmdf/gnssUmdf.vcxproj.filters b/gnss/gnssUmdf/gnssUmdf.vcxproj.filters new file mode 100644 index 00000000..15af8928 --- /dev/null +++ b/gnss/gnssUmdf/gnssUmdf.vcxproj.filters @@ -0,0 +1,69 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + <Filter Include="Driver Files"> + <UniqueIdentifier>{8E41214B-6785-4CFE-B992-037D68949A14}</UniqueIdentifier> + <Extensions>inf;inv;inx;mof;mc;</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <Inf Include="gnssUmdf.inf"> + <Filter>Driver Files</Filter> + </Inf> + </ItemGroup> + <ItemGroup> + <ClInclude Include="Device.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Driver.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Queue.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Trace.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="Defaults.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="FixHandler.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="FixSession.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="precomp.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ClCompile Include="Device.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Driver.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="Queue.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="FixHandler.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="FixSession.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/gnss/gnssUmdf/precomp.h b/gnss/gnssUmdf/precomp.h new file mode 100644 index 00000000..e07f2171 --- /dev/null +++ b/gnss/gnssUmdf/precomp.h @@ -0,0 +1,29 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + precomp.h + +Abstract: + + This module contains the common type definitions and includes. + +Environment: + + Windows User-Mode Driver Framework + +--*/ + +#pragma once + +// +// Include the type specific headers. +// +#include <windows.h> +#include <wdf.h> +#include <initguid.h> +#include <sstream> +#include <vector> +#include <gnssdriver.h> |
