3

I build up some kind of RFID-Reader with an Raspberry Pi 3 and an RC522 using this code as a start: https://github.com/mxgxw/MFRC522-python. Unfortunately I'm not able to get a APDU-Response from my card after sending any APDU-Command.

My current workflow is more or less the ISO 14443-4:

  1. Search for cards
  2. receive ATQA
  3. Perform anticollision and select card
  4. Determine whether card is supporting ISO-14443-4 protocol or not
  5. Send RATS and receive ATS
  6. Perform an PPS-Request [Until here everything is fine and I get responses.]
  7. Send an APDU-Command [btw. command works fine with my smartphone and an APP]

    #Scan for cards    
    (status,TagType) = MIFAREReader.MFRC522_Request(MIFAREReader.PICC_REQIDL)
    
    #If a card is found
    if status == MIFAREReader.MI_OK:
    print "Card detected"
    TagType = (TagType >> 6) | 0 #(Länge der UID errechnen 
    print "Tagtype:  %s" % (TagType)
    
    # START  ANTI-COLLISION AS OF ISO 14443
    
    if TagType == 0:
        print "UID length is single -- starting ANTI-COLLISION CL1"
        (status,uid) = MIFAREReader.MFRC522_Anticoll()
    
        if status == MIFAREReader.MI_OK:
            print "Card read UID: %s,%s,%s,%s" % (uid[0], uid[1], uid[2], uid[3])
    
    elif TagType == 1: # Ignore this part as there is no functionality by now
        print "CARD IS NOT SUPPORTED YET"
        (status,uid) = MIFAREReader.MFRC522_Anticoll()
    
    elif TagType == 2:
        print "CARD IS NOT SUPPORTED YET"
        (status,uid) = MIFAREReader.MFRC522_Anticoll()
    
    elif TagType == 3:
        print "CARD IS NOT SUPPORTED YET"
        (status,uid) = MIFAREReader.MFRC522_Anticoll()
    
    
    else:
        print "An unexpected error occured: UID length is not covered by ISO-14443."
    
    (size, APDU) = MIFAREReader.MFRC522_SelectTag(uid)
    
    print "Card selected"
    print "ISO 14443-4 Compatibility: %s" % (APDU)
    
    if APDU == 1: # Card supports ISO 14443-4 protocol [Problem could be here]
    
        #SEND RATS
        print "Sening RATS"
        RATS_Sequenz = [0xE0, 0x50]
        CRC_RATS = []
        CRC_RATS = MIFAREReader.CalulateCRC(RATS_Sequenz)
        RATS_Sequenz.append(CRC_RATS[0])
        RATS_Sequenz.append(CRC_RATS[1])
        (stat, res, leng) = MIFAREReader.MFRC522_ToCard(MIFAREReader.PCD_TRANSCEIVE, RATS_Sequenz)
    
        # Muss: Auswertung des ATS
    
        # PPS
        print "Initialisiere PPS-Kommando"
        PPSS_Sequenz = [0xD0, 0x11, 0x00]
        CRC_PPSS = []
        CRC_PPSS = MIFAREReader.CalulateCRC(PPSS_Sequenz)
        PPSS_Sequenz.append(CRC_PPSS[0])
        PPSS_Sequenz.append(CRC_PPSS[1])
        (stat, res, leng) = MIFAREReader.MFRC522_ToCard(MIFAREReader.PCD_TRANSCEIVE, PPSS_Sequenz)
    
        #PCB = [0x02]
        #PCB.append(PCB[0])
        #PCB.append(PCB[1])
        #(stat, res, leng) = MIFAREReader.MFRC522_ToCard(MIFAREReader.PCD_TRANSCEIVE, PCB)
    
        command = [0xFF, 0x41, 0x00, 0x00, 0x00] # NOT THE COMMAND!
        Header = [0x00, 0x22, 0xC1, 0xA4, 0x12, 0x80, 0x0A, 0x04, 0x00, 0x7F, 0x00, 0x07, 0x02, 0x02, 0x04, 0x02, 0x02, 0x83, 0x01, 0x02, 0x84, 0x01, 0x0D] #Command to be sent
        pOut = MIFAREReader.CalulateCRC(Header)
        Header.append(pOut[0])
        Header.append(pOut[1])
    
        (stat, res, leng) = MIFAREReader.MFRC522_ToCard(MIFAREReader.PCD_TRANSCEIVE, (Header))
        time.sleep(1) # Leftover from here / another non working try
    
        Body = [0x80, 0x0A, 0x04, 0x00, 0x7F, 0x00, 0x07, 0x02, 0x02, 0x04, 0x02, 0x02, 0x83, 0x01, 0x02, 0x84, 0x01, 0x0D]
        #pOut = MIFAREReader.CalulateCRC(Body)
        #Body.append(pOut[0])
        #Body.append(pOut[1])
    
        #(stat, res, leng) = MIFAREReader.MFRC522_ToCard(MIFAREReader.PCD_TRANSCEIVE, Body)
    elif APDU == 0:
        #HALT
        command = [0x50]
        pOut = MIFAREReader.CalulateCRC(command)
        command.append(pOut[0])
        command.append(pOut[1])
        (stat, res, leng) = MIFAREReader.MFRC522_ToCard(MIFAREReader.PCD_TRANSCEIVE, command)
        #WOP
    

This is the send function as found in the 'library':

def MFRC522_ToCard(self,command,sendData):
backData = []
backLen = 0
status = self.MI_ERR
irqEn = 0x00
waitIRq = 0x00
lastBits = None
n = 0
i = 0

if command == self.PCD_AUTHENT:
  irqEn = 0x12
  waitIRq = 0x10
if command == self.PCD_TRANSCEIVE:
  irqEn = 0x77
  waitIRq = 0x30

self.Write_MFRC522(self.CommIEnReg, irqEn|0x80)
self.ClearBitMask(self.CommIrqReg, 0x80)
self.SetBitMask(self.FIFOLevelReg, 0x80)

self.Write_MFRC522(self.CommandReg, self.PCD_IDLE);  

while(i<len(sendData)):
  self.Write_MFRC522(self.FIFODataReg, sendData[i])
  i = i+1

self.Write_MFRC522(self.CommandReg, command)

if command == self.PCD_TRANSCEIVE:
  self.SetBitMask(self.BitFramingReg, 0x80)

i = 2000
while True:
  n = self.Read_MFRC522(self.CommIrqReg)
  i = i - 1
  if ~((i!=0) and ~(n&0x01) and ~(n&waitIRq)):
    break

self.ClearBitMask(self.BitFramingReg, 0x80)

if i != 0:
  if (self.Read_MFRC522(self.ErrorReg) & 0x1B)==0x00:
    status = self.MI_OK

    if n & irqEn & 0x01:
      status = self.MI_NOTAGERR

    if command == self.PCD_TRANSCEIVE:
      n = self.Read_MFRC522(self.FIFOLevelReg)
      lastBits = self.Read_MFRC522(self.ControlReg) & 0x07
      if lastBits != 0:
        backLen = (n-1)*8 + lastBits
      else:
        backLen = n*8

      if n == 0:
        n = 1
      if n > self.MAX_LEN:
        n = self.MAX_LEN

      i = 0
      while i<n:
        backData.append(self.Read_MFRC522(self.FIFODataReg))
        i = i + 1;
  else:
    status = self.MI_ERR

print"Status: %s, Data: %s, Length: %s" % (status, backData, backLen)

return (status,backData,backLen)

The command is send using the 'toCard' function of the code mentioned above with following structure:

APDU-Command + CRC-Bytes.


e.g. 0x00 [CLA], 0x22 [INS], 0xC1 [P1], 0xA4 [P2], 0x12 [Length], 0x80 [DATA, 0x0A, 0x04, 0x00, 0x7F, 0x00, 0x07, 0x02, 0x02, 0x04, 0x02, 0x02, 0x83, 0x01, 0x02, 0x84, 0x01, 0x0D, CRC1, CRC2


I also tried sending the Command with an additional PCB or in multiple parts (e.g. Header first then body). I'm not sure if the structure of the APDU-Command is or if I forgot some part of the activation process as of ISO 14443. I'd be glad if anybody can help me.

  • 1
    Welcome to Stack Overflow! Please read [ask] and take the [tour]. This is a great question, although we could benefit from seeing your code! <3 – SIGSTACKFAULT Apr 12 '18 at 17:57
  • I was trying to do exactly the same thing as you. As far as I have been able to dig some info about this and I found 1 little comment somewhere on stack overflow that RC522 doesn't work with HCE. Looked like a comment from author of MFRC522 library. Don't have the link anymore tho. I got PN532 reader and now I am trying to make it work againn. – Srneczek Mar 26 '20 at 11:18

0 Answers0