async Task UnlockByRfid(string rfid) { if (!isRunning) { return; } if (!_rfidSettingsManager.Settings.IsRfidEnabled) { return; } if (Interlocked.CompareExchange(ref _isConnecting, 1, 1) == 1) { return; } HwVaultShortInfoFromHesDto info = null; try { _screenActivator?.ActivateScreen(); if (_hesConnection == null) { throw new Exception(TranslationSource.Instance["ConnectionFlow.RfidConnection.Error.NotConnectedToHes"]); } // get MAC address from the HES info = await _hesConnection.GetHwVaultInfoByRfid(rfid); await _clientUiManager.SendNotification(TranslationSource.Instance["ConnectionFlow.RfidConnection.ContactingHesMessage"], info.VaultMac); if (Interlocked.CompareExchange(ref _isConnecting, 1, 0) == 0) { try { await _connectionFlowProcessor.ConnectAndUnlock(info.VaultMac, OnUnlockAttempt); } catch (Exception) { // Silent handling. Log is already printed inside of _connectionFlowProcessor.ConnectAndUnlock() } finally { // this delay allows a user to move away the device from the rfid // and prevents the repeated call of this method await Task.Delay(SdkConfig.DelayAfterMainWorkflow); Interlocked.Exchange(ref _isConnecting, 0); } } } catch (Exception ex) { WriteLine(ex); await _clientUiManager.SendError(HideezExceptionLocalization.GetErrorAsString(ex), info?.VaultMac); } }
async Task SetPinWorkflow(IDevice device, int timeout, CancellationToken ct) { Debug.WriteLine(">>>>>>>>>>>>>>> SetPinWorkflow +++++++++++++++++++++++++++++++++++++++"); await _ui.SendNotification(TranslationSource.Instance.Format("ConnectionFlow.Pin.NewPinMessage", device.MinPinLength), device.Mac); while (device.AccessLevel.IsNewPinRequired) { string pin = await _ui.GetPin(device.Id, timeout, ct, withConfirm : true); ct.ThrowIfCancellationRequested(); if (string.IsNullOrWhiteSpace(pin)) { // we received an empty PIN from the user. Trying again with the same timeout. WriteLine("Received empty PIN"); continue; } var pinResult = await device.SetPin(pin); //this using default timeout for BLE commands ct.ThrowIfCancellationRequested(); if (pinResult == HideezErrorCode.Ok) { Debug.WriteLine($">>>>>>>>>>>>>>> PIN OK"); break; } else if (pinResult == HideezErrorCode.ERR_PIN_TOO_SHORT) { await _ui.SendError(TranslationSource.Instance["ConnectionFlow.Pin.Error.PinToShort"], device.Mac); } else if (pinResult == HideezErrorCode.ERR_PIN_WRONG) { await _ui.SendError(TranslationSource.Instance["ConnectionFlow.Pin.Error.WrongPin"], device.Mac); } } Debug.WriteLine(">>>>>>>>>>>>>>> SetPinWorkflow ---------------------------------------"); }
async Task WorkflowCleanup(string errorMessage, string mac, IDevice device, bool workflowFinishedSuccessfully, bool deleteVaultBond) { // Cleanup try { await _ui.HidePinUi(); if (!string.IsNullOrEmpty(errorMessage)) { if (device != null && !string.IsNullOrWhiteSpace(device.SerialNo)) { var sb = new StringBuilder(); sb.Append(errorMessage); sb.Append(Environment.NewLine); sb.Append(Environment.NewLine); sb.Append(string.Format(TranslationSource.Instance["ConnectionFlow.VaultSerialNo"], device.SerialNo)); errorMessage = sb.ToString(); } WriteLine(errorMessage); await _ui.SendError(errorMessage, mac); } if (device != null) { if (workflowFinishedSuccessfully) { WriteLine($"Successfully finished the main workflow: ({device.Id})"); DeviceFinishedMainFlow?.Invoke(this, device); } else if (deleteVaultBond) { WriteLine($"Mainworkflow critical error, Removing ({device.Id})"); await _deviceManager.Remove(device); } else { WriteLine($"Main workflow failed, Disconnecting ({device.Id})"); await _deviceManager.DisconnectDevice(device); } } } catch (Exception ex) { WriteLine(ex, LogErrorSeverity.Error); } }
public async Task <HwVaultInfoFromHesDto> ActivateVault(IDevice device, HwVaultInfoFromHesDto vaultInfo, CancellationToken ct) { HwVaultInfoFromHesDto newVaultInfo = null; if (device.IsLocked && device.IsCanUnlock) { try { do { ct.ThrowIfCancellationRequested(); var code = await _ui.GetActivationCode(device.Id, 30_000, ct); // Todo: activation timeout should not be a magic number ct.ThrowIfCancellationRequested(); if (code.Length < 6) { await _ui.SendError(TranslationSource.Instance["ConnectionFlow.ActivationCode.Error.CodeToShort"], device.Mac); continue; } if (code.Length > 8) { await _ui.SendError(TranslationSource.Instance["ConnectionFlow.ActivationCode.Error.CodeToLong"], device.Mac); continue; } try { await device.UnlockDeviceCode(code); } catch (HideezException ex) when(ex.ErrorCode == HideezErrorCode.ERR_PIN_WRONG) // Entered invalid activation code { } catch (HideezException ex) when(ex.ErrorCode == HideezErrorCode.ERR_DEVICE_LOCKED_BY_CODE) // Unlock attempts == 0 { throw new WorkflowException(TranslationSource.Instance["ConnectionFlow.ActivationCode.Error.LockedByInvalidAttempts"]); } ct.ThrowIfCancellationRequested(); await device.RefreshDeviceInfo(); ct.ThrowIfCancellationRequested(); if (!device.IsLocked) { WriteLine($"({device.SerialNo}) unlocked with activation code"); } else if (device.UnlockAttemptsRemain > 0) { await _ui.SendNotification(TranslationSource.Instance.Format("ConnectionFlow.ActivationCode.Error.InvalidCode", device.UnlockAttemptsRemain), device.Mac); } else { // We won't reach this line, but will leave it just in case throw new WorkflowException(TranslationSource.Instance["ConnectionFlow.ActivationCode.Error.LockedByInvalidAttempts"]); } }while (device.IsLocked); } catch { if (_hesConnection.State == HesConnectionState.Connected) { await _hesConnection.UpdateHwVaultStatus(new HwVaultInfoFromClientDto(device), ct); } throw; } finally { await _ui.HideActivationCodeUi(); } if (_hesConnection.State == HesConnectionState.Connected) { newVaultInfo = await _hesConnection.UpdateHwVaultStatus(new HwVaultInfoFromClientDto(device), ct); } } if (device.IsLocked) { if (_hesConnection.State == HesConnectionState.Connected) { throw new WorkflowException(TranslationSource.Instance["ConnectionFlow.ActivationCode.Error.VaultIsLocked"]); } else { throw new WorkflowException(TranslationSource.Instance["ConnectionFlow.ActivationCode.Error.VaultIsLockedNoNetwork"]); } } return(newVaultInfo ?? vaultInfo); }