/// <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);
public static IDeviceFactory CreateAndroidUsbDeviceFactory( this FilterDeviceDefinition filterDeviceDefinition, UsbManager usbManager, Context context, ILoggerFactory loggerFactory = null, GetConnectedDeviceDefinitionsAsync getConnectedDeviceDefinitionsAsync = null, GetUsbInterfaceManager getUsbInterfaceManager = null, ushort?readBufferSize = null, ushort?writeBufferSize = null, IAndroidFactory androidFactory = null, Func <AndroidUsbDevice, IUsbPermissionBroadcastReceiver> getUsbPermissionBroadcastReceiver = null ) => CreateAndroidUsbDeviceFactory( new ReadOnlyCollection <FilterDeviceDefinition>(new List <FilterDeviceDefinition> { filterDeviceDefinition }), usbManager, context, loggerFactory, getConnectedDeviceDefinitionsAsync, getUsbInterfaceManager, readBufferSize, writeBufferSize, androidFactory, getUsbPermissionBroadcastReceiver);
/// <summary> /// Creates a <see cref="IDeviceFactory"/> for Windows 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="hidApiService">Abstraction for Hid interaction</param> /// <param name="classGuid">Filters by specified class guid</param> /// <param name="readBufferSize">Override the input report size</param> /// <param name="writeBufferSize">Override the output report size</param> /// <param name="writeReportTransform">Given the data supplied, allow you to divide the data in to a <see cref="Report"/></param> /// <param name="getConnectedDeviceDefinitionsAsync">Override the default call for getting definitions</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> /// <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> /// <returns>A factory which enumerates and instantiates devices</returns> public static IDeviceFactory CreateWindowsHidDeviceFactory( this FilterDeviceDefinition filterDeviceDefinition, ILoggerFactory loggerFactory = null, IHidApiService hidApiService = null, Guid?classGuid = null, ushort?readBufferSize = null, ushort?writeBufferSize = null, GetConnectedDeviceDefinitionsAsync getConnectedDeviceDefinitionsAsync = null, Func <Report, TransferResult> readReportTransform = null, Func <TransferResult, Report> readTransferTransform = null, Func <byte[], byte, byte[]> writeTransferTransform = null, WriteReportTransform writeReportTransform = null) { return(CreateWindowsHidDeviceFactory( new ReadOnlyCollection <FilterDeviceDefinition>(new List <FilterDeviceDefinition> { filterDeviceDefinition }), loggerFactory, hidApiService, classGuid, readBufferSize, writeBufferSize, getConnectedDeviceDefinitionsAsync, readReportTransform, readTransferTransform, writeTransferTransform, writeReportTransform)); }
/// <summary> /// Creates a factory 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="hidApiService">Abstraction for Hid interaction</param> /// <param name="classGuid">Filters by specified class guid</param> /// <param name="readBufferSize">Override the input report size</param> /// <param name="writeBufferSize">Override the output report size</param> /// <param name="getConnectedDeviceDefinitionsAsync">Override the default call for getting definitions</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> /// <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> /// <returns>A factory which enumerates and instantiates devices</returns> public static IDeviceFactory CreateWindowsHidDeviceFactory( this IEnumerable <FilterDeviceDefinition> filterDeviceDefinitions, ILoggerFactory loggerFactory = null, IHidApiService hidApiService = null, Guid?classGuid = null, ushort?readBufferSize = null, ushort?writeBufferSize = null, GetConnectedDeviceDefinitionsAsync getConnectedDeviceDefinitionsAsync = null, Func <Report, TransferResult> readReportTransform = null, Func <TransferResult, Report> readTransferTransform = null, Func <byte[], byte, byte[]> writeTransferTransform = null, WriteReportTransform writeReportTransform = null) { if (filterDeviceDefinitions == null) { throw new ArgumentNullException(nameof(filterDeviceDefinitions)); } loggerFactory ??= NullLoggerFactory.Instance; var selectedHidApiService = hidApiService ?? new WindowsHidApiService(loggerFactory); classGuid ??= selectedHidApiService.GetHidGuid(); if (getConnectedDeviceDefinitionsAsync == null) { var windowsDeviceEnumerator = new WindowsDeviceEnumerator( loggerFactory.CreateLogger <WindowsDeviceEnumerator>(), classGuid.Value, (d, guid) => GetDeviceDefinition(d, selectedHidApiService, loggerFactory.CreateLogger(nameof(WindowsHidDeviceFactoryExtensions))), c => Task.FromResult(!filterDeviceDefinitions.Any() || filterDeviceDefinitions.FirstOrDefault(f => f.IsDefinitionMatch(c, DeviceType.Hid)) != null) ); getConnectedDeviceDefinitionsAsync = windowsDeviceEnumerator.GetConnectedDeviceDefinitionsAsync; } return(new DeviceFactory( loggerFactory, getConnectedDeviceDefinitionsAsync, (c, cancellationToken) => Task.FromResult <IDevice>(new HidDevice ( new WindowsHidHandler( c.DeviceId, writeBufferSize, readBufferSize, hidApiService, loggerFactory, readTransferTransform, writeTransferTransform), loggerFactory, readReportTransform, writeReportTransform )), (c, cancellationToken) => Task.FromResult(c.DeviceType == DeviceType.Hid))); }
/// <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)); }
public static IDeviceFactory CreateWindowsUsbDeviceFactory( ILoggerFactory loggerFactory = null, GetConnectedDeviceDefinitionsAsync getConnectedDeviceDefinitionsAsync = null, GetUsbInterfaceManager getUsbInterfaceManager = null, Guid?classGuid = null, ushort?readBufferSize = null, ushort?writeBufferSize = null ) => CreateWindowsUsbDeviceFactory( new List <FilterDeviceDefinition>(), loggerFactory, getConnectedDeviceDefinitionsAsync, getUsbInterfaceManager, classGuid, readBufferSize, writeBufferSize);
public static IDeviceFactory CreateUwpUsbDeviceFactory( this FilterDeviceDefinition filterDeviceDefinitions, ILoggerFactory loggerFactory = null, GetConnectedDeviceDefinitionsAsync getConnectedDeviceDefinitionsAsync = null, GetUsbInterfaceManager getUsbInterfaceManager = null, ushort?readBufferSize = null, ushort?writeBufferSize = null ) => CreateUwpUsbDeviceFactory( new List <FilterDeviceDefinition> { filterDeviceDefinitions }, loggerFactory, getConnectedDeviceDefinitionsAsync, getUsbInterfaceManager, readBufferSize, writeBufferSize);
public static IDeviceFactory CreateUsbDeviceFactory( GetConnectedDeviceDefinitionsAsync getConnectedDeviceDefinitionsAsync, GetUsbInterfaceManager getUsbInterfaceManager, ILoggerFactory loggerFactory = null, Guid?classGuid = null) => new DeviceFactory( loggerFactory, getConnectedDeviceDefinitionsAsync, async(d, cancellationToken) => { var usbInterfaceManager = await getUsbInterfaceManager(d.DeviceId, cancellationToken).ConfigureAwait(false); return(new UsbDevice(d.DeviceId, usbInterfaceManager, loggerFactory)); }, //Support the device if the factory doesn't filter on class guid, or the filter matches the device (c, cancellationToken) => Task.FromResult(c.DeviceType == DeviceType.Usb && (classGuid == null || classGuid.Value == c.ClassGuid)) );
public static IDeviceFactory CreateUwpUsbDeviceFactory( this IEnumerable <FilterDeviceDefinition> filterDeviceDefinitions, ILoggerFactory loggerFactory, GetConnectedDeviceDefinitionsAsync getConnectedDeviceDefinitionsAsync = null, GetUsbInterfaceManager getUsbInterfaceManager = null, ushort?readBufferSize = null, ushort?writeBufferSize = null, Func <wde.DeviceInformation, bool> deviceInformationFilter = null, Func <windowsUsbDevice, SetupPacket, byte[], CancellationToken, Task <TransferResult> > performControlTransferAsync = null, IDataReceiver dataReceiver = null) { if (getConnectedDeviceDefinitionsAsync == null) { //Filter to by device Id. //TODO: There is surely a better way to do this deviceInformationFilter ??= d => d.Id.Contains(@"\\?\usb", StringComparison.OrdinalIgnoreCase) && d.Id.Contains(@"vid", StringComparison.OrdinalIgnoreCase) && d.Id.Contains(@"pid", StringComparison.OrdinalIgnoreCase); var uwpHidDeviceEnumerator = new UwpDeviceEnumerator( AqsHelpers.GetAqs(filterDeviceDefinitions, DeviceType.Usb), DeviceType.Usb, (d, cancellationToken) => Task.FromResult(new ConnectionInfo { CanConnect = true }), loggerFactory, deviceInformationFilter); getConnectedDeviceDefinitionsAsync = uwpHidDeviceEnumerator.GetConnectedDeviceDefinitionsAsync; } getUsbInterfaceManager ??= (deviceId, cancellationToken) => Task.FromResult <IUsbInterfaceManager>( new UwpUsbInterfaceManager( //TODO: no idea if this is OK... new ConnectedDeviceDefinition(deviceId, DeviceType.Usb), dataReceiver, performControlTransferAsync, loggerFactory, readBufferSize, writeBufferSize)); return(UsbDeviceFactoryExtensions.CreateUsbDeviceFactory(getConnectedDeviceDefinitionsAsync, getUsbInterfaceManager, loggerFactory)); }
public static IDeviceFactory CreateWindowsUsbDeviceFactory( this IEnumerable <FilterDeviceDefinition> filterDeviceDefinitions, ILoggerFactory loggerFactory = null, GetConnectedDeviceDefinitionsAsync getConnectedDeviceDefinitionsAsync = null, GetUsbInterfaceManager getUsbInterfaceManager = null, Guid?classGuid = null, ushort?readBufferSize = null, ushort?writeBufferSize = null ) { if (filterDeviceDefinitions == null) { throw new ArgumentNullException(nameof(filterDeviceDefinitions)); } loggerFactory ??= NullLoggerFactory.Instance; if (getConnectedDeviceDefinitionsAsync == null) { var logger = loggerFactory.CreateLogger <WindowsDeviceEnumerator>(); var uwpHidDeviceEnumerator = new WindowsDeviceEnumerator( logger, classGuid ?? WindowsDeviceConstants.WinUSBGuid, (d, guid) => DeviceBase.GetDeviceDefinitionFromWindowsDeviceId(d, DeviceType.Usb, logger, guid), c => Task.FromResult(!filterDeviceDefinitions.Any() || filterDeviceDefinitions.FirstOrDefault(f => f.IsDefinitionMatch(c, DeviceType.Usb)) != null)); getConnectedDeviceDefinitionsAsync = uwpHidDeviceEnumerator.GetConnectedDeviceDefinitionsAsync; } getUsbInterfaceManager ??= (d, cancellationToken) => Task.FromResult <IUsbInterfaceManager>(new WindowsUsbInterfaceManager ( //TODO: no idea if this is OK... d, loggerFactory, readBufferSize, writeBufferSize ) ); return(UsbDeviceFactoryExtensions.CreateUsbDeviceFactory(getConnectedDeviceDefinitionsAsync, getUsbInterfaceManager, loggerFactory)); }
public static IDeviceFactory CreateAndroidUsbDeviceFactory( this IEnumerable <FilterDeviceDefinition> filterDeviceDefinitions, UsbManager usbManager, Context context, ILoggerFactory loggerFactory = null, GetConnectedDeviceDefinitionsAsync getConnectedDeviceDefinitionsAsync = null, GetUsbInterfaceManager getUsbInterfaceManager = null, ushort?readBufferSize = null, ushort?writeBufferSize = null, IAndroidFactory androidFactory = null, Func <AndroidUsbDevice, IUsbPermissionBroadcastReceiver> getUsbPermissionBroadcastReceiver = null ) { if (usbManager == null) { throw new ArgumentNullException(nameof(usbManager)); } if (context == null) { throw new ArgumentNullException(nameof(context)); } loggerFactory ??= NullLoggerFactory.Instance; #if __ANDROID__ androidFactory ??= new AndroidFactory(); getUsbPermissionBroadcastReceiver ??= new Func <AndroidUsbDevice, IUsbPermissionBroadcastReceiver>((ud) => new UsbPermissionBroadcastReceiver( usbManager, ud, context, androidFactory, loggerFactory.CreateLogger <UsbPermissionBroadcastReceiver>())); #else if (androidFactory == null) { throw new ArgumentNullException(nameof(androidFactory)); } if (getUsbPermissionBroadcastReceiver == null) { throw new ArgumentNullException(nameof(getUsbPermissionBroadcastReceiver)); } #endif getConnectedDeviceDefinitionsAsync ??= (cancellationToken) => { return(Task.FromResult <IEnumerable <ConnectedDeviceDefinition> > ( new ReadOnlyCollection <ConnectedDeviceDefinition> ( usbManager .DeviceList .Select(kvp => kvp.Value) .Where ( d => filterDeviceDefinitions .FirstOrDefault ( f => (!f.VendorId.HasValue || f.VendorId.Value == d.VendorId) && (!f.ProductId.HasValue || f.ProductId.Value == d.ProductId) ) != null ) .Select(AndroidUsbInterfaceManager.GetAndroidDeviceDefinition) .ToList() ) )); }; getUsbInterfaceManager ??= (a, cancellationToken) => Task.FromResult <IUsbInterfaceManager>( new AndroidUsbInterfaceManager( usbManager, //TODO: throw a validation message int.Parse(a, IntParsingCulture), androidFactory, getUsbPermissionBroadcastReceiver, loggerFactory, readBufferSize, writeBufferSize )); return(UsbDeviceFactoryExtensions.CreateUsbDeviceFactory(getConnectedDeviceDefinitionsAsync, getUsbInterfaceManager, loggerFactory)); }
/// <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)) )); }