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();
            }
        }
Example #2
0
        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();
            }
        }