private async void HandleWiteTag(INFCMiFareTag nMifareTag) { byte[] data = await Read4Pages(nMifareTag, 0); // write if (data != null) { byte[] FirstTag = MainTabViewModel.Current?.DataBag.GetData(); byte[] mem = new byte[80]; data.CopyTo(mem, 0); byte[] dstData = MainTabViewModel.MergeTagData(FirstTag, mem); bool result = true; for (byte i = 4; result && (i < 16); i++) { result = await WritePage(nMifareTag, i, dstData.Skip(4 * i).Take(4).ToArray()); } if (result) { MainTabViewModel.Current?.DataBag.SetData(dstData); } } MainTabViewModel.Current.cbNFCRead = false; MainTabViewModel.Current.cbNFCWrite = false; }
private async void HandleReadTag(INFCMiFareTag nMifareTag) { byte[] FirstTag = MainTabViewModel.Current?.DataBag.GetData(); byte[] data = await Read4Pages(nMifareTag, 4); if (data != null) { data.CopyTo(FirstTag, 16); data = await Read4Pages(nMifareTag, 8); if (data != null) { data.CopyTo(FirstTag, 32); data = await Read4Pages(nMifareTag, 12); if (data != null) { data.CopyTo(FirstTag, 48); MainThread.BeginInvokeOnMainThread(() => MainTabViewModel.Current?.SetControlsVisibility(FirstTag[41])); MainTabViewModel.Current?.DataBag.SetData(FirstTag); } } } MainTabViewModel.Current.cbNFCRead = false; MainTabViewModel.Current.cbNFCWrite = false; }
public static async Task <byte[]> DoFastRead( this INFCMiFareTag tag, byte from, byte to, byte batchSize) { var results = new List <MifareCommandResult>(); while (from < to) { var thisTo = (byte)Math.Min(from + batchSize, to); var data = await tag.SendMifareCommand(0x3a, from, thisTo); results.Add(data); from = (byte)(from + (byte)(batchSize + 0x1)); } if (results.Any(x => x.Error != null)) { throw new Exception($"Failed to fast read; first error: {results.First(x => x.Error != null).Error}"); } var all = MifareCommandResult.Combine(results); return(all.Data); }
public Task <bool> WritePage(INFCMiFareTag tag, byte page, byte [] data) { var tcs = new TaskCompletionSource <bool>(); tag.SendMiFareCommand(NSData.FromArray(new byte[] { 0xA2, page, data[0], data[1], data[2], data[3] }), (tagdata, error) => tcs.SetResult((tagdata != null) && (error == null) && (tagdata.Count() == 1))); return(tcs.Task); }
public static Task <MifareCommandResult> SendMifareCommand( this INFCMiFareTag tag, params byte[] command) { var tcs = new TaskCompletionSource <MifareCommandResult>(); tag.SendMiFareCommand( NSData.FromArray(command), (data, err) => tcs.SetResult(MifareCommandResult.From(data, err))); return(tcs.Task); }
public static async Task <byte[]> WritePage( this INFCMiFareTag tag, byte page, byte[] data) { var cmd = new byte[] { 0xa2, (byte)(page) }.Concat(data).ToArray(); var result = await tag.SendMifareCommand(cmd); if (result.Error != null) { Debug.WriteLine(result.Error); } return(result.Data); }
public Task <byte[]> Read4Pages(INFCMiFareTag tag, byte page) { var tcs = new TaskCompletionSource <byte[]>(); tag.SendMiFareCommand(NSData.FromArray(new byte[] { 0x30, page }), (data, error) => { if ((data != null) && (error == null) && (data.Count() == 16)) { tcs.SetResult(data.ToArray()); } else { tcs.SetResult(null); } }); return(tcs.Task); }
public async Task WriteAmiibo(NFCTagReaderSession session, INFCMiFareTag tag, DetectedAmiibo amiibo) { var dynamicLockBytes = new byte[] { 0x01, 0x00, 0x0F, 0xBD }; var staticLockBytes = new byte[] { 0x0F, 0xE0, 0x0F, 0xE0 }; var dump = amiibo.TagData; // this is ille🚨al so i took it out, but the flow is: // 1. make a copy of the tag dump // 2. decrypt the encrypted part of the tag dump using the original tag uid and secret nintendo key material // 3. reencrypt the now decrypted parts of the tag dump using the uid of the target tag and secret nintendo key material // 4. write the tag dump (not the lock bits) to the tag // 5. write the dynamic lock bits to 0x82 // 6. write the static lock bits to 0x2 // 7. draw the amiibo on the card for good luck // check https://www.3dbrew.org/wiki/Amiibo for amiibo data structure // check https://github.com/AcK77/AmiiBomb-uino for a good cloning reference await Task.Yield(); session.AlertMessage = "Various implementation details removed and left to the reader (check the source)."; }