Reputation: 925
Recently I am trying to read a MifareClassic 1K card. After reading about the fact, that only certain phones with NXP chips are able to read those tags, and getting one of those I am facing a new problem.
The card I am trying to read throws the error mentioned in the title but only when running without stepping through the code.
Here some details:
At first, I took the NFCSample from Xamarin and changed some things:
protected override void OnNewIntent(Intent intent)
{
if(_inWriteMode)
{
_inWriteMode = false;
var tag = intent.GetParcelableExtra(NfcAdapter.ExtraTag) as Tag;
if(tag == null)
{
return;
}
MifareClassic mifc = MifareClassic.Get(tag);
DisplayMessage("NFC recognized");
try
{
mifc.ConnectAsync().Wait();
DisplayMessage("Connected to Mifare Tag");
DisplayMessage("SectorCount:" + mifc.SectorCount);
DisplayMessage("BlockCount in Sector 1:" + mifc.GetBlockCountInSector(1));
byte[] blargh = new byte[6];
MifareClassic.KeyDefault.CopyTo(blargh,0);
if(Task.Factory.StartNew<bool>(() => mifc.AuthenticateSectorWithKeyA(1, blargh)).Result)
{
DisplayMessage("Auth A Complete");
blargh = new byte[6];
MifareClassic.KeyDefault.CopyTo(blargh, 0);
if(Task.Factory.StartNew<bool>(() => mifc.AuthenticateSectorWithKeyB(1, blargh)).Result)
{
DisplayMessage("Auth B Complete");
DisplayMessage("Read All Blocks of Section 1 ...");
int firstBlock = mifc.SectorToBlock(1);
int lastBlock = firstBlock + 3;
List<byte[]> lstBlocks = new List<byte[]>();
for(int i = firstBlock; i < lastBlock; i++)
{
DisplayMessage("Read Block " + i);
byte[] block = mifc.ReadBlockAsync(i).Result; //fails without stepping through in Debug mode
lstBlocks.Add(block);
}
string BlockData = string.Empty;
foreach(var item in lstBlocks)
{
BlockData += Encoding.ASCII.GetString(item) + "\r\n";
}
DisplayMessage(BlockData);
}
}
DisplayMessage("Close Connection");
mifc.Close();
}
catch(Exception ex)
{
DisplayMessage(ex.ToString());
}
}
}
So, if I step through the code ReadBlock/ReadBlockAsync works perfectly fine. Without breakpoints it will throw the exception mentioned above. Whats wrong here?
Edit: The StackTraces of the Exceptions: Outer Exception:
One or more errors occurred.
at System.Threading.Tasks.Task.ThrowIfExceptional (Boolean includeTaskCanceledExceptions) [0x00014] in <filename unknown>:0
at System.Threading.Tasks.Task`1[System.Byte[]].GetResultCore (Boolean waitCompletionNotification) [0x00034] in <filename unknown>:0
at System.Threading.Tasks.Task`1[System.Byte[]].get_Result () [0x0000b] in <filename unknown>:0
at NfcXample.MainActivity.OnNewIntent (Android.Content.Intent intent) [0x001d0] in c:\\Users\\user\\Desktop\\monodroid-samples-master\\NfcSample\\MainActivity.cs:94 "
Inner Exception:
Exception of type 'Java.IO.IOException' was thrown.
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000b] in <filename unknown>:0
at Android.Runtime.JNIEnv.CallObjectMethod (IntPtr jobject, IntPtr jmethod, Android.Runtime.JValue* parms) [0x00064] in /Users/builder/data/lanes/monodroid-mavericks-monodroid-5.1-series/d419c934/source/monodroid/src/Mono.Android/src/Runtime/JNIEnv.g.cs:195
at Android.Nfc.Tech.MifareClassic.ReadBlock (Int32 p0) [0x00044] in /Users/builder/data/lanes/monodroid-mavericks-monodroid-5.1-series/d419c934/source/monodroid/src/Mono.Android/platforms/android-10/src/generated/Android.Nfc.Tech.MifareClassic.cs:360
at Android.Nfc.Tech.MifareClassic+<ReadBlockAsync>c__AnonStorey2.<>m__0 () [0x00000] in /Users/builder/data/lanes/monodroid-mavericks-monodroid-5.1-series/d419c934/source/monodroid/src/Mono.Android/platforms/android-10/src/generated/Android.Nfc.Tech.MifareClassic.cs:367
at System.Threading.Tasks.Task`1[System.Byte[]].InnerInvoke () [0x00012] in <filename unknown>:0
at System.Threading.Tasks.Task.Execute () [0x00016] in <filename unknown>:0
--- End of managed exception stack trace ---
java.io.IOException: Transceive failed
at android.nfc.TransceiveResult.getResponseOrThrow(TransceiveResult.java:52)
at android.nfc.tech.BasicTagTechnology.transceive(BasicTagTechnology.java:151)
at android.nfc.tech.MifareClassic.readBlock(MifareClassic.java:425)
at dalvik.system.NativeStart.run(Native Method)
Upvotes: 3
Views: 2868
Reputation: 925
IT'S TOO FAST!
The device is reading the card to damn fast. After inserting a System.Threading.Thread.Sleep(100)
it finally worked! The for-loop now looks like this:
for(int i = firstBlock; i < lastBlock; i++)
{
if(mifc.IsConnected)
{
DisplayMessage("Read Block " + i);
System.Threading.Thread.Sleep(100);
byte[] block = mifc.ReadBlockAsync(i).Result;
lstBlocks.Add(block);
}
else
{
DisplayMessage("Card Disconnected");
}
}
Upvotes: 2