pn532_error_t pn532_mifareclassic_ReadDataBlock (uint8_t uiBlockNumber, byte_t * pbtData)
{
  pn532_error_t error;
  byte_t abtCommand[4];
  byte_t abtResponse[PN532_RESPONSELEN_INDATAEXCHANGE];
  size_t szLen;

  #ifdef PN532_DEBUGMODE
    PN532_DEBUG("Reading 16 bytes at block %03d%s", uiBlockNumber, CFG_PRINTF_NEWLINE);
  #endif

  /* Prepare the command */
  abtCommand[0] = PN532_COMMAND_INDATAEXCHANGE;
  abtCommand[1] = 1;                            /* Card number */
  abtCommand[2] = PN532_MIFARE_CMD_READ;        /* Mifare Read command = 0x30 */
  abtCommand[3] = uiBlockNumber;                /* Block Number (0..63 for 1K, 0..255 for 4K) */
  
  /* Send the commands */
  error = pn532Write(abtCommand, sizeof(abtCommand));
  if (error)
  {
    /* Bus error, etc. */
    #ifdef PN532_DEBUGMODE
      PN532_DEBUG("Read failed%s", CFG_PRINTF_NEWLINE);
    #endif
    return error;
  }

  /* Read the response */
  memset(abtResponse, 0, PN532_RESPONSELEN_INDATAEXCHANGE);
  do
  {
    systickDelay(50);
    error = pn532Read(abtResponse, &szLen);
  }
  while (error == PN532_ERROR_RESPONSEBUFFEREMPTY);
  if (error)
  {
    #ifdef PN532_DEBUGMODE
      PN532_DEBUG("Read failed%s", CFG_PRINTF_NEWLINE);
    #endif
    return error;
  }

  /* Make sure we have a valid response (should be 26 bytes long) */
  if (szLen == 26)
  {
    /* Copy the 16 data bytes to the output buffer        */
    /* Block content starts at byte 9 of a valid response */
    memcpy (pbtData, abtResponse+8, 16);
  }
  else
  {
    #ifdef PN532_DEBUGMODE
      PN532_DEBUG("Unexpected response reading block %d.  Bad key?%s", uiBlockNumber, CFG_PRINTF_NEWLINE);
    #endif
    return PN532_ERROR_BLOCKREADFAILED;
  }

  /* Display data for debug if requested */
  #ifdef PN532_DEBUGMODE
    PN532_DEBUG("Block %03d: ", uiBlockNumber, CFG_PRINTF_NEWLINE);
    pn532PrintHexVerbose(pbtData, 16);
  #endif

  // Return OK signal
  return PN532_ERROR_NONE;
}
pn532_error_t pn532_mifareclassic_AuthenticateBlock (byte_t * pbtCUID, size_t szCUIDLen, uint32_t uiBlockNumber, uint8_t uiKeyType, byte_t * pbtKeys)
{
  pn532_error_t error;
  byte_t abtCommand[17];
  byte_t abtResponse[PN532_RESPONSELEN_INDATAEXCHANGE];
  size_t szLen;

  #ifdef PN532_DEBUGMODE
  PN532_DEBUG("Trying to authenticate card ");
  pn532PrintHex(pbtCUID, szCUIDLen);
  #endif

  /* Prepare the authentication command */
  abtCommand[0] = PN532_COMMAND_INDATAEXCHANGE;   /* Data Exchange Header */
  abtCommand[1] = 1;                              /* Max card numbers */
  abtCommand[2] = (uiKeyType) ? PN532_MIFARE_CMD_AUTH_A : PN532_MIFARE_CMD_AUTH_B;
  abtCommand[3] = uiBlockNumber;                  /* Block Number (1K = 0..63, 4K = 0..255 */
  memcpy (abtCommand+4, pbtKeys, 6);
  uint8_t i;
  for (i = 0; i < szCUIDLen; i++)
  {
    abtCommand[10+i] = pbtCUID[i];                /* 4 byte card ID */
  }
  
  /* Send the command */
  error = pn532Write(abtCommand, 10+szCUIDLen);
  if (error)
  {
    /* Problem with the serial bus, etc. */
    #ifdef PN532_DEBUGMODE
      PN532_DEBUG("Authentification failed%s", CFG_PRINTF_NEWLINE);
    #endif
    return error;
  }

  /* Read the authentication response */
  memset(abtResponse, 0, PN532_RESPONSELEN_INDATAEXCHANGE);
  do
  {
    systickDelay(25);
    error = pn532Read(abtResponse, &szLen);
  }
  while (error == PN532_ERROR_RESPONSEBUFFEREMPTY);
  if (error)
  {
    #ifdef PN532_DEBUGMODE
      PN532_DEBUG("Authentification failed%s", CFG_PRINTF_NEWLINE);
    #endif
    return error;
  }

  // ToDo: How to check if authentification really worked (bad key, etc.)?

  /* Output the authentification data */
  #ifdef PN532_DEBUGMODE
    PN532_DEBUG("Authenticated block %d %s", uiBlockNumber, CFG_PRINTF_NEWLINE);
  #endif

  // Return OK signal
  return PN532_ERROR_NONE;
}
示例#3
0
int main (void)
{
  #ifdef CFG_INTERFACE
    #error "CFG_INTERFACE must be disabled in projectconfig.h for this demo"
  #endif
  #if !defined CFG_PRINTF_USBCDC
    #error "CFG_PRINTF_USBCDC must be enabled in projectconfig.h for this demo"
  #endif

  // Configure cpu and mandatory peripherals
  systemInit();
  
  // Wait 5 second for someone to open the USB connection for printf
  systickDelay(5000);

  // Initialise the PN532
  pn532Init();

  byte_t response[256];
  size_t responseLen;
  pn532_error_t error;

  // Setup command to initialise a single ISO14443A target at 106kbps 
  byte_t abtCommand[] = { PN532_COMMAND_INLISTPASSIVETARGET, 0x01, PN532_MODULATION_ISO14443A_106KBPS };

  while (1)
  {
    printf("%s", CFG_PRINTF_NEWLINE);
    printf("Waiting for an ISO14443A card (Mifare Classic, etc.)%s", CFG_PRINTF_NEWLINE);

    // Send the command (and handle the most common errors)
    error = pn532Write(abtCommand, sizeof(abtCommand));
    if (error)
    {
      // Something went wrong sending the command (probably the bus selection or wiring)
      switch(error)
      {
        case (PN532_ERROR_NOACK):
          // No ACK frame received in UART mode (bus pins not set correctly?)
          printf("Ooops ... No ACK frame was received! Are the bus pins sets to UART?%s", CFG_PRINTF_NEWLINE);
          break;
        case (PN532_ERROR_I2C_NACK):
          // No ACK bit received to I2C start (bus pins not set correctly?)
          printf("Ooops ... No ACK bit received for I2C start! Are the bus pins sets to I2C?%s", CFG_PRINTF_NEWLINE);
          break;
        default:
          printf("Ooops ... something went wrong! [PN532 Error Code: 0x%02X]%s", error, CFG_PRINTF_NEWLINE);
          break;
      }
    }
    else
    {
      // Commmand seems to have gone through ... 
      do
      {
        // Keep reading until we get a response or an unexpected error condition
        error = pn532Read(response, &responseLen);
        systickDelay(25);
      }
      while (error == PN532_ERROR_RESPONSEBUFFEREMPTY);
  
      // Print the card details if possible
      if (!error)
      {
        /* Response for ISO14443A 106KBPS (Mifare Classic, etc.)
           See UM0701-02 section 7.3.5 for more information
  
           byte            Description
           -------------   ------------------------------------------
           b7              Tags Found
           b8              Tag Number (only one used in this example)
           b9..10          SENS_RES
           b11             SEL_RES
           b12             NFCID Length
           b13..NFCIDLen   NFCID
           
           SENS_RES   SEL_RES     Manufacturer/Card Type    NFCID Len
           --------   -------     -----------------------   ---------
           00 04      08          NXP Mifare Classic 1K     4 bytes   */
  
        printf("%s", CFG_PRINTF_NEWLINE);
        printf("%-12s: %d %s", "Tags Found", response[7], CFG_PRINTF_NEWLINE);
        printf("%-12s: %02X %02X %s", "SENS_RES", response[9], response[10], CFG_PRINTF_NEWLINE);
        printf("%-12s: %02X %s", "SEL_RES", response[11], CFG_PRINTF_NEWLINE);
        printf("%-12s: ", "NFCID");
        size_t pos;
        for (pos=0; pos < response[12]; pos++) 
        {
          printf("%02x ", response[13 + pos]);
        }
        printf(CFG_PRINTF_NEWLINE);
        if ((response[9] == 0x00) && (response[10] == 0x04) && (response[11] == 0x08))
        {
          printf("Seems to be a Mifare Classic 1K Card%s", CFG_PRINTF_NEWLINE);
        }
      }
      else
      {
        // Oops .... something bad happened.  Check 'error'
        printf("Ooops! Error %02X %s", error, CFG_PRINTF_NEWLINE);
      }
    }

    // Wait at least one second before trying again
    systickDelay(1000);
  }
}
pn532_error_t pn532_mifareclassic_WaitForPassiveTarget (byte_t * pbtCUID, size_t * szCUIDLen)
{
  byte_t abtResponse[PN532_RESPONSELEN_INLISTPASSIVETARGET];
  pn532_error_t error;
  size_t szLen;

  #ifdef PN532_DEBUGMODE
    PN532_DEBUG("Waiting for an ISO14443A Card%s", CFG_PRINTF_NEWLINE);
  #endif

  /* Try to initialise a single ISO14443A tag at 106KBPS                  */
  /* Note:  To wait for a card with a known UID, append the four byte     */
  /*        UID to the end of the command.                                */ 
  byte_t abtCommand[] = { PN532_COMMAND_INLISTPASSIVETARGET, 0x01, PN532_MODULATION_ISO14443A_106KBPS};
  error = pn532Write(abtCommand, sizeof(abtCommand));
  if (error) 
    return error;

  /* Wait until we get a valid response or a timeout                      */
  do
  {
    systickDelay(25);
    error = pn532Read(abtResponse, &szLen);
  } while (error == PN532_ERROR_RESPONSEBUFFEREMPTY);
  if (error) 
    return error;

  /* Check SENSE_RES to make sure this is a Mifare Classic card           */
  /*          Classic 1K       = 00 04                                    */
  /*          Classic 4K       = 00 02                                    */
  /*          Classic Emulated = 00 08                                    */
  if ((abtResponse[10] == 0x02) || 
      (abtResponse[10] == 0x04) || 
      (abtResponse[10] == 0x08))
  {
    /* Card appears to be Mifare Classic */
    *szCUIDLen = abtResponse[12];
    uint8_t i;
    for (i=0; i < *szCUIDLen; i++) 
    {
      pbtCUID[i] = abtResponse[13+i];
    }
    #ifdef PN532_DEBUGMODE
      PN532_DEBUG("Card Found: %s", CFG_PRINTF_NEWLINE);
      PN532_DEBUG("      ATQA: ");
      pn532PrintHex(abtResponse+9, 2);
      PN532_DEBUG("      SAK: %02x%s", abtResponse[11], CFG_PRINTF_NEWLINE);
      PN532_DEBUG("      UID: ");
      pn532PrintHex(pbtCUID, *szCUIDLen);
    #endif
  }
  else
  {
    /* Card is ISO14443A but doesn't appear to be Mifare Classic          */
    /*    Mifare Ultralight    = 0x0044                                   */
    /*    Mifare DESFire       = 0x0344                                   */
    /*    Innovision Jewel     = 0x0C00                                   */
    #ifdef PN532_DEBUGMODE
      PN532_DEBUG("Wrong Card Type (Expected ATQA 00 02, 00 04 or 00 08) %s%s", CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
      PN532_DEBUG("  ATQA       : ");
      pn532PrintHex(abtResponse+9, 2);
      PN532_DEBUG("  SAK        : %02x%s", abtResponse[11], CFG_PRINTF_NEWLINE);
      PN532_DEBUG("  UID Length : %d%s", abtResponse[12], CFG_PRINTF_NEWLINE);
      PN532_DEBUG("  UID        : ");
      size_t pos;
      for (pos=0; pos < abtResponse[12]; pos++) 
      {
        printf("%02x ", abtResponse[13 + pos]);
      }
      printf("%s%s", CFG_PRINTF_NEWLINE, CFG_PRINTF_NEWLINE);
    #endif
    return PN532_ERROR_WRONGCARDTYPE;
  }

  return PN532_ERROR_NONE;
}
示例#5
0
int main (void)
{
  #ifdef CFG_INTERFACE
    //#error "CFG_INTERFACE must be disabled in projectconfig.h for this demo"
  #endif
  #if !defined CFG_PRINTF_USBCDC
    #error "CFG_PRINTF_USBCDC must be enabled in projectconfig.h for this demo"
  #endif

  // Configure cpu and mandatory peripherals
  systemInit();
  
  // Wait a bit for someone to open the USB connection for printf
  systickDelay(5000);

  // Initialise the PN532
  pn532Init();

  pn532_error_t error;
  byte_t response[64];
  size_t responseLen;

  // Setup command to initialise a single ISO14443A target at 106kbps (Mifare Classic, Ultralight, etc.)
  byte_t abtCommand[] = { PN532_COMMAND_INLISTPASSIVETARGET, 0x01, PN532_MODULATION_ISO14443A_106KBPS };

  while (1)
  {
    printf("%s", CFG_PRINTF_NEWLINE);
    printf("Waiting for an ISO14443A card (Mifare Classic, etc.)%s", CFG_PRINTF_NEWLINE);

    // Send the command (and handle the most common errors)
    error = pn532Write(abtCommand, sizeof(abtCommand));
    if (error)
    {
      // Something went wrong sending the command (probably the bus selection or wiring)
      switch(error)
      {
        case (PN532_ERROR_NOACK):
        case (PN532_ERROR_INVALIDACK):
          // No ACK response frame received from the PN532
          printf("Ooops ... No valid ACK frame received!%s", CFG_PRINTF_NEWLINE);
          break;
        case (PN532_ERROR_I2C_NACK):
          // No ACK bit received to I2C start ... not same as PN532 ACK frame (bus pins not set correctly?)
          printf("Ooops ... No I2C ACK received! Are the bus select pins sets to I2C?%s", CFG_PRINTF_NEWLINE);
          break;
        case (PN532_ERROR_READYSTATUSTIMEOUT):
          // Timed out waiting for the ready bit to clear ... this can be intentional, though, in the
          // case of PN532_COMMAND_INLISTPASSIVETARGET since it will only clear when a card
          // enters the magnetic field!  Handle with caution because it isn't always an error
          // Note: Only valid for I2C and SPI
          printf("Timed out waiting for Ready/IRQ%s", CFG_PRINTF_NEWLINE);
          break;
        default:
          printf("Ooops ... something went wrong! [PN532 Error Code: 0x%02X]%s", error, CFG_PRINTF_NEWLINE);
          break;
      }
    }
    else
    {
      // Commmand seems to have gone through ... 
      do
      {
        // Keep reading until we get a response or an unexpected error condition
        error = pn532Read(response, &responseLen);
        systickDelay(25);
      }
      while (error == PN532_ERROR_RESPONSEBUFFEREMPTY);

      printf("%s", CFG_PRINTF_NEWLINE);
      printf("%-12s: ", "Received");
      pn532PrintHex(response, responseLen);

      // Try to handle some potential frame errors
      // Unhandled errors are caught further down
      switch (error)
      {
        case (PN532_ERROR_PREAMBLEMISMATCH):
          // Frame should start with 0x00 0x00 0xFF!
          printf("Response frame doesn't start with expected preamble (00 00 FF)%s", CFG_PRINTF_NEWLINE);
          break;
        case (PN532_ERROR_APPLEVELERROR):
          printf("Application level error reported by PN532%s", CFG_PRINTF_NEWLINE);
          break;
        case (PN532_ERROR_LENCHECKSUMMISMATCH):          
          printf("Frame length check/checksum mismatch%s", CFG_PRINTF_NEWLINE);
          break;
        default:
          // Other errors handled below
          break;
      }
  
      // Print the card details if possible
      if (!error)
      {
        /* Response for ISO14443A 106KBPS (Mifare Classic, etc.)
           See UM0701-02 section 7.3.5 for more information
  
           byte            Description
           -------------   ------------------------------------------
           b7              Tags Found
           b8              Tag Number (only one used in this example)
           b9..10          SENS_RES
           b11             SEL_RES
           b12             NFCID Length
           b13..NFCIDLen   NFCID
           
           SENS_RES   SEL_RES     Manufacturer/Card Type    NFCID Len
           --------   -------     -----------------------   ---------
           00 04      08          NXP Mifare Classic 1K     4 bytes   */
  
        printf("%-12s: %d %s", "Tags Found", response[7], CFG_PRINTF_NEWLINE);
        printf("%-12s: %02X %02X %s", "SENS_RES", response[9], response[10], CFG_PRINTF_NEWLINE);
        printf("%-12s: %02X %s", "SEL_RES", response[11], CFG_PRINTF_NEWLINE);
        printf("%-12s: ", "NFCID");
        size_t pos;
        for (pos=0; pos < response[12]; pos++) 
        {
          printf("%02x ", response[13 + pos]);
        }
        printf(CFG_PRINTF_NEWLINE);
        if ((response[9] == 0x00) && (response[10] == 0x04) && (response[11] == 0x08))
        {
          printf("Seems to be a Mifare Classic 1K Card%s", CFG_PRINTF_NEWLINE);
        }
      }
      else
      {
        // Oops .... something bad happened.  Check 'error'
        printf("Ooops! Error %02X %s", error, CFG_PRINTF_NEWLINE);
      }
    }

    // Wait at least one second before trying again
    systickDelay(1000);
  }
}