Не удается получить PACK с помощью команды PWD_AUTH NTAG213 с использованием PN532.

---Обновление от 03.10.2014------------ Спасибо за совет Майкла Роланда.

Я пытался увидеть "настоящий" ответ от PN532. Я изменил свой код так, чтобы я мог прочитать ответ:

uint16_t PN532::mifareultralight_IntoAuth (uint8_t *Password, uint8_t *PACK)
{
    /* Prepare the command */
    pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
    pn532_packetbuffer[1] = 1;                   /* Card number */
    pn532_packetbuffer[2] = MIFARE_U_CMD_PWD_AUTH;     /* Xsys MH: Mifare Ultralight Read command = 0x1B */
    memcpy (pn532_packetbuffer + 3, Password, 4);        /* Password Payload 

    /* Send the command */
    if (HAL(writeCommand)(pn532_packetbuffer, 7)) {
        return 0xAA;
    }
    /* Read the response packet */
    int16_t status = HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer));
    return status;
}

Я использую ключ по умолчанию: uint8_t Password[4] = {0xFF, 0xFF, 0xFF, 0xFF };

Я получил ответ 0xFFFC Теперь я запутался, PACK по умолчанию равен 0x0000, так что это не PACK, если это NACK, почему я получил NACK с 2 байтами?

Я сделал это правильно?

Любой совет благодарен!!

----Пост от 22.09.2014--------------

Я пытаюсь получить доступ к аутентифицированному состоянию Ntag213 с помощью pn532. Вот код, как я это делал:

Подфункция доступа:

uint8_t PN532::mifareultralight_IntoAuth (uint8_t *Password, uint8_t *Response)
{
    /* Prepare the command */
    pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
    pn532_packetbuffer[1] = 1;                   /* Card number */
    pn532_packetbuffer[2] = MIFARE_U_CMD_PWD_AUTH;     /* Xsys MH: Mifare Ultralight Read command = 0x1B */
    memcpy (pn532_packetbuffer + 3, Password, 4);        /* Password Payload 

    /* Send the command */
    if (HAL(writeCommand)(pn532_packetbuffer, 7)) {
        return 0xAA;
    }

    /* Read the response packet */
    HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer));


    memcpy (Response, pn532_packetbuffer, 4);


    // Return OK signal
    return 0xFF;
}

И вот как я использую подфункцию:

Сначала я проверил, есть ли карта, затем прочитал страницы конфигурации, чтобы проверить конфигурацию.

На 3-м шаге я отправляю команду PWD_AUTH с кодом INDATAEXCHANGE. Если я получал 0xFF за успех, я запускал процесс. Это означает, что при отправке не было ошибки. Я получил ответ от Ntag и от Pn532.

Но я проверяю ответ, это то же самое, что и данные, которые я отправил с кодом INDATAEXCHANGE.

Вот результат:

Hello!
Found chip PN532
Firmware ver. 1.6
Waiting for an ISO14443A Card ...
This will try to read all the data in the Tag
If the Tag is ready, enter any key to start!

Found an ISO14443A card
  UID Length: 7 bytes
  UID Value:  0x4 0xEA 0xFC 0x2 0xD9 0x38 0x80
Seems to be a Mifare Ultralight tag (7 byte UID)

The data for the configuration pages before writing look like this:
 0x4 0x0 0x0 0xFF
 0x0 0x5 0x0 0x0
Send the PWD_AUTH command...
Success code: 0xFF
Response code: 0x40 0x1 0x1B 0xFF
End of the program, enter any key to restart it.

Я думал, что смогу получить Pack или Nack, но похоже, что я ничего не получил от pn532. Как это происходило? И как мне улучшить код для перехода в состояние Authenticated?

Спасибо за любую помощь.

Основной код, как здесь:

// choose to SPI or I2C or HSU
#if 0
  #include <SPI.h>
  #include <PN532_SPI.h>
  #include "PN532.h"

  PN532SPI pn532spi(SPI, 10);
  PN532 nfc(pn532spi);
#elif 0
  #include <PN532_HSU.h>
  #include <PN532.h>

  PN532_HSU pn532hsu(Serial1);
  PN532 nfc(pn532hsu);
#else 
  #include <Wire.h>
  #include <PN532_I2C.h>
  #include <PN532.h>

  PN532_I2C pn532i2c(Wire);
  PN532 nfc(pn532i2c);
#endif
void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("Hello!");

  nfc.begin();

  uint32_t versiondata = nfc.getFirmwareVersion();
  if (! versiondata) {
    Serial.print("Didn't find PN53x board");
    while (1); // halt
  }
  // Got ok data, print it out!
  Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX); 
  Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC); 
  Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);

  // configure board to read RFID tags
  nfc.SAMConfig();

  Serial.println("Waiting for an ISO14443A Card ...");
  Serial.println("This will try to read all the data in the Tag");
  Serial.println("If the Tag is ready, enter any key to start!");
  // Wait for user input before proceeding
  while (!Serial.available());
  while (Serial.available()) Serial.read();
}


void loop() 
{
  int i;                                    // For for-loop
  uint8_t success;                          // Flag to check if there was an error with the PN532
  uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };  // Buffer to store the returned UID
  uint8_t uidLength;                        // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
  bool Fail = false;                        
  uint8_t data[4];                         // Array to store block data during reads
  // Keyb on NDEF and Mifare Classic should be the same
  uint8_t Password[4] = {0xFF, 0xFF, 0xFF, 0xFF };  // using default password
  uint8_t PACK[2] = {0x00, 0x00};
  uint8_t Response[4] = {0,0,0,0};
  // 1. Step: Get the Tag ID

  // Wait for an ISO14443A type cards (Mifare, etc.).  When one is found
  // 'uid' will be populated with the UID, and uidLength will indicate
  // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
  success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
  // put your main code here, to run repeatedly:
  if (success) 
  {
    // Display some basic information about the card
    Serial.println("");
    Serial.println("Found an ISO14443A card");
    Serial.print("  UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
    Serial.print("  UID Value: ");
    for (i=0;i<uidLength;i++)
    {
      Serial.print(" 0x");Serial.print(uid[i],HEX);
    }
    //nfc.PrintHex(uid, uidLength);
    Serial.println("");
  }
  else
  {
    Serial.println("Can not read the Tag");
    Fail = true;
  }   

  if (uidLength == 7 && !Fail)
  {
    // We probably have a Mifare Ultralight card ...
    Serial.println("Seems to be a Mifare Ultralight tag (7 byte UID)");
    Serial.println(""); 
  }
  else
  {
    Serial.println("Ooops... Its not a 7-byte Tag");
    Fail = true;
  }   

   // 2. Step: Try to Read and show the Configuration in Page 0x29, 0x2A
   if(!Fail)
   {
     Serial.println("The data for the configuration pages before writing look like this:");
     //for page 0x29
     success = nfc.mifareultralight_ReadPage (0x29, data);
     if (success)
     {
       // Data seems to have been read ... spit it out
       int j;
       for(j=0;j<4;j++)
       {
         Serial.print(" 0x");Serial.print(data[j],HEX);
       }     
       //nfc.PrintHexChar(data, 4);
       Serial.println("");
     }
     else
     {
       Serial.println("Ooops ... unable to read the configuration page 1 !?");
       Fail = true;
     } 
     // for page 0x2A
     success = nfc.mifareultralight_ReadPage (0x2A, data);
     if (success)
     {
       // Data seems to have been read ... spit it out
       int j;
       for(j=0;j<4;j++)
       {
         Serial.print(" 0x");Serial.print(data[j],HEX);
       }     
       //nfc.PrintHexChar(data, 4);
       Serial.println("");  
     }
     else
     {
       Serial.println("Ooops ... unable to read the configuration page 2 !?");
       Fail = true;
     }      
  }      

    // 3. Step: Use PWD_AUTH command to try to get a PAck
  if (!Fail)
  {
      Serial.println("Send the PWD_AUTH command...");
      success = nfc.mifareultralight_IntoAuth(Password, Response);
      // If the success code is 0xFF, we can check the response
      // print success code
      Serial.print("Success code: 0x");Serial.println(success,HEX);
      // print response code
      Serial.print("Response code:");
      int j;
      for(j=0;j<4;j++)
      {
        Serial.print(" 0x");Serial.print(Response[j],HEX);
      }     
      //nfc.PrintHexChar(data, 4);
      Serial.println("");

  }      

  Serial.println("End of the program, enter any key to restart it.");
  // Wait for user input before proceeding
  while (!Serial.available());
  while (Serial.available()) Serial.read();
}

person MinShu Huang    schedule 22.09.2014    source источник
comment
Какую версию библиотеки PN532 вы используете? Каково возвращаемое значение HAL(readResponse)(...)?   -  person Michael Roland    schedule 28.09.2014
comment
Спасибо за ваш комментарий. Я использую версию 1.6, я думаю. Ответ, который я получил, что-то вроде 0x40 0x1 0x1B 0xFF.... Похоже, что программа не получила ответа, но просто дайте мне запрос, который я отправил. 0x40 — для PN532_COMMAND_INDATAEXCHANGE, 0x01 — для 1 тега, 0x1B — индекс PWD_AUTH, 0xFF — первый байт ключа по умолчанию. Так что на самом деле я не получил ответа от PN532.   -  person MinShu Huang    schedule 02.10.2014
comment
Это не очень полезно и не отвечает на мой вопрос. Вы видите эти байты как ответ, потому что pn532_packetbuffer не был изменен HAL(readResponse). Итак, теперь было бы интересно, почему эта функция не работает. Таким образом, вам нужно будет проверить возвращаемое значение из вызова HAL(readResponse) и посмотреть, указывает ли это на какой-либо конкретный сбой.   -  person Michael Roland    schedule 02.10.2014
comment
Я сделал еще одну попытку, пожалуйста, смотрите мое обновление выше.   -  person MinShu Huang    schedule 04.10.2014
comment
То, что вы получаете как status, является не ответом от тега, а кодом ошибки, сгенерированным HAL. Это означает PN532_NO_SPACE, хотя я действительно не понимаю, почему вы получили этот ответ для команды InDataExchange (если только вы не изменили размер pn532_packetbuffer или оператор sizeof() не возвращает неправильную длину.   -  person Michael Roland    schedule 05.11.2014


Ответы (2)


Я предлагаю вам попробовать следующее (обратите внимание, что вам может понадобиться прочитать страницу из тега после обнаружения тега и перед выдачей этой команды аутентификации):

uint16_t PN532::mifareultralight_IntoAuth (uint8_t *Password, uint8_t *PACK)
{
    /* Prepare the command */
    pn532_packetbuffer[0] = PN532_COMMAND_INCOMMUNICATETHRU;
    pn532_packetbuffer[1] = 0x1B;
    memcpy (pn532_packetbuffer + 2, Password, 4);    /* Password Payload */

    /* Send the command */
    if (HAL(writeCommand)(pn532_packetbuffer, 6)) {
        return 0xAA;
    }
    /* Read the response packet */
    int16_t status = HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer));
    return status;
}

Если это работает, команда NTAG PWD_AUTH может не поддерживаться режимом PN532 MIFARE PCD.

person Michael Roland    schedule 04.11.2014

вы не можете прочитать пакет или pwd из памяти... раздел 8.8.1 из таблицы данных ntag..

person Fred    schedule 08.05.2017