在python中发送APDU命令(RC522,RaspberryPi)

时间:2018-04-12 17:50:42

标签: python raspberry-pi rfid apdu contactless-smartcard

我用Raspberry Pi 3和RC522构建了某种RFID-Reader,使用此代码作为开头:https://github.com/mxgxw/MFRC522-python。 不幸的是,我发送任何APDU-Command后无法从我的卡上获得APDU响应。

我目前的工作流程或多或少是ISO 14443-4:

  1. 搜寻卡片
  2. 收到ATQA
  3. 执行防撞并选择卡
  4. 确定卡是否支持ISO-14443-4协议
  5. 发送RATS并接收ATS
  6. 执行PPS请求[直到这里一切正常,我得到回复。]
  7. 发送APDU命令[btw。命令适用于我的智能手机和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
    
  8. 这是'库中的发送功能:

    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)
    

    使用&#39; toCard&#39;发送命令。上述代码的功能具有以下结构:

    APDU-Command + CRC-Bytes。

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

    我还尝试使用额外的PCB或多个部分发送命令(例如,首先是标题然后是标题)。 我不确定APDU-Command的结构是否是,或者我是否忘记了ISO 14443中激活过程的某些部分。如果有人可以帮助我,我很高兴。

0 个答案:

没有答案