1

I am trying to modify an existing SCardTransmit() command (C#) that currently reads one security status/block from a ISO 15693 vicinity RFID card (TI Tag-it HF), to one that will retrieve the security status for all 64 blocks on the card. The existing code is as follows:

Byte[] sendHeader = { 0xFF, 0x30, 0x00, 0x03, 0x05, 0x01, 0x00, 0x00, 0x00, Convert.ToByte(blockNum), 0x01 };

Byte[] sendBuffer = new Byte[255]; //Send Buffer in SCardTransmit
int sendbufferlen;                 //Send Buffer length in SCardTransmit

SmartCardData pack = new SmartCardData();

sendHeader.CopyTo(sendBuffer, 0);
sendbufferlen = Convert.ToByte(sendHeader.Length);

SCardTransmitReceived rxBuf = SmartCardTransmit(sendBuffer, sendbufferlen);

The way I understand it, the bytes preceding Convert.ToByte(blockNum) represent the command to get a security status, followed by the block in question, and the number of blocks to read. The only reference I have seen regarding security status reads is in section 10.3.4 in the "Contactless Smart Card Reader Dev Guide"

NOTE: SmartCardTransmit takes care of calling SCardTransmit with the correct card handle and the other needed parameters. I'm more interested in the format of the send header that represents a request for security blocks 0 to 63.

Michael Roland
  • 39,663
  • 10
  • 99
  • 206
mikem419
  • 61
  • 1
  • 7
  • What RFID card are you using? The subject suggests you are using some type of MIFARE card. However, the command you are refering to (10.3.4: Get Security Status) is a command specific to ISO 15693 vicinity cards. No MIFARE card is of that type. – Michael Roland Dec 19 '13 at 08:22
  • My mistake, after investigating further, it looks like I am using a Texas Instruments Tag-it™ card, and an OMNIKEY contactless smart card reader. – mikem419 Dec 19 '13 at 12:42
  • With that said, I am not sure how to convert the byte array above to one that results in returning all 64 security blocks. – mikem419 Dec 19 '13 at 18:05

2 Answers2

2

Unfortunately, that is not possible. The Get Security Status command of the HID/Omnikey smartcard reader can only retrieve the security status of one block with each command. So regardless of what Le byte you try to provide, the reader will always only return the security status of the block you specify with blockNum.

So the only way to get the security status for all blocks is by iterating through all blocks and issuing the command for each of them:

bool moreBlocks = true;
int blockNum = 0;
while (moreBlocks) {
    byte[] sendBuffer = {
        0xFF, 0x30, 0x00, 0x03,
        0x05,
        0x01,
        0x00, 0x00,
        (byte)((blockNum>>8) & 0xFF), (byte)(blockNum & 0xFF),
        0x00
    };
    SCardTransmitReceived rxBuf = SmartCardTransmit(sendBuffer, sendBuffer.Length);
    moreBlocks = check_if_rxBuf_ends_with_sw9000(rxBuf);
    ++blockNum;
}
Michael Roland
  • 39,663
  • 10
  • 99
  • 206
  • Michael, thank you very much for your answer! That clears things up quite a bit. I assume your check_if_rxBuf_ends_with_sw9000 checks for 0x90 and 0x00 at the end of the returned buffer? – mikem419 Dec 20 '13 at 13:20
  • Right, that's what this pseudo-code function is supposed to do. Normally, if a block does not exist, you should get 0x6A82 (or with some reader versions 0x6A81). So checking for 0x9000 is the easiest choice. – Michael Roland Dec 20 '13 at 13:34
  • Thanks Mike. This actually brings up another question that I will ask here instead of making a new one. The current code also reads 64 data blocks 8 blocks at a time. 9 out of 10 times, the read works just fine, but occasionally I get the 0x6A82 that you speak of. Do you happen to know what could cause the sporadic error? – mikem419 Dec 20 '13 at 13:40
  • You should start a separate question for this (including code, results, etc). – Michael Roland Dec 22 '13 at 08:47
0

From this document: link it appears that your tag complies with ISO15693 standard. From the documentation you have provided it appears that the command you need is at page 59. Now, from the description of the command it appears 0x01 is Version and the following two bytes (0x00 and 0x00) means reading by block. The byte before Convert.ToByte() seams to be the MSB of the starting block (0x00). The Convert.ToByte() is the LSB of the starting block. The next is Le in command description (the number of blocks to be read).

Ionut Ciobanu
  • 346
  • 2
  • 8