public void RegisterDefaultInterfaces() { foreach (var usbInterface in UsbInterfaces) { usbInterface.RegisterDefaultEndpoints(); } ReadUsbInterface = UsbInterfaces.FirstOrDefault(i => i.ReadEndpoint != null); WriteUsbInterface = UsbInterfaces.FirstOrDefault(i => i.WriteEndpoint != null); ReadInterruptUsbInterface = UsbInterfaces.FirstOrDefault(i => i.InterruptReadEndpoint != null); WriteInterruptUsbInterface = UsbInterfaces.FirstOrDefault(i => i.InterruptWriteEndpoint != null); }
public void Close() { foreach (var usbInterface in UsbInterfaces) { usbInterface.Dispose(); } UsbInterfaces.Clear(); _DeviceHandle?.Dispose(); _DeviceHandle = null; }
public void RegisterDefaultInterfaces() { foreach (var usbInterface in UsbInterfaces) { usbInterface.RegisterDefaultEndpoints(); } ReadUsbInterface = UsbInterfaces.FirstOrDefault(i => i.ReadEndpoint != null); WriteUsbInterface = UsbInterfaces.FirstOrDefault(i => i.WriteEndpoint != null); ReadInterruptUsbInterface = UsbInterfaces.FirstOrDefault(i => i.InterruptReadEndpoint != null); WriteInterruptUsbInterface = UsbInterfaces.FirstOrDefault(i => i.InterruptWriteEndpoint != null); Logger.LogInformation("Defaults: Read interface: {readInterface} Write interface {writeInterface} Read PipeId: {readPipeId} Write PipeId: {writePipeId}", ReadUsbInterface?.InterfaceNumber, WriteUsbInterface?.InterfaceNumber, ReadUsbInterface?.ReadEndpoint?.PipeId, WriteUsbInterface?.WriteEndpoint?.PipeId ); }
private void Initialize() { using var logScope = Logger.BeginScope("DeviceId: {deviceId} Call: {call}", DeviceId, nameof(Initialize)); try { Close(); int errorCode; if (string.IsNullOrEmpty(DeviceId)) { throw new ValidationException( $"{nameof(ConnectedDeviceDefinition)} must be specified before {nameof(InitializeAsync)} can be called."); } _DeviceHandle = APICalls.CreateFile(DeviceId, FileAccessRights.GenericWrite | FileAccessRights.GenericRead, APICalls.FileShareRead | APICalls.FileShareWrite, IntPtr.Zero, APICalls.OpenExisting, APICalls.FileAttributeNormal | APICalls.FileFlagOverlapped, IntPtr.Zero); if (_DeviceHandle.IsInvalid) { //TODO: is error code useful here? errorCode = Marshal.GetLastWin32Error(); if (errorCode > 0) { throw new ApiException($"Device handle no good. Error code: {errorCode}"); } } Logger.LogInformation(Messages.SuccessMessageGotWriteAndReadHandle); var isSuccess = WinUsbApiCalls.WinUsb_Initialize(_DeviceHandle, out var interfaceHandle); _ = WindowsHelpers.HandleError(isSuccess, Messages.ErrorMessageCouldntIntializeDevice, Logger); #pragma warning disable CA2000 //We need to hold on to this handle var defaultInterfaceHandle = new SafeFileHandle(interfaceHandle, false); #pragma warning restore CA2000 var connectedDeviceDefinition = GetDeviceDefinition(defaultInterfaceHandle, DeviceId, Logger); if (!WriteBufferSizeProtected.HasValue) { if (!connectedDeviceDefinition.WriteBufferSize.HasValue) { throw new ValidationException("Write buffer size not specified"); } WriteBufferSizeProtected = (ushort)connectedDeviceDefinition.WriteBufferSize.Value; } if (!ReadBufferSizeProtected.HasValue) { if (!connectedDeviceDefinition.ReadBufferSize.HasValue) { throw new ValidationException("Read buffer size not specified"); } ReadBufferSizeProtected = (ushort)connectedDeviceDefinition.ReadBufferSize.Value; } //Get the first (default) interface #pragma warning disable CA2000 //Ths should be disposed later var defaultInterface = GetInterface(defaultInterfaceHandle); UsbInterfaces.Add(defaultInterface); byte i = 0; while (true) { isSuccess = WinUsbApiCalls.WinUsb_GetAssociatedInterface(defaultInterfaceHandle, i, out var interfacePointer); if (!isSuccess) { errorCode = Marshal.GetLastWin32Error(); if (errorCode == APICalls.ERROR_NO_MORE_ITEMS) { break; } throw new ApiException( $"Could not enumerate interfaces for device. Error code: {errorCode}"); } var associatedInterface = GetInterface(interfacePointer); //TODO: this is bad design. The handler should be taking care of this UsbInterfaces.Add(associatedInterface); i++; } RegisterDefaultInterfaces(); #pragma warning restore CA2000 } catch (Exception ex) { Logger.LogError(ex, Messages.ErrorMessageCouldntIntializeDevice); throw; } }
public async Task InitializeAsync() { try { if (disposed) { throw new Exception(Messages.DeviceDisposedErrorMessage); } await _InitializingSemaphoreSlim.WaitAsync(); Close(); _UsbDevice = UsbManager.DeviceList.Select(d => d.Value).FirstOrDefault(d => d.DeviceId == DeviceNumberId); if (_UsbDevice == null) { throw new Exception($"The device {DeviceNumberId} is not connected to the system"); } Logger?.Log($"Found device: {_UsbDevice.DeviceName} Id: {_UsbDevice.DeviceId}", nameof(AndroidUsbInterfaceManager), null, LogLevel.Information); var isPermissionGranted = await RequestPermissionAsync(); if (!isPermissionGranted.HasValue) { throw new Exception("User did not respond to permission request"); } if (!isPermissionGranted.Value) { throw new Exception("The user did not give the permission to access the device"); } _UsbDeviceConnection = UsbManager.OpenDevice(_UsbDevice); if (_UsbDeviceConnection == null) { throw new Exception("could not open connection"); } for (var x = 0; x < _UsbDevice.InterfaceCount; x++) { //TODO: This is the default interface but other interfaces might be needed so this needs to be changed. var usbInterface = _UsbDevice.GetInterface(x); var androidUsbInterface = new AndroidUsbInterface(usbInterface, _UsbDeviceConnection, Logger, Tracer, _ReadBufferSize, _WriteBufferSize); UsbInterfaces.Add(androidUsbInterface); for (var y = 0; y < usbInterface.EndpointCount; y++) { var usbEndpoint = usbInterface.GetEndpoint(y); if (usbEndpoint != null) { //TODO: This is probably all wrong... var androidUsbEndpoint = new AndroidUsbEndpoint(usbEndpoint); androidUsbInterface.UsbInterfaceEndpoints.Add(androidUsbEndpoint); } } } Log("Hid device initialized. About to tell everyone.", null); RegisterDefaultInterfaces(); } catch (Exception ex) { Log("Error initializing Hid Device", ex); throw; } finally { _InitializingSemaphoreSlim.Release(); } }
private void Initialize() { try { Close(); int errorCode; if (string.IsNullOrEmpty(DeviceId)) { throw new ValidationException($"{nameof(DeviceDefinitionBase)} must be specified before {nameof(InitializeAsync)} can be called."); } _DeviceHandle = APICalls.CreateFile(DeviceId, FileAccessRights.GenericWrite | FileAccessRights.GenericRead, APICalls.FileShareRead | APICalls.FileShareWrite, IntPtr.Zero, APICalls.OpenExisting, APICalls.FileAttributeNormal | APICalls.FileFlagOverlapped, IntPtr.Zero); if (_DeviceHandle.IsInvalid) { //TODO: is error code useful here? errorCode = Marshal.GetLastWin32Error(); if (errorCode > 0) { throw new ApiException($"Device handle no good. Error code: {errorCode}"); } } Logger?.Log(Messages.SuccessMessageGotWriteAndReadHandle, nameof(WindowsUsbInterfaceManager), null, LogLevel.Information); var isSuccess = WinUsbApiCalls.WinUsb_Initialize(_DeviceHandle, out var defaultInterfaceHandle); WindowsDeviceBase.HandleError(isSuccess, Messages.ErrorMessageCouldntIntializeDevice); var connectedDeviceDefinition = WindowsUsbDeviceFactory.GetDeviceDefinition(defaultInterfaceHandle, DeviceId); if (!_WriteBufferSize.HasValue) { if (!connectedDeviceDefinition.WriteBufferSize.HasValue) { throw new ValidationException("Write buffer size not specified"); } _WriteBufferSize = (ushort)connectedDeviceDefinition.WriteBufferSize.Value; } if (!_ReadBufferSize.HasValue) { if (!connectedDeviceDefinition.ReadBufferSize.HasValue) { throw new ValidationException("Read buffer size not specified"); } _ReadBufferSize = (ushort)connectedDeviceDefinition.ReadBufferSize.Value; } //Get the first (default) interface var defaultInterface = GetInterface(defaultInterfaceHandle); UsbInterfaces.Add(defaultInterface); byte i = 0; while (true) { isSuccess = WinUsbApiCalls.WinUsb_GetAssociatedInterface(defaultInterfaceHandle, i, out var interfacePointer); if (!isSuccess) { errorCode = Marshal.GetLastWin32Error(); if (errorCode == APICalls.ERROR_NO_MORE_ITEMS) { break; } throw new ApiException($"Could not enumerate interfaces for device. Error code: { errorCode}"); } var associatedInterface = GetInterface(interfacePointer); //TODO: this is bad design. The handler should be taking care of this UsbInterfaces.Add(associatedInterface); i++; } RegisterDefaultInterfaces(); } catch (Exception ex) { Logger?.Log($"{nameof(Initialize)} error. DeviceId {DeviceId}", nameof(UsbDevice), ex, LogLevel.Error); throw; } }
public async Task InitializeAsync(CancellationToken cancellationToken = default) { if (disposed) { throw new DeviceException(Messages.DeviceDisposedErrorMessage); } using var logScope = Logger.BeginScope("DeviceId: {deviceId} Call: {call}", DeviceNumberId, nameof(InitializeAsync)); if (IsInitialized) { Logger.LogWarning("Device is already initialized..."); } Logger.LogInformation("Attempting to initialize..."); try { await Task.Run(async() => { Logger.LogTrace("Waiting for initialization lock ... {deviceId}", DeviceNumberId); await _InitializingSemaphoreSlim.WaitAsync(cancellationToken).ConfigureAwait(false); Close(); _UsbDevice = UsbManager.DeviceList.Select(d => d.Value).FirstOrDefault(d => d.DeviceId == DeviceNumberId); if (_UsbDevice == null) { throw new DeviceException($"The device {DeviceNumberId} is not connected to the system"); } Logger.LogInformation("Found device: {deviceName} Id: {deviceId}", _UsbDevice.DeviceName, _UsbDevice.DeviceId); var isPermissionGranted = await RequestPermissionAsync().ConfigureAwait(false); if (!isPermissionGranted.HasValue) { throw new DeviceException("User did not respond to permission request"); } if (!isPermissionGranted.Value) { throw new DeviceException("The user did not give the permission to access the device"); } _UsbDeviceConnection = UsbManager.OpenDevice(_UsbDevice); if (_UsbDeviceConnection == null) { throw new DeviceException("could not open connection"); } Logger.LogInformation("Interface count: {count}", _UsbDevice.InterfaceCount); for (var interfaceNumber = 0; interfaceNumber < _UsbDevice.InterfaceCount; interfaceNumber++) { //TODO: This is the default interface but other interfaces might be needed so this needs to be changed. var usbInterface = _UsbDevice.GetInterface(interfaceNumber); var androidUsbInterface = new AndroidUsbInterface( usbInterface, _UsbDeviceConnection, _androidFactory, LoggerFactory.CreateLogger <AndroidUsbInterface>(), ReadBufferSizeProtected, WriteBufferSizeProtected); Logger.LogInformation("Interface found. Id: {id} Endpoint Count: {endpointCount} Interface Class: {interfaceclass} Interface Subclass: {interfacesubclass} Name: {name}", usbInterface.Id, usbInterface.EndpointCount, usbInterface.InterfaceClass, usbInterface.InterfaceSubclass, usbInterface.Name); UsbInterfaces.Add(androidUsbInterface); for (var endpointNumber = 0; endpointNumber < usbInterface.EndpointCount; endpointNumber++) { var usbEndpoint = usbInterface.GetEndpoint(endpointNumber); if (usbEndpoint == null) { continue; } var androidUsbEndpoint = new AndroidUsbEndpoint(usbEndpoint, interfaceNumber, LoggerFactory.CreateLogger <AndroidUsbEndpoint>()); androidUsbInterface.UsbInterfaceEndpoints.Add(androidUsbEndpoint); } await androidUsbInterface.ClaimInterface().ConfigureAwait(false); } RegisterDefaultInterfaces(); Logger.LogInformation("Device initialized successfully."); }, cancellationToken).ConfigureAwait(false); } catch (Exception ex) { Logger.LogError(ex, "Error initializing device"); throw; } finally { Logger.LogTrace("Releasing initialization lock"); _ = _InitializingSemaphoreSlim.Release(); } }
public async Task InitializeAsync(CancellationToken cancellationToken = default) { if (disposed) { throw new ValidationException(Messages.DeviceDisposedErrorMessage); } await Task.Run(() => { //TODO: Error handling etc. _ = UsbDevice.Open(); switch (UsbDevice) { //TODO: This is far beyond not cool. case MonoUsbDevice monoUsbDevice: _ = monoUsbDevice.ClaimInterface(0); break; case WinUsbDevice winUsbDevice: //Doesn't seem necessary in this case... break; default: _ = ((IUsbDevice)UsbDevice).ClaimInterface(0); break; } foreach (var usbConfigInfo in UsbDevice.Configs) { foreach (var usbInterfaceInfo in usbConfigInfo.InterfaceInfoList) { //Create an interface. var usbInterface = new UsbInterface(UsbDevice, usbInterfaceInfo.Descriptor.InterfaceID, null, null, Logger, Timeout); UsbInterfaces.Add(usbInterface); ReadUsbInterface ??= usbInterface; WriteUsbInterface ??= usbInterface; //Write endpoint var usbEndpointWriter = UsbDevice.OpenEndpointWriter(WriteEndpointID.Ep01); var writeBufferSize = _writeBufferSize ?? 64; var writeEndpoint = new WriteEndpoint(usbEndpointWriter, writeBufferSize); usbInterface.UsbInterfaceEndpoints.Add(writeEndpoint); usbInterface.WriteEndpoint ??= writeEndpoint; //Read endpoint var usbEndpointReader = UsbDevice.OpenEndpointReader(ReadEndpointID.Ep01); var readBufferSize = _readBufferSize ?? 64; var readEndpoint = new ReadEndpoint(usbEndpointReader, readBufferSize); usbInterface.UsbInterfaceEndpoints.Add(readEndpoint); usbInterface.ReadEndpoint ??= readEndpoint; //int endpointCount = usbInterfaceInfo.EndpointInfoList.Count; /* * for (var i = 0; i < endpointCount; i++) * { * var usbEndpointInfo = usbInterfaceInfo.EndpointInfoList[i]; * * //var IsWrite = (usbEndpointInfo.Descriptor.EndpointID & 128) == 0; * //var IsRead = (usbEndpointInfo.Descriptor.EndpointID & 128) != 0; * * //Write endpoint * //var id = usbEndpointInfo.Descriptor.EndpointID ^ 128; * //var writeEndpointID = (WriteEndpointID)Enum.Parse(typeof(WriteEndpointID), $"Ep{id.ToString().PadLeft(2, '0')}"); * var usbEndpointWriter = UsbDevice.OpenEndpointWriter(WriteEndpointID.Ep01); * var writeBufferSize = _WriteBufferSize ?? (ushort)usbEndpointInfo.Descriptor.MaxPacketSize; * var writeEndpoint = new WriteEndpoint(usbEndpointWriter, writeBufferSize); * usbInterface.UsbInterfaceEndpoints.Add(writeEndpoint); * if (usbInterface.WriteEndpoint == null) usbInterface.WriteEndpoint = writeEndpoint; * * //Read endpoint * //var id = usbEndpointInfo.Descriptor.EndpointID ^ 1; * //var readEndpointID = (ReadEndpointID)Enum.Parse(typeof(ReadEndpointID), $"Ep{id.ToString().PadLeft(2, '0')}"); * var usbEndpointReader = UsbDevice.OpenEndpointReader(ReadEndpointID.Ep01); * var readBufferSize = _ReadBufferSize ?? (ushort)usbEndpointInfo.Descriptor.MaxPacketSize; * var readEndpoint = new ReadEndpoint(usbEndpointReader, readBufferSize); * usbInterface.UsbInterfaceEndpoints.Add(readEndpoint); * if (usbInterface.ReadEndpoint == null) usbInterface.ReadEndpoint = readEndpoint; * } */ } ReadUsbInterface = UsbInterfaces[0]; WriteUsbInterface = UsbInterfaces[0]; } IsInitialized = true; }, cancellationToken).ConfigureAwait(false); }