private void StartConversation(MifareTypeResponse requestResponse, MifareReadCallback callback) { sendLedRequest(LEDColor.BLUE_ON_RED_OFF); // Start anticollistion (and get serialNo) AnticollisionResponse collisionResponse = null; //for(int retryCount = 0; retryCount < RETRY_COUNT; retryCount++) { collisionResponse = sendMifareAnticollisionRequest(); if (collisionResponse.Response == Response.OK) { uint serialNo = ReverseBytes(collisionResponse.SerialNo); Console.WriteLine("Card detected, type={0}, serialNo={1}", requestResponse.MifareType, serialNo); SelectResponse selectResponse = sendMifareSelect(collisionResponse.SerialNo); if (selectResponse.Response != Response.OK) { throw new Exception("Mifare select error!"); } Console.WriteLine("Card {0} selected and active", serialNo); //callback.status(BitConverter.GetBytes(collisionResponse.SerialNo).ToHex()); DateTime before = DateTime.Now; Console.WriteLine(); callback.status(String.Format("Reading card {0} with serialno. {1}", requestResponse.MifareType, serialNo)); int lastAuthorizedSectorIndex = -1; for (int blockIndex = 0; blockIndex < getBlockCount(requestResponse.MifareType); blockIndex++) { if (cancellationToken.IsCancellationRequested) { // Clean up here, then... //cancellationToken.ThrowIfCancellationRequested(); callback.status("Reading of card interupted by user!"); callback.error(); return; } int sectorIndex = getSectorIndexByBlockIndex(blockIndex); // If we haven't authorized for this sector before if (sectorIndex != lastAuthorizedSectorIndex) { lastAuthorizedSectorIndex = sectorIndex; //Console.WriteLine("Autorizing sector {0} for block starting at index {1}", sectorIndex, blockIndex); if (callback.getAuthByKeyA()) { MifareResponse auth = sendAuth((byte)blockIndex, AuthMode.KEY_A, getRejsekortKeyByBlock(AuthMode.KEY_A, blockIndex)); if (auth.Response == Response.ERR_AUTH_FAILURE) { var response = sendMifareRequest(MifareRequestCode.IDLE_CARD).Response; callback.status(string.Format("Error while trying to authorize sector {0} with A-key {1}", getSectorIndexByBlockIndex(blockIndex), getRejsekortKeyByBlock(AuthMode.KEY_A, blockIndex).ToHex())); callback.error(); return; } } if (callback.getAuthByKeyB()) { MifareResponse auth = sendAuth((byte)blockIndex, AuthMode.KEY_B, getRejsekortKeyByBlock(AuthMode.KEY_B, blockIndex)); if (auth.Response == Response.ERR_AUTH_FAILURE) { var response = sendMifareRequest(MifareRequestCode.IDLE_CARD).Response; callback.status(string.Format("Error while trying to authorize sector {0} with B-key {1}", getSectorIndexByBlockIndex(blockIndex), getRejsekortKeyByBlock(AuthMode.KEY_A, blockIndex).ToHex())); callback.error(); return; } } } { ReadResponse read = sendRead((byte)blockIndex); // If this block is a sector trailer if (getSectorIndexByBlockIndex(blockIndex + 1) != sectorIndex) { // If keys are supposed to be included in data if (callback.getInclKeys()) { // If authorizing with key A is enabled if (callback.getAuthByKeyA()) { Buffer.BlockCopy(callback.getKeyABySector(sectorIndex), 0, read.Data, 0, 6); } // If authorizing with key B is enabled if (callback.getAuthByKeyB()) { Buffer.BlockCopy(callback.getKeyBBySector(sectorIndex), 0, read.Data, 10, 6); } } } callback.completeBlock(blockIndex, read.Data); //Console.WriteLine("Copying {0} bytes over to index {1}", 16, (blockIndex*16)); Buffer.BlockCopy(read.Data, 0, buffer, blockIndex * 16, 16); } } DateTime after = DateTime.Now; TimeSpan span = after - before; //Console.WriteLine ("Auth took {0} ms", span.TotalMilliseconds); // Done with card, halt session if (sendHalt().Response == Response.OK) { // Turn BLUE LED on to signal All OK //sendLedRequest (LEDColor.BLUE_ON_RED_OFF); sendBeepRequest(BeepType.SHORT_60MS); //Thread.Sleep (500); // Revert to normal LED state off sendLedRequest(LEDColor.ALL_LED_OFF); callback.status(String.Format("Card read in {0},{1} sec.", span.Seconds, span.Milliseconds)); } else { //sendLedRequest(LEDColor.RED_ON_BLUE_OFF); } MD5 md5 = System.Security.Cryptography.MD5.Create(); string hash = md5.ComputeHash(buffer).ToHex(); callback.success(serialNo, hash); return; } }; }