25

I have reader which has doc almost exact as this one: http://www.jinmuyu.com/download/JMY680A_EN.pdf main difference being, my reader claims it supports also TYPE B cards.

I have three ISO 14443 cards, which I test consecutively, and following code:

   byte[] rs = null;

   Thread.Sleep(500);

   // Set module Idle 
   Random r = new Random();
   byte rInt = (byte) r.Next(0, 255);
   rs = send(new byte[] { 0x12, rInt });
   if (rs[1] == 0xED)
       throw new Exception("Failed set idle");

   Thread.Sleep(500);

   //// Request B
   //rs = send(new byte[] { 0x60, 0x00, 0x00 });
   //if (rs[1] == 0x9F)
   //    throw new Exception("Failed card requestB"); 

   // RequestA
   rs = send(new byte[] { 0x20, 0x00 });
   if (rs[1] == 0xDF)
       throw new Exception("Failed card requestA");

    // Reset cardA
    rs = send(new byte[] { 0x30 });
    if(rs[1] == 0xCF)
        throw new Exception("Failed card reset");

     // Do other work, Send some APDU to card, etc.
     // ........


     // Exit program

Most of the time, this code works well with all three cards. However, sometimes, when I bring one of the card near reader, the Card Request A (RequestA call) call fails. It will then always fail with this card, until I bring a new card to the reader. Does anyone have any idea what can be causing this? Maybe I need some delays between calls? Or need to call some other (ISO14443 related) function before calling RequestA?

send is method implemented using SerialPort class. In the following way:

  1. On each invocation of send, new SerialPort object is created
  2. Call Open on object created above
  3. Write and Read some data
  4. Close the connection using Close on object which was created in this method instance

btw. this is successful response from one of the cards (on which reader failed once) on RequestA command:

ID                 | ATQ     | SAK
0xe1 0x8f 0x68 0xe6 0x04 0x00 0x28
Ian Kemp
  • 28,293
  • 19
  • 112
  • 138
  • 2
    What do you mean by "fail"? The card answers with an error, or do you have no answer at all, or do you have a comm error from the serial? – Lorenzo Dematté May 29 '14 at 09:58
  • 1
    @LorenzoDematté: I mean with fail the exception gets thrown. According to doc, if card returns `0xDF` as second byte, it means failure. –  May 29 '14 at 10:00
  • I see.. It can be a number of things. The 0x20 command seems specific to your reader, it probably does and ISO / Mifare commands to select (activate) the card. Iso and desfire commands have some different error codes, depending on the error, but ... it seems you are alone with what the reader tells (or do not tell) you – Lorenzo Dematté May 29 '14 at 10:10
  • That's one problem with "cheap" readers: they implement their own protocol, and then you have to deal with what you get. That error may be a card error, a communication error, whatever.. Wait: I have seen your edit. Is that a "correct" response you got from one of the cards? – Lorenzo Dematté May 29 '14 at 10:11
  • @LorenzoDematté: I am not sure if this is a correct response, this is just a response I managed to record when one of the cards didn't return error on `RequestA` command... –  May 29 '14 at 10:14
  • It seems so... And I guess you are using a Mifare Classic card? (UID of 4 bytes). It looks OK, the card should now be selected and you can proceed with what you need (authentication, read, write..) – Lorenzo Dematté May 29 '14 at 10:16
  • @LorenzoDematté: Dear Lorenzo, no these are EMV cards. Yes, indeed it was selected and I can proceed normally. But when I bring another card to reader, read that one, then bring another card, and try to do the same - suddenly Request A will fail (and that is what is driving me mad); it's more like randomly can't deduce when it fails, sometimes it will read all three well, and once then it will fail –  May 29 '14 at 10:18
  • 2
    Oh, OK. Mifare classic are... strange things. Almost type A, but with their own set of commands. But usually quite reliable. But I digress (they are the only cards I know with 4 bytes UID). What happens when, upon failure, you try again? Is the reader in continuous polling (will it try to select the card again?). You have to consider that transmission in a PICC can be highly unreliable, so trying 2/3 times before failing is quite normal. – Lorenzo Dematté May 29 '14 at 10:20
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/54707/discussion-between-lorenzo-dematte-and-dmcr-code). – Lorenzo Dematté May 29 '14 at 10:22
  • ps. problem not solved yet –  May 29 '14 at 12:49
  • @dmcr_code What types of cards are you using (don't tell me they are ISO 14443A, I know that, I want an exact type)? What is the exact flow that leads to the problem (your question is not quite clear on that and the comment thread is too long to properly follow)? – Michael Roland Jun 03 '14 at 15:06
  • @MichaelRoland: Is ATQ and SAK I posted in question not enough? What you mean with exact type? I will let you know more details when I get access to reader. btw. These are contactless EMV cards (MasterCard, Visa). About when it gets stuck: When I put card near reader, then run the code I posted in question - requestA will return error code 0xDF. Like I said, many times this might not fail, but on one occasion it might fail - and then if I restart the program, it still fails on the *same* card –  Jun 04 '14 at 06:43

2 Answers2

1

I can't be sure what the issue is from your code, but it seems to be a problem when a connection gets a error there is no new connection opened. Because a SerialPort is an hardware resource you will need to handle the dispose, the SerialPort probably implements IDisposable, which means you can use using be sure the connection is closed and disposed. Bring a new card will probably do this, however when you use the same card, you still working with the serial port in a fault state.

Peter
  • 27,590
  • 8
  • 64
  • 84
  • please see my comment to jhonnash below. By bringing card to reader second time - this happens after I restart my program and run the code above from the beginning - do you think in this case Dispose can still be a problem? –  Jun 03 '14 at 11:04
  • Yes it could, the serialport could have some state which is not reset correctly. See it it implements IDisposable and if so, use `using` blocks. – Peter Jun 03 '14 at 11:43
  • I am a bit new to C#. I found this: http://msdn.microsoft.com/en-us/library/3cc9y48w.aspx You suggest I call this after `SerialPort.Close()` method? –  Jun 03 '14 at 11:51
  • also note if *Failed card requestA* exception is thrown as in code by me - by that time port should be closed in previous `send` call, but I will check your suggestion –  Jun 03 '14 at 12:24
0

While you bring cardA near the card reader and it fails. After that every time you bring the cardA near to card reader it fails.

I am not sure but I am guessing when any it fails 2nd position of byte array rs[1] contain the code for failure. So, after that every time you bring the cardA near to card reader it fails because byte array 2nd position might have previous value.

So, try with clearing the byte array that might solve your problem.

suneet saini
  • 592
  • 3
  • 16
  • by second time bringing same card to reader, I mean when I exit the program and run it once again -then rs can't have old value right? (because you can see there is no loop - so I can only bring card to reader if I restart the program) –  Jun 03 '14 at 11:00
  • Will it accepts it in 3 to 4 trials after that or the scenario that once it gave failure it never give success with the same card...!!! – suneet saini Jun 03 '14 at 11:11
  • with the same card it is *always* issue once it got blocked once, if I change card, then it works ok ... –  Jun 03 '14 at 11:20
  • I answered this already :) ps. when I *change* card it will work, and also if I now use old card - on which it was blocking it will also work ... –  Jun 03 '14 at 11:26
  • After briefing the document; have you go according to `ISO1443` and follow the `RATS Process` defined in `5.2.26 ISO14443-4 TYPE-A card reset(RATS)` – suneet saini Jun 03 '14 at 11:28