internal async Task <string> SendCommandAsync(DeviceSelector deviceSelector, IEnumerable <HwiOption> options, HwiCommands?command, string[] commandArguments, CancellationToken cancel) { try { return(await SendCommandCoreAsync(deviceSelector, options, command, commandArguments, cancel).ConfigureAwait(false)); } catch (Exception ex) when(ex is OperationCanceledException || ex is TaskCanceledException || ex is TimeoutException) { throw new OperationCanceledException($"'hwi operation is canceled.", ex); } // HWI is inconsistent with error codes here. catch (HwiException ex) when(ex.ErrorCode == HwiErrorCode.DeviceConnError || ex.ErrorCode == HwiErrorCode.DeviceNotReady) { // Probably didn't find device with specified fingerprint. // Enumerate and call again, but not forever. if (!(deviceSelector is FingerprintDeviceSelector)) { throw; } IEnumerable <HwiEnumerateEntry> hwiEntries = await EnumerateEntriesAsync(cancel); // Trezor T won't give Fingerprint info so we'll assume that the first device that doesn't give fingerprint is what we need. HwiEnumerateEntry firstNoFingerprintEntry = hwiEntries.Where(x => x.Fingerprint is null).FirstOrDefault(); if (firstNoFingerprintEntry is null) { throw; } deviceSelector = DeviceSelectors.FromDeviceType(firstNoFingerprintEntry.Model, firstNoFingerprintEntry.Path); return(await SendCommandCoreAsync(deviceSelector, options, command, commandArguments, cancel).ConfigureAwait(false)); } }
public HwiEnumerateEntry( HardwareWalletModels model, string path, string serialNumber, HDFingerprint?fingerprint, bool?needsPinSent, bool?needsPassphraseSent, string error, HwiErrorCode?code) { Model = model; Path = path; SerialNumber = serialNumber; Fingerprint = fingerprint; NeedsPinSent = needsPinSent; NeedsPassphraseSent = needsPassphraseSent; Error = error; Code = code; DeviceSelector = fingerprint is HDFingerprint fp?DeviceSelectors.FromFingerprint(fp) : DeviceSelectors.FromDeviceType(Model, path); }