private void HandleHCEClient(ICardReader reader) { StatusMessage?.Invoke("Attemtping to talk to Android HCE device."); var selectCmd = new Iso7816.SelectCommand(FLAGCARRIER_HCE_AID, 0); var res = reader.Transceive(selectCmd); if (res.SW == 0x6a82) { ErrorMessage?.Invoke("Device has no idea who we are."); return; } else if (!res.Succeeded) { ErrorMessage?.Invoke("Failed communicating with device: " + res.ToString()); return; } StatusMessage?.Invoke("Connected to FlagCarrier HCE device!"); byte[] challengeToken = new byte[32]; random.NextBytes(challengeToken, 0, challengeToken.Length); var updateCmd = new Iso7816.UpdateBinaryCommand(challengeToken); res = reader.Transceive(updateCmd); if (res.SW == 0x6A82) { ErrorMessage?.Invoke("HCE Device does not have any data for us."); return; } if (!res.Succeeded) { ErrorMessage?.Invoke("Failed sending challenge token: " + res.ToString()); return; } StatusMessage?.Invoke("Sent challenge token."); byte[] ndefData = new byte[0]; const int len = 250; int offset = 0; do { var readCmd = new Iso7816.ReadBinaryCommand(len, offset); res = reader.Transceive(readCmd); if (!res.Succeeded) { ErrorMessage?.Invoke("Failed reading data at " + offset + ": " + res.ToString()); return; } if (res.ResponseData == null || res.ResponseData.Length == 0) { break; } Array.Resize(ref ndefData, ndefData.Length + res.ResponseData.Length); res.ResponseData.CopyTo(ndefData, offset); offset += res.ResponseData.Length; } while (res.ResponseData.Length == len); StatusMessage?.Invoke("Read " + ndefData.Length + " bytes of ndef data from device."); NdefMessage msg = NdefMessage.FromByteArray(ndefData); NewTagUid?.Invoke(challengeToken); ReceiveNdefMessage?.Invoke(msg); var eraseCmd = new Iso7816.EraseBinaryCommand(); res = reader.Transceive(eraseCmd); if (!res.Succeeded) { ErrorMessage?.Invoke("Failed confirming transaction to device."); } }