/// <summary> /// Creates a <see cref="IDeviceFactory"/> for UWP Hid devices /// </summary> /// <param name="filterDeviceDefinition">Devices must match this</param> /// <param name="loggerFactory"><see href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.iloggerfactory"/></param> /// <param name="classGuid">Filters by specified class guid</param> /// <param name="deviceInformationFilter"></param> /// <param name="dataReceiver"></param> /// <param name="readBufferSize">Override the input report size</param> /// <param name="readTransferTransform">Exposes the raw data from the device (including Report Id) on reads and allows you to format the returned <see cref="TransferResult"/></param> /// <param name="writeTransferTransform">Given the Report Id and data supplied for the write, allow you to format the raw data that is sent to the device</param> /// <param name="writeReportTransform">Given the data supplied, allow you to divide the data in to a <see cref="Report"/></param> /// <param name="writeBufferSize">Override the output report size</param> /// <param name="getConnectedDeviceDefinitionsAsync">Override the default call for getting definitions</param> /// <param name="getDevice"></param> /// <param name="readReportTransform">Allows you to manually convert the <see cref="Report"/> in to a <see cref="TransferResult"/> so that the Report Id is not discarded on ReadAsync. By default, this inserts the Report Id at index zero of the array.</param> /// <returns>A factory which enumerates and instantiates devices</returns> public static IDeviceFactory CreateUwpHidDeviceFactory( this FilterDeviceDefinition filterDeviceDefinition, ILoggerFactory loggerFactory = null, GetConnectedDeviceDefinitionsAsync getConnectedDeviceDefinitionsAsync = null, GetDeviceAsync getDevice = null, Guid?classGuid = null, Func <wde.DeviceInformation, bool> deviceInformationFilter = null, IDataReceiver dataReceiver = null, ushort?writeBufferSize = null, ushort?readBufferSize = null, Func <Report, TransferResult> readReportTransform = null, Func <TransferResult, Report> readTransferTransform = null, Func <byte[], byte, byte[]> writeTransferTransform = null, WriteReportTransform writeReportTransform = null) => CreateUwpHidDeviceFactory( new List <FilterDeviceDefinition> { filterDeviceDefinition }, loggerFactory, getConnectedDeviceDefinitionsAsync, getDevice, classGuid, deviceInformationFilter, dataReceiver, writeBufferSize, readBufferSize, readReportTransform, readTransferTransform, writeTransferTransform, writeReportTransform);
/// <summary> /// Constructs a DeviceFactory /// </summary> /// <param name="loggerFactory">The factory for creating new loggers for each device</param> /// <param name="getConnectedDevicesAsync">A delegate that returns matching connected device definitions</param> /// <param name="getDevice">A delegate to construct the device based on the specified connected device definition</param> /// <param name="supportsDevice">A delegate that returns whether or not this factory supports the connected device</param> public DeviceFactory( ILoggerFactory loggerFactory, GetConnectedDeviceDefinitionsAsync getConnectedDevicesAsync, GetDeviceAsync getDevice, Func <ConnectedDeviceDefinition, CancellationToken, Task <bool> > supportsDevice ) { _getConnectedDevicesAsync = getConnectedDevicesAsync ?? throw new ArgumentNullException(nameof(getConnectedDevicesAsync)); _loggerFactory = loggerFactory ?? NullLoggerFactory.Instance; _logger = _loggerFactory.CreateLogger <DeviceFactory>(); _getDevice = getDevice; _supportsDevice = supportsDevice ?? throw new ArgumentNullException(nameof(supportsDevice)); }
/// <summary> /// Creates a <see cref="IDeviceFactory"/> for UWP Hid devices /// </summary> /// <param name="filterDeviceDefinitions">Devices must match these</param> /// <param name="loggerFactory"><see href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.iloggerfactory"/></param> /// <param name="classGuid">Filters by specified class guid</param> /// <param name="deviceInformationFilter"></param> /// <param name="dataReceiver"></param> /// <param name="readBufferSize">Override the input report size</param> /// <param name="readTransferTransform">Exposes the raw data from the device (including Report Id) on reads and allows you to format the returned <see cref="TransferResult"/></param> /// <param name="writeTransferTransform">Given the Report Id and data supplied for the write, allow you to format the raw data that is sent to the device</param> /// <param name="writeReportTransform">Given the data supplied, allow you to divide the data in to a <see cref="Report"/></param> /// <param name="writeBufferSize">Override the output report size</param> /// <param name="getConnectedDeviceDefinitionsAsync">Override the default call for getting definitions</param> /// <param name="getDevice"></param> /// <param name="readReportTransform">Allows you to manually convert the <see cref="Report"/> in to a <see cref="TransferResult"/> so that the Report Id is not discarded on ReadAsync. By default, this inserts the Report Id at index zero of the array.</param> /// <returns>A factory which enumerates and instantiates devices</returns> public static IDeviceFactory CreateUwpHidDeviceFactory( this IEnumerable <FilterDeviceDefinition> filterDeviceDefinitions, ILoggerFactory loggerFactory = null, GetConnectedDeviceDefinitionsAsync getConnectedDeviceDefinitionsAsync = null, GetDeviceAsync getDevice = null, Guid?classGuid = null, Func <wde.DeviceInformation, bool> deviceInformationFilter = null, IDataReceiver dataReceiver = null, ushort?writeBufferSize = null, ushort?readBufferSize = null, Func <Report, TransferResult> readReportTransform = null, Func <TransferResult, Report> readTransferTransform = null, Func <byte[], byte, byte[]> writeTransferTransform = null, WriteReportTransform writeReportTransform = null) { loggerFactory ??= NullLoggerFactory.Instance; getDevice ??= (c, cancellationToken) => Task.FromResult <IDevice>( new HidDevice( new UwpHidDeviceHandler( c, dataReceiver ?? new UwpDataReceiver( new Observable <TransferResult>(), loggerFactory.CreateLogger <UwpDataReceiver>()), loggerFactory, writeBufferSize, readBufferSize, readTransferTransform, writeTransferTransform), loggerFactory, readReportTransform, writeReportTransform)); var aqs = AqsHelpers.GetAqs(filterDeviceDefinitions, DeviceType.Hid); var logger = loggerFactory.CreateLogger <UwpDeviceEnumerator>(); if (getConnectedDeviceDefinitionsAsync == null) { //Filter to by device Id. //TODO: There is surely a better way to do this deviceInformationFilter ??= d => d.Id.Contains(@"\\?\hid", StringComparison.OrdinalIgnoreCase) && d.Id.Contains(@"vid", StringComparison.OrdinalIgnoreCase) && d.Id.Contains(@"pid", StringComparison.OrdinalIgnoreCase); var uwpHidDeviceEnumerator = new UwpDeviceEnumerator( aqs, DeviceType.Hid, async(deviceId, cancellationToken) => { using var hidDevice = await UwpHidDeviceHandler.GetHidDevice(deviceId).AsTask(cancellationToken); var canConnect = hidDevice != null; if (!canConnect) { return new ConnectionInfo { CanConnect = false } } ; logger?.LogInformation("Testing device connection. Id: {deviceId}. Can connect: {canConnect}", deviceId, true); return(new ConnectionInfo { CanConnect = true, UsagePage = hidDevice.UsagePage }); }, loggerFactory, deviceInformationFilter); getConnectedDeviceDefinitionsAsync = uwpHidDeviceEnumerator.GetConnectedDeviceDefinitionsAsync; } return(new DeviceFactory( loggerFactory, getConnectedDeviceDefinitionsAsync, getDevice, (c, cancellationToken) => Task.FromResult(c.DeviceType == DeviceType.Hid && (classGuid == null || classGuid.Value == c.ClassGuid)) )); }